Back to index

scribus-ng  1.3.4.dfsg+svn20071115
exif.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 //--------------------------------------------------------------------------
00008 // Program to pull the information out of various types of EFIF digital
00009 // camera files and show it in a reasonably consistent way
00010 //
00011 // This module parses the very complicated exif structures.
00012 //
00013 // Matthias Wandel,  Dec 1999 - August 2000
00014 //--------------------------------------------------------------------------
00015 
00016 
00017 #include "exif.h"
00018 #include <qwmatrix.h>
00019 
00020 
00021 static unsigned char * LastExifRefd;
00022 static int ExifSettingsLength;
00023 static double FocalplaneXRes;
00024 static double FocalplaneUnits;
00025 static int MotorolaOrder = 0;
00026 static int SectionsRead;
00027 //static int HaveAll;
00028 
00029 //--------------------------------------------------------------------------
00030 // Table of Jpeg encoding process names
00031 
00032 #define M_SOF0  0xC0            // Start Of Frame N
00033 #define M_SOF1  0xC1            // N indicates which compression process
00034 #define M_SOF2  0xC2            // Only SOF0-SOF2 are now in common use
00035 #define M_SOF3  0xC3
00036 #define M_SOF5  0xC5            // NB: codes C4 and CC are NOT SOF markers
00037 #define M_SOF6  0xC6
00038 #define M_SOF7  0xC7
00039 #define M_SOF9  0xC9
00040 #define M_SOF10 0xCA
00041 #define M_SOF11 0xCB
00042 #define M_SOF13 0xCD
00043 #define M_SOF14 0xCE
00044 #define M_SOF15 0xCF
00045 #define M_SOI   0xD8            // Start Of Image (beginning of datastream)
00046 #define M_EOI   0xD9            // End Of Image (end of datastream)
00047 #define M_SOS   0xDA            // Start Of Scan (begins compressed data)
00048 #define M_JFIF  0xE0            // Jfif marker
00049 #define M_EXIF  0xE1            // Exif marker
00050 #define M_COM   0xFE            // COMment
00051 
00052 
00053 TagTable ProcessTable[] = {
00054     TagTable(M_SOF0,   "Baseline"),
00055     TagTable(M_SOF1,   "Extended sequential"),
00056     TagTable(M_SOF2,   "Progressive"),
00057     TagTable(M_SOF3,   "Lossless"),
00058     TagTable(M_SOF5,   "Differential sequential"),
00059     TagTable(M_SOF6,   "Differential progressive"),
00060     TagTable(M_SOF7,   "Differential lossless"),
00061     TagTable(M_SOF9,   "Extended sequential, arithmetic coding"),
00062     TagTable(M_SOF10,  "Progressive, arithmetic coding"),
00063     TagTable(M_SOF11,  "Lossless, arithmetic coding"),
00064     TagTable(M_SOF13,  "Differential sequential, arithmetic coding"),
00065     TagTable(M_SOF14,  "Differential progressive, arithmetic coding"),
00066     TagTable(M_SOF15,  "Differential lossless, arithmetic coding"),
00067     TagTable(0,        "Unknown")
00068 };
00069 
00070 //--------------------------------------------------------------------------
00071 // Describes format descriptor
00072 static int BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
00073 #define NUM_FORMATS 12
00074 
00075 #define FMT_BYTE       1
00076 #define FMT_STRING     2
00077 #define FMT_USHORT     3
00078 #define FMT_ULONG      4
00079 #define FMT_URATIONAL  5
00080 #define FMT_SBYTE      6
00081 #define FMT_UNDEFINED  7
00082 #define FMT_SSHORT     8
00083 #define FMT_SLONG      9
00084 #define FMT_SRATIONAL 10
00085 #define FMT_SINGLE    11
00086 #define FMT_DOUBLE    12
00087 
00088 //--------------------------------------------------------------------------
00089 // Describes tag values
00090 
00091 #define TAG_EXIF_OFFSET       0x8769
00092 #define TAG_INTEROP_OFFSET    0xa005
00093 
00094 #define TAG_MAKE              0x010F
00095 #define TAG_MODEL             0x0110
00096 #define TAG_ORIENTATION       0x0112
00097 
00098 #define TAG_EXPOSURETIME      0x829A
00099 #define TAG_FNUMBER           0x829D
00100 
00101 #define TAG_SHUTTERSPEED      0x9201
00102 #define TAG_APERTURE          0x9202
00103 #define TAG_MAXAPERTURE       0x9205
00104 #define TAG_FOCALLENGTH       0x920A
00105 
00106 #define TAG_DATETIME_ORIGINAL 0x9003
00107 #define TAG_USERCOMMENT       0x9286
00108 
00109 #define TAG_SUBJECT_DISTANCE  0x9206
00110 #define TAG_FLASH             0x9209
00111 
00112 #define TAG_FOCALPLANEXRES    0xa20E
00113 #define TAG_FOCALPLANEUNITS   0xa210
00114 #define TAG_EXIF_IMAGEWIDTH   0xA002
00115 #define TAG_EXIF_IMAGELENGTH  0xA003
00116 
00117 // the following is added 05-jan-2001 vcs
00118 #define TAG_EXPOSURE_BIAS     0x9204
00119 #define TAG_WHITEBALANCE      0x9208
00120 #define TAG_METERING_MODE     0x9207
00121 #define TAG_EXPOSURE_PROGRAM  0x8822
00122 #define TAG_ISO_EQUIVALENT    0x8827
00123 #define TAG_COMPRESSION_LEVEL 0x9102
00124 
00125 #define TAG_THUMBNAIL_OFFSET  0x0201
00126 #define TAG_THUMBNAIL_LENGTH  0x0202
00127 
00128 
00129 /*static TagTable_t TagTable[] = {
00130   {   0x100,   "ImageWidth"},
00131   {   0x101,   "ImageLength"},
00132   {   0x102,   "BitsPerSample"},
00133   {   0x103,   "Compression"},
00134   {   0x106,   "PhotometricInterpretation"},
00135   {   0x10A,   "FillOrder"},
00136   {   0x10D,   "DocumentName"},
00137   {   0x10E,   "ImageDescription"},
00138   {   0x10F,   "Make"},
00139   {   0x110,   "Model"},
00140   {   0x111,   "StripOffsets"},
00141   {   0x112,   "Orientation"},
00142   {   0x115,   "SamplesPerPixel"},
00143   {   0x116,   "RowsPerStrip"},
00144   {   0x117,   "StripByteCounts"},
00145   {   0x11A,   "XResolution"},
00146   {   0x11B,   "YResolution"},
00147   {   0x11C,   "PlanarConfiguration"},
00148   {   0x128,   "ResolutionUnit"},
00149   {   0x12D,   "TransferFunction"},
00150   {   0x131,   "Software"},
00151   {   0x132,   "DateTime"},
00152   {   0x13B,   "Artist"},
00153   {   0x13E,   "WhitePoint"},
00154   {   0x13F,   "PrimaryChromaticities"},
00155   {   0x156,   "TransferRange"},
00156   {   0x200,   "JPEGProc"},
00157   {   0x201,   "ThumbnailOffset"},
00158   {   0x202,   "ThumbnailLength"},
00159   {   0x211,   "YCbCrCoefficients"},
00160   {   0x212,   "YCbCrSubSampling"},
00161   {   0x213,   "YCbCrPositioning"},
00162   {   0x214,   "ReferenceBlackWhite"},
00163   {   0x828D,  "CFARepeatPatternDim"},
00164   {   0x828E,  "CFAPattern"},
00165   {   0x828F,  "BatteryLevel"},
00166   {   0x8298,  "Copyright"},
00167   {   0x829A,  "ExposureTime"},
00168   {   0x829D,  "FNumber"},
00169   {   0x83BB,  "IPTC/NAA"},
00170   {   0x8769,  "ExifOffset"},
00171   {   0x8773,  "InterColorProfile"},
00172   {   0x8822,  "ExposureProgram"},
00173   {   0x8824,  "SpectralSensitivity"},
00174   {   0x8825,  "GPSInfo"},
00175   {   0x8827,  "ISOSpeedRatings"},
00176   {   0x8828,  "OECF"},
00177   {   0x9000,  "ExifVersion"},
00178   {   0x9003,  "DateTimeOriginal"},
00179   {   0x9004,  "DateTimeDigitized"},
00180   {   0x9101,  "ComponentsConfiguration"},
00181   {   0x9102,  "CompressedBitsPerPixel"},
00182   {   0x9201,  "ShutterSpeedValue"},
00183   {   0x9202,  "ApertureValue"},
00184   {   0x9203,  "BrightnessValue"},
00185   {   0x9204,  "ExposureBiasValue"},
00186   {   0x9205,  "MaxApertureValue"},
00187   {   0x9206,  "SubjectDistance"},
00188   {   0x9207,  "MeteringMode"},
00189   {   0x9208,  "LightSource"},
00190   {   0x9209,  "Flash"},
00191   {   0x920A,  "FocalLength"},
00192   {   0x927C,  "MakerNote"},
00193   {   0x9286,  "UserComment"},
00194   {   0x9290,  "SubSecTime"},
00195   {   0x9291,  "SubSecTimeOriginal"},
00196   {   0x9292,  "SubSecTimeDigitized"},
00197   {   0xA000,  "FlashPixVersion"},
00198   {   0xA001,  "ColorSpace"},
00199   {   0xA002,  "ExifImageWidth"},
00200   {   0xA003,  "ExifImageLength"},
00201   {   0xA005,  "InteroperabilityOffset"},
00202   {   0xA20B,  "FlashEnergy"},                 // 0x920B in TIFF/EP
00203   {   0xA20C,  "SpatialFrequencyResponse"},  // 0x920C    -  -
00204   {   0xA20E,  "FocalPlaneXResolution"},     // 0x920E    -  -
00205   {   0xA20F,  "FocalPlaneYResolution"},      // 0x920F    -  -
00206   {   0xA210,  "FocalPlaneResolutionUnit"},  // 0x9210    -  -
00207   {   0xA214,  "SubjectLocation"},             // 0x9214    -  -
00208   {   0xA215,  "ExposureIndex"},            // 0x9215    -  -
00209   {   0xA217,  "SensingMethod"},            // 0x9217    -  -
00210   {   0xA300,  "FileSource"},
00211   {   0xA301,  "SceneType"},
00212   {      0, NULL}
00213 } ;
00214 */
00215 
00216 
00217 //--------------------------------------------------------------------------
00218 // Parse the marker stream until SOS or EOI is seen;
00219 //--------------------------------------------------------------------------
00220 int ExifData::ReadJpegSections (QFile & infile, ReadMode_t ReadMode)
00221 {
00222     int a;
00223 
00224     a = infile.getch();
00225 
00226     if (a != 0xff || infile.getch() != M_SOI) {
00227         SectionsRead = 0;
00228         return false;
00229     }
00230     for(SectionsRead = 0; SectionsRead < MAX_SECTIONS-1; ){
00231         int marker = 0;
00232         int got;
00233         unsigned int ll,lh;
00234         unsigned int itemlen;
00235         uchar * Data;
00236 
00237         for (a=0;a<7;a++){
00238             marker = infile.getch();
00239             if (marker != 0xff) break;
00240 
00241             if (a >= 6){
00242 
00243                 qDebug("too many padding bytes");
00244                 return false;
00245 
00246             }
00247         }
00248 
00249         if (marker == 0xff){
00250             // 0xff is legal padding, but if we get that many, something's wrong.
00251                 return false;
00252 //            throw FatalError("too many padding bytes!");
00253         }
00254 
00255         Sections[SectionsRead].Type = marker;
00256 
00257         // Read the length of the section.
00258         lh = (uchar) infile.getch();
00259         ll = (uchar) infile.getch();
00260 
00261         itemlen = (lh << 8) | ll;
00262 
00263         if (itemlen < 2) {
00264                 return false;
00265  //           throw FatalError("invalid marker");
00266         }
00267 
00268         Sections[SectionsRead].Size = itemlen;
00269 
00270         Data = (uchar *)malloc(itemlen+1); // Add 1 to allow sticking a 0 at the end.
00271         Sections[SectionsRead].Data = Data;
00272 
00273         // Store first two pre-read bytes.
00274         Data[0] = (uchar)lh;
00275         Data[1] = (uchar)ll;
00276 
00277         got = infile.readBlock((char*)Data+2, itemlen-2); // Read the whole section.
00278         if (( unsigned ) got != itemlen-2){
00279                 return false;
00280 //            throw FatalError("reading from file");
00281         }
00282         SectionsRead++;
00283 
00284         switch(marker){
00285 
00286             case M_SOS:   // stop before hitting compressed data
00287                 // If reading entire image is requested, read the rest of the data.
00288                 if (ReadMode & READ_IMAGE){
00289                     unsigned long size;
00290 
00291                     size = QMAX( 0ul, infile.size()-infile.at() );
00292                     Data = (uchar *)malloc(size);
00293                     if (Data == NULL){
00294                 return false;
00295 //                        throw FatalError("could not allocate data for entire image");
00296                     }
00297 
00298                     got = infile.readBlock((char*)Data,  size);
00299                     if (( unsigned ) got != size){
00300                 return false;
00301  //                       throw FatalError("could not read the rest of the image");
00302                     }
00303 
00304                     Sections[SectionsRead].Data = Data;
00305                     Sections[SectionsRead].Size = size;
00306                     Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER;
00307                     SectionsRead ++;
00308                     //HaveAll = 1;
00309                 }
00310                 return true;
00311 
00312             case M_EOI:   // in case it's a tables-only JPEG stream
00313                 qDebug("No image in jpeg!");
00314                 return false;
00315 
00316             case M_COM: // Comment section
00317               // pieczy 2002-02-12
00318               // now the User comment goes to UserComment
00319               // so we can store a Comment section also in READ_EXIF mode
00320               process_COM(Data, itemlen);
00321                 break;
00322 
00323             case M_JFIF:
00324                 // Regular jpegs always have this tag, exif images have the exif
00325                 // marker instead, althogh ACDsee will write images with both markers.
00326                 // this program will re-create this marker on absence of exif marker.
00327                 // hence no need to keep the copy from the file.
00328                 free(Sections[--SectionsRead].Data);
00329                 break;
00330 
00331             case M_EXIF:
00332                 // Seen files from some 'U-lead' software with Vivitar scanner
00333                 // that uses marker 31 for non exif stuff.  Thus make sure
00334                 // it says 'Exif' in the section before treating it as exif.
00335                 if ((ReadMode & READ_EXIF) && memcmp(Data+2, "Exif", 4) == 0)
00336                 {
00337                     process_EXIF((uchar *)Data, itemlen); // FIXME: This call
00338                      // requires Data to be array of at least 8 bytes. Code
00339                      // above only checks for itemlen < 2.
00340                                    exifDataValid = true;
00341                 }
00342                 else
00343                 {
00344                     // Discard this section.
00345                     free(Sections[--SectionsRead].Data);
00346 //                    return false;
00347                 }
00348                 break;
00349 
00350             case M_SOF0:
00351             case M_SOF1:
00352             case M_SOF2:
00353             case M_SOF3:
00354             case M_SOF5:
00355             case M_SOF6:
00356             case M_SOF7:
00357             case M_SOF9:
00358             case M_SOF10:
00359             case M_SOF11:
00360             case M_SOF13:
00361             case M_SOF14:
00362             case M_SOF15:
00363                 process_SOFn(Data, marker); //FIXME: This call requires Data to
00364               // be array of at least 8 bytes. Code above only checks for 
00365               // itemlen < 2.
00366             default:
00367                 break;
00368                 break;
00369         }
00370     }
00371     return true;
00372 }
00373 
00374 
00375 //--------------------------------------------------------------------------
00376 // Discard read data.
00377 //--------------------------------------------------------------------------
00378 void ExifData::DiscardData(void)
00379 {
00380     for (int a=0; a < SectionsRead; a++)
00381         free(Sections[a].Data);
00382     SectionsRead = 0;
00383 }
00384 
00385 //--------------------------------------------------------------------------
00386 // Convert a 16 bit unsigned value from file's native byte order
00387 //--------------------------------------------------------------------------
00388 int ExifData::Get16u(void * Short)
00389 {
00390     if (MotorolaOrder){
00391         return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1];
00392     }else{
00393         return (((uchar *)Short)[1] << 8) | ((uchar *)Short)[0];
00394     }
00395 }
00396 
00397 //--------------------------------------------------------------------------
00398 // Convert a 32 bit signed value from file's native byte order
00399 //--------------------------------------------------------------------------
00400 int ExifData::Get32s(void * Long)
00401 {
00402     if (MotorolaOrder){
00403         return  ((( char *)Long)[0] << 24) | (((uchar *)Long)[1] << 16)
00404               | (((uchar *)Long)[2] << 8 ) | (((uchar *)Long)[3] << 0 );
00405     }else{
00406         return  ((( char *)Long)[3] << 24) | (((uchar *)Long)[2] << 16)
00407               | (((uchar *)Long)[1] << 8 ) | (((uchar *)Long)[0] << 0 );
00408     }
00409 }
00410 
00411 //--------------------------------------------------------------------------
00412 // Convert a 32 bit unsigned value from file's native byte order
00413 //--------------------------------------------------------------------------
00414 unsigned ExifData::Get32u(void * Long)
00415 {
00416     return (unsigned)Get32s(Long) & 0xffffffff;
00417 }
00418 
00419 //--------------------------------------------------------------------------
00420 // Evaluate number, be it int, rational, or float from directory.
00421 //--------------------------------------------------------------------------
00422 double ExifData::ConvertAnyFormat(void * ValuePtr, int Format)
00423 {
00424     double Value;
00425     Value = 0;
00426 
00427     switch(Format){
00428         case FMT_SBYTE:     Value = *(signed char *)ValuePtr;  break;
00429         case FMT_BYTE:      Value = *(uchar *)ValuePtr;        break;
00430 
00431         case FMT_USHORT:    Value = Get16u(ValuePtr);          break;
00432 
00433         case FMT_ULONG:     Value = Get32u(ValuePtr);          break;
00434 
00435         case FMT_URATIONAL:
00436         case FMT_SRATIONAL:
00437             {
00438                 int Num,Den;
00439                 Num = Get32s(ValuePtr);
00440                 Den = Get32s(4+(char *)ValuePtr);
00441                 if (Den == 0){
00442                     Value = 0;
00443                 }else{
00444                     Value = (double)Num/Den;
00445                 }
00446                 break;
00447             }
00448 
00449         case FMT_SSHORT:    Value = (signed short)Get16u(ValuePtr);  break;
00450         case FMT_SLONG:     Value = Get32s(ValuePtr);                break;
00451 
00452         // Not sure if this is correct (never seen float used in Exif format)
00453         case FMT_SINGLE:    Value = (double)*(float *)ValuePtr;      break;
00454         case FMT_DOUBLE:    Value = *(double *)ValuePtr;             break;
00455     }
00456     return Value;
00457 }
00458 
00459 //--------------------------------------------------------------------------
00460 // Process one of the nested EXIF directories.
00461 //--------------------------------------------------------------------------
00462 void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength)
00463 {
00464     int de;
00465     int a;
00466     int NumDirEntries;
00467     unsigned ThumbnailOffset = 0;
00468     unsigned ThumbnailSize = 0;
00469 
00470     NumDirEntries = Get16u(DirStart);
00471     #define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry))
00472 
00473     {
00474         unsigned char * DirEnd;
00475         DirEnd = DIR_ENTRY_ADDR(DirStart, NumDirEntries);
00476         if (DirEnd+4 > (OffsetBase+ExifLength)){
00477             if (DirEnd+2 == OffsetBase+ExifLength || DirEnd == OffsetBase+ExifLength){
00478                 // Version 1.3 of jhead would truncate a bit too much.
00479                 // This also caught later on as well.
00480             }else{
00481                 // Note: Files that had thumbnails trimmed with jhead 1.3 or earlier
00482                 // might trigger this.
00483                 return;
00484 //                throw FatalError("Illegally sized directory");
00485             }
00486         }
00487         if (DirEnd < LastExifRefd) LastExifRefd = DirEnd;
00488     }
00489 
00490     for (de=0;de<NumDirEntries;de++){
00491         int Tag, Format, Components;
00492         unsigned char * ValuePtr;
00493         int ByteCount;
00494         char * DirEntry;
00495         DirEntry = (char *)DIR_ENTRY_ADDR(DirStart, de);
00496 
00497         Tag = Get16u(DirEntry);
00498         Format = Get16u(DirEntry+2);
00499         Components = Get32u(DirEntry+4);
00500 
00501         if ((Format-1) >= NUM_FORMATS) {
00502             // (-1) catches illegal zero case as unsigned underflows to positive large.
00503                 return;
00504 //            throw FatalError("Illegal format code in EXIF dir");
00505         }
00506 
00507         ByteCount = Components * BytesPerFormat[Format];
00508 
00509         if (ByteCount > 4){
00510             unsigned OffsetVal;
00511             OffsetVal = Get32u(DirEntry+8);
00512             // If its bigger than 4 bytes, the dir entry contains an offset.
00513             if (OffsetVal+ByteCount > ExifLength){
00514                 // Bogus pointer offset and / or bytecount value
00515                 //printf("Offset %d bytes %d ExifLen %d\n",OffsetVal, ByteCount, ExifLength);
00516 
00517                 return ;
00518 //                throw FatalError("Illegal pointer offset value in EXIF");
00519             }
00520             ValuePtr = OffsetBase+OffsetVal;
00521         }else{
00522             // 4 bytes or less and value is in the dir entry itself
00523             ValuePtr = (unsigned char *)DirEntry+8;
00524         }
00525 
00526         if (LastExifRefd < ValuePtr+ByteCount){
00527             // Keep track of last byte in the exif header that was actually referenced.
00528             // That way, we know where the discardable thumbnail data begins.
00529             LastExifRefd = ValuePtr+ByteCount;
00530         }
00531 
00532         // Extract useful components of tag
00533         switch(Tag){
00534 
00535             case TAG_MAKE:
00536                 ExifData::CameraMake = QString((char*)ValuePtr);
00537                 break;
00538 
00539             case TAG_MODEL:
00540                 ExifData::CameraModel = QString((char*)ValuePtr);
00541               break;
00542 
00543             case TAG_ORIENTATION:
00544                 Orientation = (int)ConvertAnyFormat(ValuePtr, Format);
00545                 break;
00546 
00547             case TAG_DATETIME_ORIGINAL:
00548               DateTime = QString((char*)ValuePtr);
00549                 break;
00550 
00551             case TAG_USERCOMMENT:
00552                 // Olympus has this padded with trailing spaces.  Remove these first.
00553                 for (a=ByteCount;;){
00554                     a--;
00555                     if ((ValuePtr)[a] == ' '){
00556                         (ValuePtr)[a] = '\0';
00557                     }else{
00558                         break;
00559                     }
00560                     if (a == 0) break;
00561                 }
00562 
00563                 // Copy the comment
00564                 if (memcmp(ValuePtr, "ASCII",5) == 0){
00565                     for (a=5;a<10;a++){
00566                         int c;
00567                         c = (ValuePtr)[a];
00568                         if (c != '\0' && c != ' '){
00569                             //strncpy(ImageInfo.Comments, (const char*)(a+ValuePtr), 199);
00570                             UserComment.sprintf("%s", (const char*)(a+ValuePtr));
00571                             break;
00572                         }
00573                     }
00574                 }else{
00575                     //strncpy(ImageInfo.Comments, (const char*)ValuePtr, 199);
00576                     UserComment.sprintf("%s", (const char*)ValuePtr);
00577                 }
00578                 break;
00579 
00580             case TAG_FNUMBER:
00581                 // Simplest way of expressing aperture, so I trust it the most.
00582                 // (overwrite previously computd value if there is one)
00583               ExifData::ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format);
00584                 break;
00585 
00586             case TAG_APERTURE:
00587             case TAG_MAXAPERTURE:
00588                 // More relevant info always comes earlier, so only use this field if we don't
00589                 // have appropriate aperture information yet.
00590                 if (ExifData::ApertureFNumber == 0){
00591                     ExifData::ApertureFNumber
00592                         = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0)*0.5);
00593                 }
00594                 break;
00595 
00596             case TAG_FOCALLENGTH:
00597                 // Nice digital cameras actually save the focal length as a function
00598                 // of how far they are zoomed in.
00599                 ExifData::FocalLength = (float)ConvertAnyFormat(ValuePtr, Format);
00600                 break;
00601 
00602             case TAG_SUBJECT_DISTANCE:
00603                 // Inidcates the distacne the autofocus camera is focused to.
00604                 // Tends to be less accurate as distance increases.
00605                 ExifData::Distance = (float)ConvertAnyFormat(ValuePtr, Format);
00606                 break;
00607 
00608             case TAG_EXPOSURETIME:
00609                 // Simplest way of expressing exposure time, so I trust it most.
00610                 // (overwrite previously computd value if there is one)
00611                 ExifData::ExposureTime = (float)ConvertAnyFormat(ValuePtr, Format);
00612                 break;
00613 
00614             case TAG_SHUTTERSPEED:
00615                 // More complicated way of expressing exposure time, so only use
00616                 // this value if we don't already have it from somewhere else.
00617                 if (ExifData::ExposureTime == 0){
00618                     ExifData::ExposureTime
00619                         = (float)(1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0)));
00620                 }
00621                 break;
00622 
00623             case TAG_FLASH:
00624               ExifData::FlashUsed = (int)ConvertAnyFormat(ValuePtr, Format);
00625                 break;
00626 
00627             case TAG_EXIF_IMAGELENGTH:
00628                 ExifImageLength = (int)ConvertAnyFormat(ValuePtr, Format);
00629                 break;
00630 
00631             case TAG_EXIF_IMAGEWIDTH:
00632                 ExifImageWidth = (int)ConvertAnyFormat(ValuePtr, Format);
00633                 break;
00634 
00635             case TAG_FOCALPLANEXRES:
00636                 FocalplaneXRes = ConvertAnyFormat(ValuePtr, Format);
00637                 break;
00638 
00639             case TAG_FOCALPLANEUNITS:
00640                 switch((int)ConvertAnyFormat(ValuePtr, Format)){
00641                     case 1: FocalplaneUnits = 25.4; break; // inch
00642                     case 2:
00643                         // According to the information I was using, 2 means meters.
00644                         // But looking at the Cannon powershot's files, inches is the only
00645                         // sensible value.
00646                         FocalplaneUnits = 25.4;
00647                         break;
00648 
00649                     case 3: FocalplaneUnits = 10;   break;  // centimeter
00650                     case 4: FocalplaneUnits = 1;    break;  // milimeter
00651                     case 5: FocalplaneUnits = .001; break;  // micrometer
00652                 }
00653                 break;
00654 
00655                 // Remaining cases contributed by: Volker C. Schoech (schoech@gmx.de)
00656 
00657             case TAG_EXPOSURE_BIAS:
00658               ExifData::ExposureBias = (float)ConvertAnyFormat(ValuePtr, Format);
00659               break;
00660 
00661             case TAG_WHITEBALANCE:
00662                  ExifData::Whitebalance = (int)ConvertAnyFormat(ValuePtr, Format);
00663                break;
00664 
00665             case TAG_METERING_MODE:
00666                 ExifData::MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format);
00667                 break;
00668 
00669             case TAG_EXPOSURE_PROGRAM:
00670                 ExifData::ExposureProgram = (int)ConvertAnyFormat(ValuePtr, Format);
00671                 break;
00672 
00673             case TAG_ISO_EQUIVALENT:
00674                 ExifData::ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format);
00675                 if ( ExifData::ISOequivalent < 50 ) ExifData::ISOequivalent *= 200;
00676                 break;
00677 
00678             case TAG_COMPRESSION_LEVEL:
00679                 ExifData::CompressionLevel = (int)ConvertAnyFormat(ValuePtr, Format);
00680                 break;
00681 
00682             case TAG_THUMBNAIL_OFFSET:
00683                 ThumbnailOffset = (unsigned)ConvertAnyFormat(ValuePtr, Format);
00684                 break;
00685 
00686             case TAG_THUMBNAIL_LENGTH:
00687                 ThumbnailSize = (unsigned)ConvertAnyFormat(ValuePtr, Format);
00688                 break;
00689 
00690         }
00691 
00692         if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET){
00693             unsigned char * SubdirStart;
00694             SubdirStart = OffsetBase + Get32u(ValuePtr);
00695             if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength){
00696                 return ;
00697 //                throw FatalError("Illegal subdirectory link");
00698             }
00699             ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
00700             continue;
00701         }
00702     }
00703 
00704     {
00705         // In addition to linking to subdirectories via exif tags,
00706         // there's also a potential link to another directory at the end of each
00707         // directory.  this has got to be the result of a comitee!
00708         unsigned char * SubdirStart;
00709         unsigned Offset;
00710 
00711         if (DIR_ENTRY_ADDR(DirStart, NumDirEntries) + 4 <= OffsetBase+ExifLength){
00712             Offset = Get32u(DIR_ENTRY_ADDR(DirStart, NumDirEntries));
00713            // There is at least one jpeg from an HP camera having an Offset of almost MAXUINT.
00714            // Adding OffsetBase to it produces an overflow, so compare with ExifLength here.
00715            // See http://bugs.kde.org/show_bug.cgi?id=54542
00716            if (Offset && Offset < ExifLength){
00717                 SubdirStart = OffsetBase + Offset;
00718                 if (SubdirStart > OffsetBase+ExifLength){
00719                     if (SubdirStart < OffsetBase+ExifLength+20){
00720                         // Jhead 1.3 or earlier would crop the whole directory!
00721                         // As Jhead produces this form of format incorrectness,
00722                         // I'll just let it pass silently
00723                         qDebug("Thumbnail removed with Jhead 1.3 or earlier");
00724                     }else{
00725                 return ;
00726  //                       throw FatalError("Illegal subdirectory link 2");
00727                     }
00728                 }else{
00729                     if (SubdirStart <= OffsetBase+ExifLength){
00730                         ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
00731                     }
00732                 }
00733             }
00734         }else{
00735             // The exif header ends before the last next directory pointer.
00736         }
00737     }
00738 
00739     if (ThumbnailSize && ThumbnailOffset){
00740         if (ThumbnailSize + ThumbnailOffset <= ExifLength){
00741             // The thumbnail pointer appears to be valid.  Store it.
00742            Thumbnail.loadFromData(OffsetBase + ThumbnailOffset, ThumbnailSize, "JPEG");
00743         }
00744     }
00745 }
00746 
00747 //--------------------------------------------------------------------------
00748 // Process a COM marker.  We want to leave the bytes unchanged.  The
00749 // progam that displays this text may decide to remove blanks, convert
00750 // newlines, or otherwise modify the text.  In particular we want to be
00751 // safe for passing utf-8 text.
00752 //--------------------------------------------------------------------------
00753 void ExifData::process_COM (const uchar * Data, int length)
00754 {
00755     Comment = QString::fromUtf8((char *)Data+2, (length-2));
00756 }
00757 
00758 
00759 //--------------------------------------------------------------------------
00760 // Process a SOFn marker.  This is useful for the image dimensions
00761 //--------------------------------------------------------------------------
00762 void ExifData::process_SOFn (const uchar * Data, int marker)
00763 {
00764     int data_precision, num_components;
00765 
00766     data_precision = Data[2];
00767     ExifData::Height = Get16m(Data+3);
00768     ExifData::Width = Get16m(Data+5);
00769     num_components = Data[7];
00770 
00771     if (num_components == 3){
00772         ExifData::IsColor = 1;
00773     }else{
00774         ExifData::IsColor = 0;
00775     }
00776 
00777     ExifData::Process = marker;
00778 
00779 }
00780 
00781 //--------------------------------------------------------------------------
00782 // Get 16 bits motorola order (always) for jpeg header stuff.
00783 //--------------------------------------------------------------------------
00784 int ExifData::Get16m(const void * Short)
00785 {
00786     return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1];
00787 }
00788 
00789 
00790 //--------------------------------------------------------------------------
00791 // Process a EXIF marker
00792 // Describes all the drivel that most digital cameras include...
00793 //--------------------------------------------------------------------------
00794 void ExifData::process_EXIF(unsigned char * CharBuf, unsigned int length)
00795 {
00796     ExifData::FlashUsed = 0; // If it s from a digicam, and it used flash, it says so.
00797 
00798     FocalplaneXRes = 0;
00799     FocalplaneUnits = 0;
00800     ExifImageWidth = 0;
00801     ExifImageLength = 0;
00802 
00803     {   // Check the EXIF header component
00804         static const uchar ExifHeader[] = "Exif\0\0";
00805         if (memcmp(CharBuf+2, ExifHeader,6)){
00806                 return ;
00807 //            throw FatalError("Incorrect Exif header");
00808         }
00809     }
00810 
00811     if (memcmp(CharBuf+8,"II",2) == 0){
00812         // printf("Exif section in Intel order\n");
00813         MotorolaOrder = 0;
00814     }else{
00815         if (memcmp(CharBuf+8,"MM",2) == 0){
00816             // printf("Exif section in Motorola order\n");
00817             MotorolaOrder = 1;
00818         }else{
00819                 return ;
00820 //            throw FatalError("Invalid Exif alignment marker.");
00821         }
00822     }
00823 
00824     // Check the next two values for correctness.
00825     if (Get16u(CharBuf+10) != 0x2a
00826       || Get32u(CharBuf+12) != 0x08){
00827                 return ;
00828 //        throw FatalError("Invalid Exif start (1)");
00829     }
00830 
00831     LastExifRefd = CharBuf;
00832 
00833     // First directory starts 16 bytes in.  Offsets start at 8 bytes in.
00834     ProcessExifDir(CharBuf+16, CharBuf+8, length-6);
00835 
00836     // This is how far the interesting (non thumbnail) part of the exif went.
00837     ExifSettingsLength = LastExifRefd - CharBuf;
00838 
00839     // Compute the CCD width, in milimeters.
00840     if (FocalplaneXRes != 0){
00841         ExifData::CCDWidth = (float)(ExifImageWidth * FocalplaneUnits / FocalplaneXRes);
00842     }
00843 }
00844 
00845 //--------------------------------------------------------------------------
00846 // Convert exif time to Unix time structure
00847 //--------------------------------------------------------------------------
00848 int ExifData::Exif2tm(struct tm * timeptr, char * ExifTime)
00849 {
00850     int a;
00851 
00852     timeptr->tm_wday = -1;
00853 
00854     // Check for format: YYYY:MM:DD HH:MM:SS format.
00855     a = sscanf(ExifTime, "%d:%d:%d %d:%d:%d",
00856             &timeptr->tm_year, &timeptr->tm_mon, &timeptr->tm_mday,
00857             &timeptr->tm_hour, &timeptr->tm_min, &timeptr->tm_sec);
00858 
00859     if (a == 6){
00860         timeptr->tm_isdst = -1;
00861         timeptr->tm_mon -= 1;      // Adjust for unix zero-based months
00862         timeptr->tm_year -= 1900;  // Adjust for year starting at 1900
00863         return true; // worked.
00864     }
00865 
00866     return false; // Wasn't in Exif date format.
00867 }
00868 
00869 //--------------------------------------------------------------------------
00870 // Contructor for initialising
00871 //--------------------------------------------------------------------------
00872 ExifData::ExifData()
00873 {
00874     ExifData::Whitebalance = -1;
00875     ExifData::MeteringMode = -1;
00876     ExifData::FlashUsed = 0;
00877     Orientation = 0;
00878     Height = 0;
00879     Width = 0;
00880     IsColor = 0;
00881     Process = 0;
00882     FocalLength = 0;
00883     ExposureTime = 0;
00884     ApertureFNumber = 0;
00885     Distance = 0;
00886     CCDWidth = 0;
00887     ExposureBias = 0;
00888     ExposureProgram = 0;
00889     ISOequivalent = 0;
00890     CompressionLevel = 0;
00891        exifDataValid = false;
00892 }
00893 
00894 //--------------------------------------------------------------------------
00895 // process a EXIF jpeg file
00896 //--------------------------------------------------------------------------
00897 bool ExifData::scan(const QString & path)
00898 {
00899     int ret;
00900 
00901     QFile f(path);
00902     if ( !f.open(IO_ReadOnly) )
00903         return false;
00904 
00905 //    try {
00906         // Scan the JPEG headers.
00907         ret = ReadJpegSections(f, READ_EXIF);
00908 /*    }
00909     catch (FatalError& e) {
00910         e.debug_print();
00911         f.close();
00912         return false;
00913     }
00914 */
00915     if (ret == false){
00916         DiscardData();
00917         f.close();
00918         return false;
00919     }
00920     f.close();
00921     DiscardData();
00922 
00923     //now make the strings clean,
00924     // for exmaple my Casio is a "QV-4000   "
00925     CameraMake = CameraMake.stripWhiteSpace();
00926     CameraModel = CameraModel.stripWhiteSpace();
00927     UserComment = UserComment.stripWhiteSpace();
00928     Comment = Comment.stripWhiteSpace();
00929     return true;
00930 }
00931 
00932 //--------------------------------------------------------------------------
00933 // Does the embedded thumbnail match the jpeg image?
00934 //--------------------------------------------------------------------------
00935 #ifndef JPEG_TOL
00936 #define JPEG_TOL 0.02
00937 #endif
00938 bool ExifData::isThumbnailSane() {
00939   if (Thumbnail.isNull()) return false;
00940 
00941   // check whether thumbnail dimensions match the image
00942   // not foolproof, but catches some altered images (jpegtran -rotate)
00943   if (ExifImageLength != 0 && ExifImageLength != Height) return false;
00944   if (ExifImageWidth != 0 && ExifImageWidth != Width) return false;
00945   if (Thumbnail.width() == 0 || Thumbnail.height() == 0) return false;
00946   if (Height == 0 || Width == 0) return false;
00947   double d = (double)Height/Width*Thumbnail.width()/Thumbnail.height();
00948   return (1-JPEG_TOL < d) && (d < 1+JPEG_TOL);
00949 }
00950 
00951 
00952 //--------------------------------------------------------------------------
00953 // return a thumbnail that respects the orientation flag
00954 // only if it seems sane
00955 //--------------------------------------------------------------------------
00956 QImage ExifData::getThumbnail() {
00957   if (!isThumbnailSane()) return NULL;
00958   if (!Orientation || Orientation == 1) return Thumbnail;
00959 
00960   // now fix orientation
00961   QWMatrix M;
00962   QWMatrix flip= QWMatrix(-1,0,0,1,0,0);
00963   switch (Orientation) {  // notice intentional fallthroughs
00964     case 2: M = flip; break;
00965     case 4: M = flip;
00966     case 3: M.rotate(180); break;
00967     case 5: M = flip;
00968     case 6: M.rotate(90); break;
00969     case 7: M = flip;
00970     case 8: M.rotate(270); break;
00971     default: break; // should never happen
00972   }
00973   return Thumbnail.xForm(M);
00974 }