/src/FreeImage/Source/Metadata/Exif.cpp
C++ | 859 lines | 517 code | 123 blank | 219 comment | 152 complexity | 217e501f0f48472bcf9c61100018106c MD5 | raw file
1// ========================================================== 2// Metadata functions implementation 3// Exif metadata model 4// 5// Design and implementation by 6// - Hervé Drolon (drolon@infonie.fr) 7// - Mihail Naydenov (mnaydenov@users.sourceforge.net) 8// 9// Based on the following implementations: 10// - metadata-extractor : http://www.drewnoakes.com/code/exif/ 11// - jhead : http://www.sentex.net/~mwandel/jhead/ 12// - ImageMagick : http://www.imagemagick.org/ 13// 14// This file is part of FreeImage 3 15// 16// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY 17// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES 18// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE 19// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED 20// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT 21// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY 22// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL 23// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER 24// THIS DISCLAIMER. 25// 26// Use at your own risk! 27// ========================================================== 28 29#ifdef _MSC_VER 30#pragma warning (disable : 4786) // identifier was truncated to 'number' characters 31#endif 32 33#include "FreeImage.h" 34#include "Utilities.h" 35#include "FreeImageTag.h" 36 37// ========================================================== 38// Exif JPEG routines 39// ========================================================== 40 41#define EXIF_NUM_FORMATS 12 42 43#define TAG_EXIF_OFFSET 0x8769 // Exif IFD Pointer 44#define TAG_GPS_OFFSET 0x8825 // GPS Info IFD Pointer 45#define TAG_INTEROP_OFFSET 0xA005 // Interoperability IFD Pointer 46#define TAG_MAKER_NOTE 0x927C // Maker note 47 48// CANON cameras have some funny bespoke fields that need further processing... 49#define TAG_CANON_CAMERA_STATE_0x01 0x0001 // tags under tag 0x001 (CameraSettings) 50#define TAG_CANON_CAMERA_STATE_0x02 0x0002 // tags under tag 0x002 (FocalLength) 51#define TAG_CANON_CAMERA_STATE_0x04 0x0004 // tags under tag 0x004 (ShotInfo) 52#define TAG_CANON_CAMERA_STATE_0x12 0x0012 // tags under tag 0x012 (AFInfo) 53#define TAG_CANON_CAMERA_STATE_0xA0 0x00A0 // tags under tag 0x0A0 (ProcessingInfo) 54#define TAG_CANON_CAMERA_STATE_0xE0 0x00E0 // tags under tag 0x0E0 (SensorInfo) 55 56 57// ===================================================================== 58// Reimplementation of strnicmp (it is not supported on some systems) 59// ===================================================================== 60 61/** 62Compare characters of two strings without regard to case. 63@param s1 Null-terminated string to compare. 64@param s2 Null-terminated string to compare. 65@param len Number of characters to compare 66@return Returns 0 if s1 substring identical to s2 substring 67*/ 68static int 69FreeImage_strnicmp(const char *s1, const char *s2, size_t len) { 70 unsigned char c1, c2; 71 72 if(!s1 || !s2) return -1; 73 74 c1 = 0; c2 = 0; 75 if(len) { 76 do { 77 c1 = *s1; c2 = *s2; 78 s1++; s2++; 79 if (!c1) 80 break; 81 if (!c2) 82 break; 83 if (c1 == c2) 84 continue; 85 c1 = (BYTE)tolower(c1); 86 c2 = (BYTE)tolower(c2); 87 if (c1 != c2) 88 break; 89 } while (--len); 90 } 91 return (int)c1 - (int)c2; 92} 93 94 95// ---------------------------------------------------------- 96// Little Endian / Big Endian io routines 97// ---------------------------------------------------------- 98 99static short 100ReadInt16(BOOL msb_order, const void *buffer) { 101 short value; 102 103 if(msb_order) { 104 value = (short)((((BYTE*) buffer)[0] << 8) | ((BYTE*) buffer)[1]); 105 return value; 106 } 107 value = (short)((((BYTE*) buffer)[1] << 8) | ((BYTE*) buffer)[0]); 108 return value; 109} 110 111static LONG 112ReadInt32(BOOL msb_order, const void *buffer) { 113 LONG value; 114 115 if(msb_order) { 116 value = (LONG)((((BYTE*) buffer)[0] << 24) | (((BYTE*) buffer)[1] << 16) | (((BYTE*) buffer)[2] << 8) | (((BYTE*) buffer)[3])); 117 return value; 118 } 119 value = (LONG)((((BYTE*) buffer)[3] << 24) | (((BYTE*) buffer)[2] << 16) | (((BYTE*) buffer)[1] << 8 ) | (((BYTE*) buffer)[0])); 120 return value; 121} 122 123static unsigned short 124ReadUint16(BOOL msb_order, const void *buffer) { 125 unsigned short value; 126 127 if(msb_order) { 128 value = (unsigned short) ((((BYTE*) buffer)[0] << 8) | ((BYTE*) buffer)[1]); 129 return value; 130 } 131 value = (unsigned short) ((((BYTE*) buffer)[1] << 8) | ((BYTE*) buffer)[0]); 132 return value; 133} 134 135static DWORD 136ReadUint32(BOOL msb_order, const void *buffer) { 137 return ((DWORD) ReadInt32(msb_order, buffer) & 0xFFFFFFFF); 138} 139 140// ---------------------------------------------------------- 141// Exif JPEG markers routines 142// ---------------------------------------------------------- 143 144/** 145Process a IFD offset 146Returns the offset and the metadata model for this tag 147*/ 148static void 149processIFDOffset(FITAG *tag, char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) { 150 // get the IFD offset 151 *subdirOffset = (DWORD) ReadUint32(msb_order, pval); 152 153 // select a tag info table 154 switch(FreeImage_GetTagID(tag)) { 155 case TAG_EXIF_OFFSET: 156 *md_model = TagLib::EXIF_EXIF; 157 break; 158 case TAG_GPS_OFFSET: 159 *md_model = TagLib::EXIF_GPS; 160 break; 161 case TAG_INTEROP_OFFSET: 162 *md_model = TagLib::EXIF_INTEROP; 163 break; 164 } 165 166} 167 168/** 169Process a maker note IFD offset 170Returns the offset and the metadata model for this tag 171*/ 172static void 173processMakerNote(FIBITMAP *dib, char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) { 174 FITAG *tagMake = NULL; 175 176 *subdirOffset = 0; 177 *md_model = TagLib::UNKNOWN; 178 179 // Determine the camera model and makernote format 180 // WARNING: note that Maker may be NULL sometimes so check its value before using it 181 // (NULL pointer checking is done by FreeImage_strnicmp) 182 FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, "Make", &tagMake); 183 const char *Maker = (char*)FreeImage_GetTagValue(tagMake); 184 185 if((memcmp("OLYMP\x00\x01", pval, 7) == 0) || (memcmp("OLYMP\x00\x02", pval, 7) == 0) || (memcmp("EPSON", pval, 5) == 0) || (memcmp("AGFA", pval, 4) == 0)) { 186 // Olympus Type 1 Makernote 187 // Epson and Agfa use Olympus maker note standard, 188 // see: http://www.ozhiker.com/electronics/pjmt/jpeg_info/ 189 *md_model = TagLib::EXIF_MAKERNOTE_OLYMPUSTYPE1; 190 *subdirOffset = 8; 191 } 192 else if(memcmp("OLYMPUS\x00\x49\x49\x03\x00", pval, 12) == 0) { 193 // Olympus Type 2 Makernote 194 // !!! NOT YET SUPPORTED !!! 195 *subdirOffset = 0; 196 *md_model = TagLib::UNKNOWN; 197 } 198 else if(memcmp("Nikon", pval, 5) == 0) { 199 /* There are two scenarios here: 200 * Type 1: 201 * :0000: 4E 69 6B 6F 6E 00 01 00-05 00 02 00 02 00 06 00 Nikon........... 202 * :0010: 00 00 EC 02 00 00 03 00-03 00 01 00 00 00 06 00 ................ 203 * Type 3: 204 * :0000: 4E 69 6B 6F 6E 00 02 00-00 00 4D 4D 00 2A 00 00 Nikon....MM.*... 205 * :0010: 00 08 00 1E 00 01 00 07-00 00 00 04 30 32 30 30 ............0200 206 */ 207 if (pval[6] == 1) { 208 // Nikon type 1 Makernote 209 *md_model = TagLib::EXIF_MAKERNOTE_NIKONTYPE1; 210 *subdirOffset = 8; 211 } else if (pval[6] == 2) { 212 // Nikon type 3 Makernote 213 *md_model = TagLib::EXIF_MAKERNOTE_NIKONTYPE3; 214 *subdirOffset = 18; 215 } else { 216 // Unsupported makernote data ignored 217 *subdirOffset = 0; 218 *md_model = TagLib::UNKNOWN; 219 } 220 } else if(Maker && (FreeImage_strnicmp("NIKON", Maker, 5) == 0)) { 221 // Nikon type 2 Makernote 222 *md_model = TagLib::EXIF_MAKERNOTE_NIKONTYPE2; 223 *subdirOffset = 0; 224 } else if(Maker && (FreeImage_strnicmp("Canon", Maker, 5) == 0)) { 225 // Canon Makernote 226 *md_model = TagLib::EXIF_MAKERNOTE_CANON; 227 *subdirOffset = 0; 228 } else if(Maker && (FreeImage_strnicmp("Casio", Maker, 5) == 0)) { 229 // Casio Makernote 230 if(memcmp("QVC\x00\x00\x00", pval, 6) == 0) { 231 // Casio Type 2 Makernote 232 *md_model = TagLib::EXIF_MAKERNOTE_CASIOTYPE2; 233 *subdirOffset = 6; 234 } else { 235 // Casio Type 1 Makernote 236 *md_model = TagLib::EXIF_MAKERNOTE_CASIOTYPE1; 237 *subdirOffset = 0; 238 } 239 } else if ((memcmp("FUJIFILM", pval, 8) == 0) || (Maker && (FreeImage_strnicmp("Fujifilm", Maker, 8) == 0))) { 240 // Fujifile Makernote 241 // Fujifilm's Makernote always use Intel order altough the Exif section maybe in Intel order or in Motorola order. 242 // If msb_order == TRUE, the Makernote won't be read: 243 // the value of ifdStart will be 0x0c000000 instead of 0x0000000c and the MakerNote section will be discarded later 244 // in jpeg_read_exif_dir because the IFD is too high 245 *md_model = TagLib::EXIF_MAKERNOTE_FUJIFILM; 246 DWORD ifdStart = (DWORD) ReadUint32(msb_order, pval + 8); 247 *subdirOffset = ifdStart; 248 } 249 else if(memcmp("KYOCERA\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00", pval, 22) == 0) { 250 *md_model = TagLib::EXIF_MAKERNOTE_KYOCERA; 251 *subdirOffset = 22; 252 } 253 else if(Maker && (FreeImage_strnicmp("Minolta", Maker, 7) == 0)) { 254 // Minolta maker note 255 *md_model = TagLib::EXIF_MAKERNOTE_MINOLTA; 256 *subdirOffset = 0; 257 } 258 else if(memcmp("Panasonic\x00\x00\x00", pval, 12) == 0) { 259 // Panasonic maker note 260 *md_model = TagLib::EXIF_MAKERNOTE_PANASONIC; 261 *subdirOffset = 12; 262 } 263 else if(Maker && (FreeImage_strnicmp("LEICA", Maker, 5) == 0)) { 264 // Leica maker note 265 if(memcmp("LEICA\x00\x00\x00", pval, 8) == 0) { 266 // not yet supported makernote data ignored 267 *subdirOffset = 0; 268 *md_model = TagLib::UNKNOWN; 269 } 270 } 271 else if(Maker && ((FreeImage_strnicmp("Pentax", Maker, 6) == 0) || (FreeImage_strnicmp("Asahi", Maker, 5) == 0))) { 272 // Pentax maker note 273 if(memcmp("AOC\x00", pval, 4) == 0) { 274 // Type 2 Pentax Makernote 275 *md_model = TagLib::EXIF_MAKERNOTE_PENTAX; 276 *subdirOffset = 6; 277 } else { 278 // Type 1 Pentax Makernote 279 *md_model = TagLib::EXIF_MAKERNOTE_ASAHI; 280 *subdirOffset = 0; 281 } 282 } 283 else if((memcmp("SONY CAM\x20\x00\x00\x00", pval, 12) == 0) || (memcmp("SONY DSC\x20\x00\x00\x00", pval, 12) == 0)) { 284 *md_model = TagLib::EXIF_MAKERNOTE_SONY; 285 *subdirOffset = 12; 286 } 287 else if((memcmp("SIGMA\x00\x00\x00", pval, 8) == 0) || (memcmp("FOVEON\x00\x00", pval, 8) == 0)) { 288 FITAG *tagModel = NULL; 289 FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, "Model", &tagModel); 290 const char *Model = (char*)FreeImage_GetTagValue(tagModel); 291 if(Model && (memcmp("SIGMA SD1\x00", Model, 10) == 0)) { 292 // Sigma SD1 maker note 293 *subdirOffset = 10; 294 *md_model = TagLib::EXIF_MAKERNOTE_SIGMA_SD1; 295 } else { 296 // Sigma / Foveon makernote 297 *subdirOffset = 10; 298 *md_model = TagLib::EXIF_MAKERNOTE_SIGMA_FOVEON; 299 } 300 } 301} 302 303/** 304Process a Canon maker note tag. 305A single Canon tag may contain many other tags within. 306*/ 307static BOOL 308processCanonMakerNoteTag(FIBITMAP *dib, FITAG *tag) { 309 char defaultKey[16]; 310 DWORD startIndex = 0; 311 TagLib& s = TagLib::instance(); 312 313 WORD tag_id = FreeImage_GetTagID(tag); 314 315 int subTagTypeBase = 0; 316 317 switch(tag_id) { 318 case TAG_CANON_CAMERA_STATE_0x01: 319 subTagTypeBase = 0xC100; 320 startIndex = 1; 321 break; 322 case TAG_CANON_CAMERA_STATE_0x02: 323 subTagTypeBase = 0xC200; 324 startIndex = 0; 325 break; 326 case TAG_CANON_CAMERA_STATE_0x04: 327 subTagTypeBase = 0xC400; 328 startIndex = 1; 329 break; 330 case TAG_CANON_CAMERA_STATE_0x12: 331 subTagTypeBase = 0x1200; 332 startIndex = 0; 333 break; 334 case TAG_CANON_CAMERA_STATE_0xA0: 335 subTagTypeBase = 0xCA00; 336 startIndex = 1; 337 break; 338 case TAG_CANON_CAMERA_STATE_0xE0: 339 subTagTypeBase = 0xCE00; 340 startIndex = 1; 341 break; 342 343 default: 344 { 345 // process as a normal tag 346 347 // get the tag key and description 348 const char *key = s.getTagFieldName(TagLib::EXIF_MAKERNOTE_CANON, tag_id, defaultKey); 349 FreeImage_SetTagKey(tag, key); 350 const char *description = s.getTagDescription(TagLib::EXIF_MAKERNOTE_CANON, tag_id); 351 FreeImage_SetTagDescription(tag, description); 352 353 // store the tag 354 if(key) { 355 FreeImage_SetMetadata(FIMD_EXIF_MAKERNOTE, dib, key, tag); 356 } 357 358 return TRUE; 359 } 360 break; 361 362 } 363 364 WORD *pvalue = (WORD*)FreeImage_GetTagValue(tag); 365 366 // create a tag 367 FITAG *canonTag = FreeImage_CreateTag(); 368 if(!canonTag) return FALSE; 369 370 // we intentionally skip the first array member (if needed) 371 for (DWORD i = startIndex; i < FreeImage_GetTagCount(tag); i++) { 372 373 tag_id = (WORD)(subTagTypeBase + i); 374 375 FreeImage_SetTagID(canonTag, tag_id); 376 FreeImage_SetTagType(canonTag, FIDT_SHORT); 377 FreeImage_SetTagCount(canonTag, 1); 378 FreeImage_SetTagLength(canonTag, 2); 379 FreeImage_SetTagValue(canonTag, &pvalue[i]); 380 381 // get the tag key and description 382 const char *key = s.getTagFieldName(TagLib::EXIF_MAKERNOTE_CANON, tag_id, defaultKey); 383 FreeImage_SetTagKey(canonTag, key); 384 const char *description = s.getTagDescription(TagLib::EXIF_MAKERNOTE_CANON, tag_id); 385 FreeImage_SetTagDescription(canonTag, description); 386 387 // store the tag 388 if(key) { 389 FreeImage_SetMetadata(FIMD_EXIF_MAKERNOTE, dib, key, canonTag); 390 } 391 } 392 393 // delete the tag 394 FreeImage_DeleteTag(canonTag); 395 396 return TRUE; 397} 398 399/** 400Process a standard Exif tag 401*/ 402static void 403processExifTag(FIBITMAP *dib, FITAG *tag, char *pval, BOOL msb_order, TagLib::MDMODEL md_model) { 404 char defaultKey[16]; 405 int n; 406 DWORD i; 407 408 // allocate a buffer to store the tag value 409 BYTE *exif_value = (BYTE*)malloc(FreeImage_GetTagLength(tag) * sizeof(BYTE)); 410 if(NULL == exif_value) { 411 // out of memory ... 412 return; 413 } 414 memset(exif_value, 0, FreeImage_GetTagLength(tag) * sizeof(BYTE)); 415 416 // get the tag value 417 switch(FreeImage_GetTagType(tag)) { 418 419 case FIDT_SHORT: 420 { 421 WORD *value = (WORD*)&exif_value[0]; 422 for(i = 0; i < FreeImage_GetTagCount(tag); i++) { 423 value[i] = ReadUint16(msb_order, pval + i * sizeof(WORD)); 424 } 425 FreeImage_SetTagValue(tag, value); 426 break; 427 } 428 case FIDT_SSHORT: 429 { 430 short *value = (short*)&exif_value[0]; 431 for(i = 0; i < FreeImage_GetTagCount(tag); i++) { 432 value[i] = ReadInt16(msb_order, pval + i * sizeof(short)); 433 } 434 FreeImage_SetTagValue(tag, value); 435 break; 436 } 437 case FIDT_LONG: 438 { 439 DWORD *value = (DWORD*)&exif_value[0]; 440 for(i = 0; i < FreeImage_GetTagCount(tag); i++) { 441 value[i] = ReadUint32(msb_order, pval + i * sizeof(DWORD)); 442 } 443 FreeImage_SetTagValue(tag, value); 444 break; 445 } 446 case FIDT_SLONG: 447 { 448 LONG *value = (LONG*)&exif_value[0]; 449 for(i = 0; i < FreeImage_GetTagCount(tag); i++) { 450 value[i] = ReadInt32(msb_order, pval + i * sizeof(LONG)); 451 } 452 FreeImage_SetTagValue(tag, value); 453 break; 454 } 455 case FIDT_RATIONAL: 456 { 457 n = sizeof(DWORD); 458 459 DWORD *value = (DWORD*)&exif_value[0]; 460 for(i = 0; i < 2 * FreeImage_GetTagCount(tag); i++) { 461 // read a sequence of (numerator, denominator) 462 value[i] = ReadUint32(msb_order, n*i + (char*)pval); 463 } 464 FreeImage_SetTagValue(tag, value); 465 break; 466 } 467 case FIDT_SRATIONAL: 468 { 469 n = sizeof(LONG); 470 471 LONG *value = (LONG*)&exif_value[0]; 472 for(i = 0; i < 2 * FreeImage_GetTagCount(tag); i++) { 473 // read a sequence of (numerator, denominator) 474 value[i] = ReadInt32(msb_order, n*i + (char*)pval); 475 } 476 FreeImage_SetTagValue(tag, value); 477 break; 478 } 479 case FIDT_BYTE: 480 case FIDT_ASCII: 481 case FIDT_SBYTE: 482 case FIDT_UNDEFINED: 483 case FIDT_FLOAT: 484 case FIDT_DOUBLE: 485 default: 486 FreeImage_SetTagValue(tag, pval); 487 break; 488 } 489 490 if(md_model == TagLib::EXIF_MAKERNOTE_CANON) { 491 // A single Canon tag can have multiple values within 492 processCanonMakerNoteTag(dib, tag); 493 } 494 else { 495 TagLib& s = TagLib::instance(); 496 497 WORD tag_id = FreeImage_GetTagID(tag); 498 499 // get the tag key and description 500 const char *key = s.getTagFieldName(md_model, tag_id, defaultKey); 501 FreeImage_SetTagKey(tag, key); 502 const char *description = s.getTagDescription(md_model, tag_id); 503 FreeImage_SetTagDescription(tag, description); 504 505 // store the tag 506 if(key) { 507 FreeImage_SetMetadata(s.getFreeImageModel(md_model), dib, key, tag); 508 } 509 } 510 511 512 // free the temporary buffer 513 free(exif_value); 514 515} 516 517/** 518 Process Exif directory 519 520 @param dib Input FIBITMAP 521 @param tiffp Pointer to the TIFF header 522 @param offset 0th IFD offset 523 @param length Length of the datafile 524 @param msb_order Endianess order of the datafile 525 @return 526*/ 527static BOOL 528jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsigned int length, BOOL msb_order) { 529 WORD de, nde; 530 531 std::stack<WORD> destack; // directory entries stack 532 std::stack<const BYTE*> ifdstack; // IFD stack 533 std::stack<TagLib::MDMODEL> modelstack; // metadata model stack 534 535 // Keep a list of already visited IFD to avoid stack overflows 536 // when recursive/cyclic directory structures exist. 537 // This kind of recursive Exif file was encountered with Kodak images coming from 538 // KODAK PROFESSIONAL DCS Photo Desk JPEG Export v3.2 W 539 std::map<DWORD, int> visitedIFD; 540 541 /* 542 "An Image File Directory (IFD) consists of a 2-byte count of the number of directory 543 entries (i.e. the number of fields), followed by a sequence of 12-byte field 544 entries, followed by a 4-byte offset of the next IFD (or 0 if none)." 545 The "next IFD" (1st IFD) is the thumbnail. 546 */ 547 #define DIR_ENTRY_ADDR(_start, _entry) (_start + 2 + (12 * _entry)) 548 549 // set the metadata model to Exif 550 551 TagLib::MDMODEL md_model = TagLib::EXIF_MAIN; 552 553 // set the pointer to the first IFD (0th IFD) and follow it were it leads. 554 555 const BYTE *ifd0th = (BYTE*)tiffp + offset; 556 557 const BYTE *ifdp = ifd0th; 558 559 de = 0; 560 561 do { 562 // if there is anything on the stack then pop it off 563 if(!destack.empty()) { 564 ifdp = ifdstack.top(); ifdstack.pop(); 565 de = destack.top(); destack.pop(); 566 md_model = modelstack.top(); modelstack.pop(); 567 } 568 569 // remember that we've visited this directory and entry so that we don't visit it again later 570 DWORD visited = (DWORD)( (((size_t)ifdp & 0xFFFF) << 16) | (size_t)de ); 571 if(visitedIFD.find(visited) != visitedIFD.end()) { 572 continue; 573 } else { 574 visitedIFD[visited] = 1; // processed 575 } 576 577 // determine how many entries there are in the current IFD 578 nde = ReadUint16(msb_order, ifdp); 579 580 for(; de < nde; de++) { 581 char *pde = NULL; // pointer to the directory entry 582 char *pval = NULL; // pointer to the tag value 583 584 // create a tag 585 FITAG *tag = FreeImage_CreateTag(); 586 if(!tag) return FALSE; 587 588 // point to the directory entry 589 pde = (char*) DIR_ENTRY_ADDR(ifdp, de); 590 591 // get the tag ID 592 FreeImage_SetTagID(tag, ReadUint16(msb_order, pde)); 593 // get the tag type 594 WORD tag_type = (WORD)ReadUint16(msb_order, pde + 2); 595 if((tag_type - 1) >= EXIF_NUM_FORMATS) { 596 // a problem occured : delete the tag (not free'd after) 597 FreeImage_DeleteTag(tag); 598 // break out of the for loop 599 break; 600 } 601 FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)tag_type); 602 603 // get number of components 604 FreeImage_SetTagCount(tag, ReadUint32(msb_order, pde + 4)); 605 // check that tag length (size of the tag value in bytes) will fit in a DWORD 606 unsigned tag_data_width = FreeImage_TagDataWidth(FreeImage_GetTagType(tag)); 607 if (tag_data_width != 0 && FreeImage_GetTagCount(tag) > ~(DWORD)0 / tag_data_width) { 608 FreeImage_DeleteTag(tag); 609 // jump to next entry 610 continue; 611 } 612 FreeImage_SetTagLength(tag, FreeImage_GetTagCount(tag) * tag_data_width); 613 614 if(FreeImage_GetTagLength(tag) <= 4) { 615 // 4 bytes or less and value is in the dir entry itself 616 pval = pde + 8; 617 } else { 618 // if its bigger than 4 bytes, the directory entry contains an offset 619 // first check if offset exceeds buffer, at this stage FreeImage_GetTagLength may return invalid data 620 DWORD offset_value = ReadUint32(msb_order, pde + 8); 621 if(offset_value > length) { 622 // a problem occured : delete the tag (not free'd after) 623 FreeImage_DeleteTag(tag); 624 // jump to next entry 625 continue; 626 } 627 // now check that length does not exceed the buffer size 628 if(FreeImage_GetTagLength(tag) > length - offset_value){ 629 // a problem occured : delete the tag (not free'd after) 630 FreeImage_DeleteTag(tag); 631 // jump to next entry 632 continue; 633 } 634 pval = (char*)(tiffp + offset_value); 635 } 636 637 // check for a IFD offset 638 BOOL isIFDOffset = FALSE; 639 switch(FreeImage_GetTagID(tag)) { 640 case TAG_EXIF_OFFSET: 641 case TAG_GPS_OFFSET: 642 case TAG_INTEROP_OFFSET: 643 case TAG_MAKER_NOTE: 644 isIFDOffset = TRUE; 645 break; 646 } 647 if(isIFDOffset) { 648 DWORD sub_offset = 0; 649 TagLib::MDMODEL next_mdmodel = md_model; 650 const BYTE *next_ifd = ifdp; 651 652 // get offset and metadata model 653 if (FreeImage_GetTagID(tag) == TAG_MAKER_NOTE) { 654 processMakerNote(dib, pval, msb_order, &sub_offset, &next_mdmodel); 655 next_ifd = (BYTE*)pval + sub_offset; 656 } else { 657 processIFDOffset(tag, pval, msb_order, &sub_offset, &next_mdmodel); 658 next_ifd = (BYTE*)tiffp + sub_offset; 659 } 660 661 if((sub_offset < (DWORD) length) && (next_mdmodel != TagLib::UNKNOWN)) { 662 // push our current directory state onto the stack 663 ifdstack.push(ifdp); 664 // bump to the next entry 665 de++; 666 destack.push(de); 667 668 // push our current metadata model 669 modelstack.push(md_model); 670 671 // push new state onto of stack to cause a jump 672 ifdstack.push(next_ifd); 673 destack.push(0); 674 675 // select a new metadata model 676 modelstack.push(next_mdmodel); 677 678 // delete the tag as it won't be stored nor deleted in the for() loop 679 FreeImage_DeleteTag(tag); 680 681 break; // break out of the for loop 682 } 683 else { 684 // unsupported camera model, canon maker tag or something unknown 685 // process as a standard tag 686 processExifTag(dib, tag, pval, msb_order, md_model); 687 } 688 689 } else { 690 // process as a standard tag 691 processExifTag(dib, tag, pval, msb_order, md_model); 692 } 693 694 // delete the tag 695 FreeImage_DeleteTag(tag); 696 697 } // for(nde) 698 699 // additional thumbnail data is skipped 700 701 } while (!destack.empty()); 702 703 // 704 // --- handle thumbnail data --- 705 // 706 707 const WORD entriesCount0th = ReadUint16(msb_order, ifd0th); 708 709 DWORD next_offset = ReadUint32(msb_order, DIR_ENTRY_ADDR(ifd0th, entriesCount0th)); 710 if((next_offset == 0) || (next_offset >= length)) { 711 return TRUE; //< no thumbnail 712 } 713 714 const BYTE* const ifd1st = (BYTE*)tiffp + next_offset; 715 const WORD entriesCount1st = ReadUint16(msb_order, ifd1st); 716 717 unsigned thCompression = 0; 718 unsigned thOffset = 0; 719 unsigned thSize = 0; 720 721 for(int e = 0; e < entriesCount1st; e++) { 722 723 // point to the directory entry 724 const BYTE* base = DIR_ENTRY_ADDR(ifd1st, e); 725 726 // check for buffer overflow 727 const size_t remaining = (size_t)base + 12 - (size_t)tiffp; 728 if(remaining >= length) { 729 // bad IFD1 directory, ignore it 730 return FALSE; 731 } 732 733 // get the tag ID 734 WORD tag = ReadUint16(msb_order, base); 735 // get the tag type 736 WORD type = ReadUint16(msb_order, base + sizeof(WORD)); 737 // get number of components 738 DWORD count = ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD)); 739 // get the tag value 740 DWORD offset = ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD) + sizeof(DWORD)); 741 742 switch(tag) { 743 case TAG_COMPRESSION: 744 // Tiff Compression Tag (should be COMPRESSION_OJPEG (6), but is not always respected) 745 thCompression = offset; 746 break; 747 case TAG_JPEG_INTERCHANGE_FORMAT: 748 // Tiff JPEGInterchangeFormat Tag 749 thOffset = offset; 750 break; 751 case TAG_JPEG_INTERCHANGE_FORMAT_LENGTH: 752 // Tiff JPEGInterchangeFormatLength Tag 753 thSize = offset; 754 break; 755 // ### X and Y Resolution ignored, orientation ignored 756 case TAG_X_RESOLUTION: // XResolution 757 case TAG_Y_RESOLUTION: // YResolution 758 case TAG_RESOLUTION_UNIT: // ResolutionUnit 759 case TAG_ORIENTATION: // Orientation 760 break; 761 default: 762 break; 763 } 764 } 765 766 if(/*thCompression != 6 ||*/ thOffset == 0 || thSize == 0) { 767 return TRUE; 768 } 769 770 if(thOffset + thSize > length) { 771 return TRUE; 772 } 773 774 // load the thumbnail 775 776 const BYTE *thLocation = tiffp + thOffset; 777 778 FIMEMORY* hmem = FreeImage_OpenMemory(const_cast<BYTE*>(thLocation), thSize); 779 FIBITMAP* thumbnail = FreeImage_LoadFromMemory(FIF_JPEG, hmem); 780 FreeImage_CloseMemory(hmem); 781 782 // store the thumbnail 783 FreeImage_SetThumbnail(dib, thumbnail); 784 // then delete it 785 FreeImage_Unload(thumbnail); 786 787 return TRUE; 788} 789 790/** 791 Read and decode JPEG_APP1 marker (Exif profile) 792 @param dib Input FIBITMAP 793 @param dataptr Pointer to the APP1 marker 794 @param datalen APP1 marker length 795 @return Returns TRUE if successful, FALSE otherwise 796*/ 797BOOL 798jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) { 799 // marker identifying string for Exif = "Exif\0\0" 800 BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; 801 BYTE lsb_first[4] = { 0x49, 0x49, 0x2A, 0x00 }; // Intel order 802 BYTE msb_first[4] = { 0x4D, 0x4D, 0x00, 0x2A }; // Motorola order 803 804 unsigned int length = datalen; 805 BYTE *profile = (BYTE*)dataptr; 806 807 // verify the identifying string 808 809 if(memcmp(exif_signature, profile, sizeof(exif_signature)) == 0) { 810 // Exif profile - TIFF header with 2 IFDs. 0th - the image attributes, 1st - may be used for thumbnail 811 812 profile += sizeof(exif_signature); 813 length -= sizeof(exif_signature); 814 815 // read the TIFF header (8 bytes) 816 817 // check the endianess order 818 819 BOOL bMotorolaOrder = TRUE; 820 821 if(memcmp(profile, lsb_first, sizeof(lsb_first)) == 0) { 822 // Exif section in Intel order 823 bMotorolaOrder = FALSE; 824 } else { 825 if(memcmp(profile, msb_first, sizeof(msb_first)) == 0) { 826 // Exif section in Motorola order 827 bMotorolaOrder = TRUE; 828 } else { 829 // Invalid Exif alignment marker 830 return FALSE; 831 } 832 } 833 834 // this is the offset to the first IFD (Image File Directory) 835 unsigned long first_offset = ReadUint32(bMotorolaOrder, profile + 4); 836 if (first_offset > length) { 837 // bad Exif data 838 return FALSE; 839 } 840 841 /* 842 Note: as FreeImage 3.14.0, this test is no longer needed for images with similar suspicious offset 843 => tested with Pentax Optio 230, FujiFilm SP-2500 and Canon EOS 300D 844 if (first_offset < 8 || first_offset > 16) { 845 // This is usually set to 8 846 // but PENTAX Optio 230 has it set differently, and uses it as offset. 847 FreeImage_OutputMessageProc(FIF_JPEG, "Exif: Suspicious offset of first IFD value"); 848 return FALSE; 849 } 850 */ 851 852 // process Exif directories 853 return jpeg_read_exif_dir(dib, profile, first_offset, length, bMotorolaOrder); 854 } 855 856 return FALSE; 857} 858 859