cWebshotsPicture.cpp

Go to the documentation of this file.
00001 /*
00002     cWebshots - Webshots files handling classes
00003     Copyright (C) 2005  Hervé "Setaou" BRY <uwc at apinc dot org>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 */
00019 
00020 
00049 #include "cWebshots.h"
00050 
00051 #include <cstdio>
00052 #include <cstring>
00053 #include <sstream>
00054 
00055 using namespace std;
00056 
00057 namespace cWebshots
00058 {
00059 
00060         //----------------------------------------------------------
00061         // Class cWebshotsPicture
00062         //----------------------------------------------------------
00063 
00064         //------------------------------------
00065         // Constructors / Destructors
00066         //------------------------------------
00067 
00071         cWebshotsPicture::cWebshotsPicture(void)
00072         {
00073                 AdditionDate = 0;
00074                 DailyDate = 0;
00075                 ID = 0;
00076 
00077                 JPGFile_Size = 0;
00078                 BMPThumbnail_Size = 0;
00079         }
00080 
00084         cWebshotsPicture::~cWebshotsPicture(void)
00085         {
00086                 if (JPGFile_Size > 0)
00087                         delete[] JPGFile;
00088 
00089                 if (BMPThumbnail_Size > 0)
00090                         delete[] BMPThumbnail;
00091         }
00092 
00093 
00099         cWebshotsPicture::cWebshotsPicture(const cWebshotsPicture& source)
00100         {
00101                 *this = source;
00102         }
00103 
00104         //------------------------------------
00105         // Operators
00106         //------------------------------------
00107 
00111         cWebshotsPicture& cWebshotsPicture::operator=(const cWebshotsPicture& source)
00112         {
00113                 if (&source != this)
00114                 {
00115                         // Delete the current picture/thumbnail
00116                         if (JPGFile_Size > 0)
00117                                 delete[] JPGFile;
00118                         if (BMPThumbnail_Size > 0)
00119                                 delete[] BMPThumbnail;
00120 
00121                         JPGFile_Size = 0;
00122                         BMPThumbnail_Size = 0;
00123 
00124                         // Copy the source
00125                         ID = source.ID;
00126                         Original_Filename = source.Original_Filename;
00127                         Title = source.Title;
00128                         Caption = source.Caption;
00129                         Credits = source.Credits;
00130 
00131                         Category = source.Category;
00132                         Album = source.Album;
00133                         AlbumID = source.AlbumID;
00134 
00135                         Source = source.Source;
00136                         DailyDate = source.DailyDate;
00137                         AdditionDate = source.AdditionDate;
00138 
00139                         JPGFile_Size = source.JPGFile_Size;
00140                         BMPThumbnail_Size = source.BMPThumbnail_Size;
00141 
00142                         if (JPGFile_Size > 0)
00143                         {
00144                                 JPGFile = new char[JPGFile_Size];
00145                                 memcpy(JPGFile, source.JPGFile, JPGFile_Size);
00146                         }
00147                         if (BMPThumbnail_Size > 0)
00148                         {
00149                                 BMPThumbnail = new char[BMPThumbnail_Size];
00150                                 memcpy(BMPThumbnail, source.BMPThumbnail, BMPThumbnail_Size);
00151                         }
00152                 }
00153 
00154                 return *this;
00155         }
00156 
00157         //------------------------------------
00158         // Public data access
00159         //------------------------------------
00160 
00166         char *cWebshotsPicture::PicturePtr() const
00167         {
00168                 return JPGFile;
00169         }
00170 
00176         long cWebshotsPicture::PictureSize() const
00177         {
00178                 return JPGFile_Size;
00179         }
00180 
00186         char *cWebshotsPicture::ThumbnailPtr() const
00187         {
00188                 return BMPThumbnail;
00189         }
00190 
00196         long cWebshotsPicture::ThumbnailSize() const
00197         {
00198                 return BMPThumbnail_Size;
00199         }
00200 
00201         //------------------------------------
00202         // Load procedures
00203         //------------------------------------
00204 
00213         void cWebshotsPicture::LoadFromFile(string File)
00214         {
00215                 ifstream in_file;
00216                 long File_Type;
00217 
00218                 // Clear everything
00219                 Clear();
00220 
00221                 // Open the file for reading
00222                 in_file.open(File.c_str(), ios_base::in | ios_base::binary);
00223 
00224                 if (in_file.is_open())
00225                 {
00226                         in_file.read((char *)&File_Type, 4);
00227 
00228                         switch (File_Type)
00229                         {
00230                         // JPG File / WB1 File
00231                         case WB1_File_Marker:
00232                         case JFIF_File_Marker: 
00233                         case EXIF_File_Marker:
00234                                         LoadWB1(in_file);
00235                                         LoadMetaDataTXT(File);
00236 
00237                                         // If the picture has no original filename (eg. JPEG), uses the filename
00238                                         if (Original_Filename.length() == 0)
00239                                                 Original_Filename = GetFileName(File);
00240                                 break;
00241 
00242                         // Unsupported file format
00243                         default:
00244                                 Exceptions::UnknownFormat Err("The file \"" + File + "\" cannot be opened as a Webshots picture.");
00245                                 throw Err;
00246                         }
00247 
00248                         in_file.close();
00249                 }
00250                 else
00251                 {
00252                         Exceptions::FileSystemError Err("Unable to open the file \"" + File + "\" for reading.");
00253                         throw Err;
00254                 }
00255         };
00256 
00262         void cWebshotsPicture::LoadWB1(ifstream &in_file)
00263         {
00264                 char *File;
00265                 unsigned long Size;
00266 
00267                 // Get the size of the file
00268                 in_file.seekg(0, ios_base::end);
00269                 Size = (unsigned long)(in_file.tellg()) + 1;
00270                 in_file.seekg(0);
00271 
00272                 // Load the file into a buffer
00273                 File = new char[Size];
00274 
00275                 try
00276                 {
00277                         in_file.read(File, Size);
00278 
00279                         // Load the picture
00280                         LoadFromMemory(File,Size);
00281                 }
00282                 catch (...)
00283                 {
00284                         delete[] File;
00285                         throw;
00286                 }
00287 
00288                 delete[] File;
00289         }
00290 
00299         void cWebshotsPicture::LoadFromMemory(const char *data, long size)
00300         {
00301                 char Key[8];
00302                 char KeyVal;
00303                 long File_Type;
00304                 int i;
00305 
00306                 // Clear the existing picture before we load the new one
00307                 Clear();
00308 
00309                 // Get the type of the file
00310                 memcpy(&File_Type,data,4);
00311 
00312                 switch (File_Type)
00313                 {
00314                 // Encrypted header
00315                 case WB1_File_Marker:
00316                         // Get the key
00317                         memcpy(Key,data,8);
00318                         if (Key[4] == '0')
00319                                 KeyVal = (char)0xA4;
00320                         else if (Key[4] == '1')
00321                                 KeyVal = (char)0xF2;
00322                         
00323                         // Load the file into the buffer
00324                         JPGFile_Size = size - 8;
00325                         JPGFile = new char[JPGFile_Size];
00326                         memcpy(JPGFile,data + 8,size - 8);
00327 
00328                         // Decrypt the file
00329                         for (i = 0; i < 100; i++)
00330                         {
00331                                 JPGFile[i] = (JPGFile[i + 100] ^ (~JPGFile[i])) ^ KeyVal;
00332                         }
00333                         break;
00334 
00335                 // Header not encrypted
00336                 case JFIF_File_Marker:
00337                 case EXIF_File_Marker:
00338                         JPGFile_Size = size;
00339                         JPGFile = new char[JPGFile_Size];
00340                         memcpy(JPGFile,data,size);
00341                         break;
00342 
00343                 // Unknown format
00344                 default:
00345                         Exceptions::UnknownFormat Err("The file has an unknown format.");
00346                         throw Err;
00347                 }
00348         };
00349 
00355         void cWebshotsPicture::LoadMetaDataTXT(string file)
00356         {
00357                 cWebshotsTXT txt;
00358                 int index;
00359                 string test;
00360 
00361                 txt.Load(test = GetDirectory(file));
00362                 index = txt.IndexFromFileName(test = GetFileName(file));
00363 
00364                 if (index != cWebshotsTXT::IndexNotFound)
00365                 {
00366                         ID = txt.Picture(index).id;
00367                         Original_Filename = txt.Picture(index).url_photo;
00368                         Title = txt.Picture(index).title;
00369                         Caption = txt.Picture(index).caption;
00370                         Credits = txt.Picture(index).credit;
00371                         Source = txt.Picture(index).source;
00372                 }
00373 
00374                 Category = txt.Album.topic_name;
00375                 Album = txt.Album.title;
00376                 AlbumID = txt.Album.id;
00377         }
00378 
00379         //------------------------------------
00380         // Save procedures
00381         //------------------------------------
00382 
00391         void cWebshotsPicture::SaveToFile(string file, Webshots_Formats format) const
00392         {
00393                 // Open the file
00394                 ofstream out_file(file.c_str(), ios_base::out | ios_base::binary | ios::trunc);
00395 
00396                 // If the file is open
00397                 if (out_file.is_open())
00398                 {
00399                         // Write the picture
00400                         if (format == WB1)
00401                         {
00402                                 char Header[100];
00403                                 int i;
00404                                 char KeyVal = 0xA4;
00405 
00406                                 // Make the encrypted header using the WWBB0000 key
00407                                 for (i = 0; i < 100; i++)
00408                                         Header[i] = ~(JPGFile[i] ^ KeyVal ^ JPGFile[i + 100]);
00409 
00410                                 out_file << "WWBB0000";
00411 
00412                                 out_file.write(Header, 100);
00413                                 out_file.write(JPGFile + 100,JPGFile_Size - 100);
00414                         }
00415                         else // format == JPG
00416                                 out_file.write(JPGFile,JPGFile_Size);
00417 
00418                         out_file.close();
00419                 }
00420                 else
00421                 {
00422                         Exceptions::FileSystemError Err("Unable to open the file \"" + file + "\" for writing.");
00423                         throw Err;
00424                 }
00425         };
00426 
00427         //------------------------------------
00428         // Clear procedures
00429         //------------------------------------
00430 
00434         void cWebshotsPicture::Clear()
00435         {
00436                 if (JPGFile_Size > 0)
00437                 {
00438                         delete[] JPGFile;
00439                         JPGFile_Size = 0;
00440                 }
00441 
00442                 if (BMPThumbnail_Size > 0)
00443                 {
00444                         delete[] BMPThumbnail;
00445                         BMPThumbnail_Size = 0;
00446                 }
00447 
00448                 ID = 0;
00449                 Original_Filename.clear();
00450                 Title.clear();
00451                 Caption.clear();
00452                 Credits.clear();
00453                 Category.clear();
00454                 Album.clear();
00455                 Source.clear();
00456                 DailyDate = 0;
00457                 AdditionDate = 0;
00458                 AlbumID.clear();
00459         }
00460 }

Generated on Tue Oct 25 14:36:29 2005 for cWebshots by  doxygen 1.4.5