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 // - Garrick Meeker (garrickmeeker@users.sourceforge.net)
9 //
10 // Based on the following implementations:
11 // - metadata-extractor : http://www.drewnoakes.com/code/exif/
12 // - jhead : http://www.sentex.net/~mwandel/jhead/
13 // - ImageMagick : http://www.imagemagick.org/
14 //
15 // This file is part of FreeImage 3
16 //
17 // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
18 // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
19 // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
20 // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
21 // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
22 // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
23 // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
24 // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
25 // THIS DISCLAIMER.
26 //
27 // Use at your own risk!
28 // ==========================================================
29
30 #ifdef _MSC_VER
31 #pragma warning (disable : 4786) // identifier was truncated to 'number' characters
32 #endif
33
34 #include "FreeImage.h"
35 #include "Utilities.h"
36 #include "FreeImageTag.h"
37
38 // ==========================================================
39 // Exif JPEG routines
40 // ==========================================================
41
42 #define EXIF_NUM_FORMATS 12
43
44 #define TAG_EXIF_OFFSET 0x8769 // Exif IFD Pointer
45 #define TAG_GPS_OFFSET 0x8825 // GPS Info IFD Pointer
46 #define TAG_INTEROP_OFFSET 0xA005 // Interoperability IFD Pointer
47 #define TAG_MAKER_NOTE 0x927C // Maker note
48
49 // CANON cameras have some funny bespoke fields that need further processing...
50 #define TAG_CANON_CAMERA_STATE_0x01 0x0001 // tags under tag 0x001 (CameraSettings)
51 #define TAG_CANON_CAMERA_STATE_0x02 0x0002 // tags under tag 0x002 (FocalLength)
52 #define TAG_CANON_CAMERA_STATE_0x04 0x0004 // tags under tag 0x004 (ShotInfo)
53 #define TAG_CANON_CAMERA_STATE_0x12 0x0012 // tags under tag 0x012 (AFInfo)
54 #define TAG_CANON_CAMERA_STATE_0xA0 0x00A0 // tags under tag 0x0A0 (ProcessingInfo)
55 #define TAG_CANON_CAMERA_STATE_0xE0 0x00E0 // tags under tag 0x0E0 (SensorInfo)
56
57
58 // =====================================================================
59 // Reimplementation of strnicmp (it is not supported on some systems)
60 // =====================================================================
61
62 /**
63 Compare characters of two strings without regard to case.
64 @param s1 Null-terminated string to compare.
65 @param s2 Null-terminated string to compare.
66 @param len Number of characters to compare
67 @return Returns 0 if s1 substring identical to s2 substring
68 */
69 static int
FreeImage_strnicmp(const char * s1,const char * s2,size_t len)70 FreeImage_strnicmp(const char *s1, const char *s2, size_t len) {
71 unsigned char c1, c2;
72
73 if(!s1 || !s2) return -1;
74
75 c1 = 0; c2 = 0;
76 if(len) {
77 do {
78 c1 = *s1; c2 = *s2;
79 s1++; s2++;
80 if (!c1)
81 break;
82 if (!c2)
83 break;
84 if (c1 == c2)
85 continue;
86 c1 = (BYTE)tolower(c1);
87 c2 = (BYTE)tolower(c2);
88 if (c1 != c2)
89 break;
90 } while (--len);
91 }
92 return (int)c1 - (int)c2;
93 }
94
95
96 // ----------------------------------------------------------
97 // Little Endian / Big Endian io routines
98 // ----------------------------------------------------------
99
100 static short
ReadInt16(BOOL msb_order,const void * buffer)101 ReadInt16(BOOL msb_order, const void *buffer) {
102 short value;
103
104 if(msb_order) {
105 value = (short)((((BYTE*) buffer)[0] << 8) | ((BYTE*) buffer)[1]);
106 return value;
107 }
108 value = (short)((((BYTE*) buffer)[1] << 8) | ((BYTE*) buffer)[0]);
109 return value;
110 }
111
112 static LONG
ReadInt32(BOOL msb_order,const void * buffer)113 ReadInt32(BOOL msb_order, const void *buffer) {
114 LONG value;
115
116 if(msb_order) {
117 value = (LONG)((((BYTE*) buffer)[0] << 24) | (((BYTE*) buffer)[1] << 16) | (((BYTE*) buffer)[2] << 8) | (((BYTE*) buffer)[3]));
118 return value;
119 }
120 value = (LONG)((((BYTE*) buffer)[3] << 24) | (((BYTE*) buffer)[2] << 16) | (((BYTE*) buffer)[1] << 8 ) | (((BYTE*) buffer)[0]));
121 return value;
122 }
123
124 static WORD
ReadUint16(BOOL msb_order,const void * buffer)125 ReadUint16(BOOL msb_order, const void *buffer) {
126 WORD value;
127
128 if(msb_order) {
129 value = (WORD) ((((BYTE*) buffer)[0] << 8) | ((BYTE*) buffer)[1]);
130 return value;
131 }
132 value = (WORD) ((((BYTE*) buffer)[1] << 8) | ((BYTE*) buffer)[0]);
133 return value;
134 }
135
136 static DWORD
ReadUint32(BOOL msb_order,const void * buffer)137 ReadUint32(BOOL msb_order, const void *buffer) {
138 return ((DWORD) ReadInt32(msb_order, buffer) & 0xFFFFFFFF);
139 }
140
141 // ----------------------------------------------------------
142 // Exif JPEG markers routines
143 // ----------------------------------------------------------
144
145 /**
146 Process a IFD offset
147 Returns the offset and the metadata model for this tag
148 */
149 static void
processIFDOffset(FITAG * tag,const char * pval,BOOL msb_order,DWORD * subdirOffset,TagLib::MDMODEL * md_model)150 processIFDOffset(FITAG *tag, const char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) {
151 // get the IFD offset
152 *subdirOffset = ReadUint32(msb_order, pval);
153
154 // select a tag info table
155 switch(FreeImage_GetTagID(tag)) {
156 case TAG_EXIF_OFFSET:
157 *md_model = TagLib::EXIF_EXIF;
158 break;
159 case TAG_GPS_OFFSET:
160 *md_model = TagLib::EXIF_GPS;
161 break;
162 case TAG_INTEROP_OFFSET:
163 *md_model = TagLib::EXIF_INTEROP;
164 break;
165 }
166 }
167
168 /**
169 Process a maker note IFD offset
170 Returns the offset and the metadata model for this tag
171 */
172 static void
processMakerNote(FIBITMAP * dib,const char * pval,BOOL msb_order,DWORD * subdirOffset,TagLib::MDMODEL * md_model)173 processMakerNote(FIBITMAP *dib, const 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 little-endian order altough the Exif section maybe in little-endian order or in big-endian 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 = 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 /**
304 Process a Canon maker note tag.
305 A single Canon tag may contain many other tags within.
306 */
307 static BOOL
processCanonMakerNoteTag(FIBITMAP * dib,FITAG * tag)308 processCanonMakerNoteTag(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 /**
400 Process a standard Exif tag
401 */
402 static void
processExifTag(FIBITMAP * dib,FITAG * tag,char * pval,BOOL msb_order,TagLib::MDMODEL md_model)403 processExifTag(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 dwOffsetIfd0 Offset to the 0th IFD (first IFD)
523 @param dwLength Length of the Exif file
524 @param dwProfileOffset File offset to be used when reading 'offset/value' tags
525 @param msb_order Endianness order of the Exif file (TRUE if big-endian, FALSE if little-endian)
526 @param starting_md_model Metadata model of the IFD (should be TagLib::EXIF_MAIN for a jpeg)
527 @return Returns TRUE if sucessful, returns FALSE otherwise
528 */
529 static BOOL
jpeg_read_exif_dir(FIBITMAP * dib,const BYTE * tiffp,DWORD dwOffsetIfd0,DWORD dwLength,DWORD dwProfileOffset,BOOL msb_order,TagLib::MDMODEL starting_md_model)530 jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, DWORD dwOffsetIfd0, DWORD dwLength, DWORD dwProfileOffset, BOOL msb_order, TagLib::MDMODEL starting_md_model) {
531 WORD de, nde;
532
533 std::stack<WORD> destack; // directory entries stack
534 std::stack<const BYTE*> ifdstack; // IFD stack
535 std::stack<TagLib::MDMODEL> modelstack; // metadata model stack
536
537 // Keep a list of already visited IFD to avoid stack overflows
538 // when recursive/cyclic directory structures exist.
539 // This kind of recursive Exif file was encountered with Kodak images coming from
540 // KODAK PROFESSIONAL DCS Photo Desk JPEG Export v3.2 W
541 std::map<DWORD, int> visitedIFD;
542
543 /*
544 "An Image File Directory (IFD) consists of a 2-byte count of the number of directory
545 entries (i.e. the number of fields), followed by a sequence of 12-byte field
546 entries, followed by a 4-byte offset of the next IFD (or 0 if none)."
547 The "next IFD" (1st IFD) is the thumbnail.
548 */
549 #define DIR_ENTRY_ADDR(_start, _entry) (_start + 2 + (12 * _entry))
550
551 // set the metadata model to Exif
552
553 TagLib::MDMODEL md_model = starting_md_model;
554
555 // set the pointer to the first IFD (0th IFD) and follow it were it leads.
556
557 const BYTE *ifd0th = (BYTE*)tiffp + (size_t)dwOffsetIfd0;
558
559 const BYTE *ifdp = ifd0th;
560
561 de = 0;
562
563 do {
564 // if there is anything on the stack then pop it off
565 if(!destack.empty()) {
566 ifdp = ifdstack.top(); ifdstack.pop();
567 de = destack.top(); destack.pop();
568 md_model = modelstack.top(); modelstack.pop();
569 }
570
571 // remember that we've visited this directory and entry so that we don't visit it again later
572 DWORD visited = (DWORD)( (((size_t)ifdp & 0xFFFF) << 16) | (size_t)de );
573 if(visitedIFD.find(visited) != visitedIFD.end()) {
574 continue;
575 } else {
576 visitedIFD[visited] = 1; // processed
577 }
578
579 // determine how many entries there are in the current IFD
580 nde = ReadUint16(msb_order, ifdp);
581 if (((size_t)(ifdp - tiffp) + 12 * nde) > (size_t)dwLength) {
582 // suspicious IFD offset, ignore
583 continue;
584 }
585
586 for(; de < nde; de++) {
587 char *pde = NULL; // pointer to the directory entry
588 char *pval = NULL; // pointer to the tag value
589
590 // create a tag
591 FITAG *tag = FreeImage_CreateTag();
592 if(!tag) return FALSE;
593
594 // point to the directory entry
595 pde = (char*) DIR_ENTRY_ADDR(ifdp, de);
596
597 // get the tag ID
598 WORD tag_id = ReadUint16(msb_order, pde);
599 FreeImage_SetTagID(tag, tag_id);
600
601 // get the tag type
602 WORD tag_type = (WORD)ReadUint16(msb_order, pde + 2);
603 if((tag_type - 1) >= EXIF_NUM_FORMATS) {
604 // a problem occured : delete the tag (not free'd after)
605 FreeImage_DeleteTag(tag);
606 // break out of the for loop
607 break;
608 }
609 FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)tag_type);
610
611 // get number of components
612 DWORD tag_count = ReadUint32(msb_order, pde + 4);
613 FreeImage_SetTagCount(tag, tag_count);
614
615 // check that tag length (size of the tag value in bytes) will fit in a DWORD
616 unsigned tag_data_width = FreeImage_TagDataWidth(FreeImage_GetTagType(tag));
617 if (tag_data_width != 0 && FreeImage_GetTagCount(tag) > ~(DWORD)0 / tag_data_width) {
618 FreeImage_DeleteTag(tag);
619 // jump to next entry
620 continue;
621 }
622 FreeImage_SetTagLength(tag, FreeImage_GetTagCount(tag) * tag_data_width);
623
624 if(FreeImage_GetTagLength(tag) <= 4) {
625 // 4 bytes or less and value is in the dir entry itself
626 pval = pde + 8;
627 } else {
628 // if its bigger than 4 bytes, the directory entry contains an offset
629 DWORD offset_value = ReadUint32(msb_order, pde + 8);
630 // the offset can be relative to tiffp or to an external reference (see JPEG-XR)
631 if(dwProfileOffset) {
632 offset_value -= dwProfileOffset;
633 }
634 // first check if offset exceeds buffer, at this stage FreeImage_GetTagLength may return invalid data
635 if(offset_value > dwLength) {
636 // a problem occured : delete the tag (not free'd after)
637 FreeImage_DeleteTag(tag);
638 // jump to next entry
639 continue;
640 }
641 // now check that length does not exceed the buffer size
642 if(FreeImage_GetTagLength(tag) > dwLength - offset_value){
643 // a problem occured : delete the tag (not free'd after)
644 FreeImage_DeleteTag(tag);
645 // jump to next entry
646 continue;
647 }
648 pval = (char*)(tiffp + offset_value);
649 }
650
651 // check for a IFD offset
652 BOOL isIFDOffset = FALSE;
653 switch(FreeImage_GetTagID(tag)) {
654 case TAG_EXIF_OFFSET:
655 case TAG_GPS_OFFSET:
656 case TAG_INTEROP_OFFSET:
657 case TAG_MAKER_NOTE:
658 isIFDOffset = TRUE;
659 break;
660 }
661 if(isIFDOffset) {
662 DWORD sub_offset = 0;
663 TagLib::MDMODEL next_mdmodel = md_model;
664 const BYTE *next_ifd = ifdp;
665
666 // get offset and metadata model
667 if (FreeImage_GetTagID(tag) == TAG_MAKER_NOTE) {
668 processMakerNote(dib, pval, msb_order, &sub_offset, &next_mdmodel);
669 next_ifd = (BYTE*)pval + sub_offset;
670 } else {
671 processIFDOffset(tag, pval, msb_order, &sub_offset, &next_mdmodel);
672 next_ifd = (BYTE*)tiffp + sub_offset;
673 }
674
675 if((sub_offset < dwLength) && (next_mdmodel != TagLib::UNKNOWN)) {
676 // push our current directory state onto the stack
677 ifdstack.push(ifdp);
678 // jump to the next entry
679 de++;
680 destack.push(de);
681
682 // push our current metadata model
683 modelstack.push(md_model);
684
685 // push new state onto of stack to cause a jump
686 ifdstack.push(next_ifd);
687 destack.push(0);
688
689 // select a new metadata model
690 modelstack.push(next_mdmodel);
691
692 // delete the tag as it won't be stored nor deleted in the for() loop
693 FreeImage_DeleteTag(tag);
694
695 break; // break out of the for loop
696 }
697 else {
698 // unsupported camera model, canon maker tag or something unknown
699 // process as a standard tag
700 processExifTag(dib, tag, pval, msb_order, md_model);
701 }
702
703 } else {
704 // process as a standard tag
705 processExifTag(dib, tag, pval, msb_order, md_model);
706 }
707
708 // delete the tag
709 FreeImage_DeleteTag(tag);
710
711 } // for(nde)
712
713 // additional thumbnail data is skipped
714
715 } while (!destack.empty());
716
717 //
718 // --- handle thumbnail data ---
719 //
720
721 const WORD entriesCount0th = ReadUint16(msb_order, ifd0th);
722
723 DWORD next_offset = ReadUint32(msb_order, DIR_ENTRY_ADDR(ifd0th, entriesCount0th));
724 if((next_offset == 0) || (next_offset >= dwLength)) {
725 return TRUE; //< no thumbnail
726 }
727
728 const BYTE* const ifd1st = (BYTE*)tiffp + next_offset;
729 const WORD entriesCount1st = ReadUint16(msb_order, ifd1st);
730
731 unsigned thCompression = 0;
732 unsigned thOffset = 0;
733 unsigned thSize = 0;
734
735 for(int e = 0; e < entriesCount1st; e++) {
736
737 // point to the directory entry
738 const BYTE* base = DIR_ENTRY_ADDR(ifd1st, e);
739
740 // check for buffer overflow
741 const size_t remaining = (size_t)base + 12 - (size_t)tiffp;
742 if(remaining >= dwLength) {
743 // bad IFD1 directory, ignore it
744 return FALSE;
745 }
746
747 // get the tag ID
748 WORD tag = ReadUint16(msb_order, base);
749 // get the tag type
750 /*WORD type = */ReadUint16(msb_order, base + sizeof(WORD));
751 // get number of components
752 /*DWORD count = */ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD));
753 // get the tag value
754 DWORD offset = ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD) + sizeof(DWORD));
755
756 switch(tag) {
757 case TAG_COMPRESSION:
758 // Tiff Compression Tag (should be COMPRESSION_OJPEG (6), but is not always respected)
759 thCompression = offset;
760 break;
761 case TAG_JPEG_INTERCHANGE_FORMAT:
762 // Tiff JPEGInterchangeFormat Tag
763 thOffset = offset;
764 break;
765 case TAG_JPEG_INTERCHANGE_FORMAT_LENGTH:
766 // Tiff JPEGInterchangeFormatLength Tag
767 thSize = offset;
768 break;
769 // ### X and Y Resolution ignored, orientation ignored
770 case TAG_X_RESOLUTION: // XResolution
771 case TAG_Y_RESOLUTION: // YResolution
772 case TAG_RESOLUTION_UNIT: // ResolutionUnit
773 case TAG_ORIENTATION: // Orientation
774 break;
775 default:
776 break;
777 }
778 }
779
780 if(/*thCompression != 6 ||*/ thOffset == 0 || thSize == 0) {
781 return TRUE;
782 }
783
784 if(thOffset + thSize > dwLength) {
785 return TRUE;
786 }
787
788 // load the thumbnail
789
790 const BYTE *thLocation = tiffp + thOffset;
791
792 FIMEMORY* hmem = FreeImage_OpenMemory(const_cast<BYTE*>(thLocation), thSize);
793 FIBITMAP* thumbnail = FreeImage_LoadFromMemory(FIF_JPEG, hmem);
794 FreeImage_CloseMemory(hmem);
795
796 // store the thumbnail
797 FreeImage_SetThumbnail(dib, thumbnail);
798 // then delete it
799 FreeImage_Unload(thumbnail);
800
801 return TRUE;
802 }
803
804 // --------------------------------------------------------------------------
805
806 /**
807 Read and decode JPEG_APP1 marker (Exif profile)
808 @param dib Input FIBITMAP
809 @param data Pointer to the APP1 marker
810 @param length APP1 marker length
811 @return Returns TRUE if successful, FALSE otherwise
812 */
813 BOOL
jpeg_read_exif_profile(FIBITMAP * dib,const BYTE * data,unsigned length)814 jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *data, unsigned length) {
815 // marker identifying string for Exif = "Exif\0\0"
816 BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
817 BYTE lsb_first[4] = { 0x49, 0x49, 0x2A, 0x00 }; // Classic TIFF signature - little-endian order
818 BYTE msb_first[4] = { 0x4D, 0x4D, 0x00, 0x2A }; // Classic TIFF signature - big-endian order
819
820 // profile size is up to 32-bit
821 DWORD dwProfileLength = (DWORD)length;
822 BYTE *pbProfile = (BYTE*)data;
823
824 // verify the identifying string
825 if(memcmp(exif_signature, pbProfile, sizeof(exif_signature)) == 0) {
826 // This is an Exif profile
827 // should contain a TIFF header with up to 2 IFDs (IFD stands for 'Image File Directory')
828 // 0th IFD : the image attributes, 1st IFD : may be used for thumbnail
829
830 pbProfile += sizeof(exif_signature);
831 dwProfileLength -= sizeof(exif_signature);
832
833 // read the TIFF header (8 bytes)
834
835 // check the endianess order
836
837 BOOL bBigEndian = TRUE;
838
839 if(memcmp(pbProfile, lsb_first, sizeof(lsb_first)) == 0) {
840 // Exif section is in little-endian order
841 bBigEndian = FALSE;
842 } else {
843 if(memcmp(pbProfile, msb_first, sizeof(msb_first)) == 0) {
844 // Exif section is in big-endian order
845 bBigEndian = TRUE;
846 } else {
847 // Invalid Exif alignment marker
848 return FALSE;
849 }
850 }
851
852 // this is the offset to the first IFD (Image File Directory)
853 DWORD dwFirstOffset = ReadUint32(bBigEndian, pbProfile + 4);
854 if (dwFirstOffset > dwProfileLength) {
855 // bad Exif data
856 return FALSE;
857 }
858
859 /*
860 Note: as FreeImage 3.14.0, this test is no longer needed for images with similar suspicious offset
861 => tested with Pentax Optio 230, FujiFilm SP-2500 and Canon EOS 300D
862 if (dwFirstOffset < 8 || dwFirstOffset > 16) {
863 // This is usually set to 8
864 // but PENTAX Optio 230 has it set differently, and uses it as offset.
865 FreeImage_OutputMessageProc(FIF_JPEG, "Exif: Suspicious offset of first IFD value");
866 return FALSE;
867 }
868 */
869
870 // process Exif directories, starting with Exif-TIFF IFD
871 return jpeg_read_exif_dir(dib, pbProfile, dwFirstOffset, dwProfileLength, 0, bBigEndian, TagLib::EXIF_MAIN);
872 }
873
874 return FALSE;
875 }
876
877 // ==========================================================
878 // Exif JPEG helper routines
879 // ==========================================================
880
881 /**
882 Read JPEG_APP1 marker (Exif profile)
883 @param dib Input FIBITMAP
884 @param dataptr Pointer to the APP1 marker
885 @param datalen APP1 marker length
886 @return Returns TRUE if successful, FALSE otherwise
887 */
888 BOOL
jpeg_read_exif_profile_raw(FIBITMAP * dib,const BYTE * profile,unsigned length)889 jpeg_read_exif_profile_raw(FIBITMAP *dib, const BYTE *profile, unsigned length) {
890 // marker identifying string for Exif = "Exif\0\0"
891 BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
892
893 // verify the identifying string
894 if(memcmp(exif_signature, profile, sizeof(exif_signature)) != 0) {
895 // not an Exif profile
896 return FALSE;
897 }
898
899 // create a tag
900 FITAG *tag = FreeImage_CreateTag();
901 if(tag) {
902 FreeImage_SetTagKey(tag, g_TagLib_ExifRawFieldName);
903 FreeImage_SetTagLength(tag, (DWORD)length);
904 FreeImage_SetTagCount(tag, (DWORD)length);
905 FreeImage_SetTagType(tag, FIDT_BYTE);
906 FreeImage_SetTagValue(tag, profile);
907
908 // store the tag
909 FreeImage_SetMetadata(FIMD_EXIF_RAW, dib, FreeImage_GetTagKey(tag), tag);
910
911 // destroy the tag
912 FreeImage_DeleteTag(tag);
913
914 return TRUE;
915 }
916
917 return FALSE;
918 }
919
920 // ==========================================================
921 // Exif JPEG-XR helper routines
922 // ==========================================================
923
924 /**
925 Read and decode JPEG-XR Exif IFD
926 @param dib Input FIBITMAP
927 @param profile Pointer to the Exif marker
928 @param length Exif marker length
929 @param file_offset Reference offset in the original file of each tag value whose length is > 4
930 @return Returns TRUE if successful, FALSE otherwise
931 */
932 BOOL
jpegxr_read_exif_profile(FIBITMAP * dib,const BYTE * profile,unsigned length,unsigned file_offset)933 jpegxr_read_exif_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset) {
934 // assume Little Endian order
935 BOOL bBigEndian = FALSE;
936
937 // process Exif specific IFD
938 return jpeg_read_exif_dir(dib, profile, 0, length, file_offset, bBigEndian, TagLib::EXIF_EXIF);
939 }
940
941 /**
942 Read and decode JPEG-XR Exif-GPS IFD
943 @param dib Input FIBITMAP
944 @param profile Pointer to the Exif-GPS profile
945 @param length Exif-GPS profile length
946 @param file_offset Reference offset in the original file of each tag value whose length is > 4
947 @return Returns TRUE if successful, FALSE otherwise
948 */
949 BOOL
jpegxr_read_exif_gps_profile(FIBITMAP * dib,const BYTE * profile,unsigned length,unsigned file_offset)950 jpegxr_read_exif_gps_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset) {
951 // assume Little Endian order
952 BOOL bBigEndian = FALSE;
953
954 // process Exif GPS IFD
955 return jpeg_read_exif_dir(dib, profile, 0, length, file_offset, bBigEndian, TagLib::EXIF_GPS);
956 }
957
958 // ==========================================================
959 // Exif common helper routines
960 // ==========================================================
961
962 /**
963 Rotate a dib according to Exif info
964 @param dib Input / Output dib to rotate
965 @see PluginJPEG.cpp
966 */
967 void
RotateExif(FIBITMAP ** dib)968 RotateExif(FIBITMAP **dib) {
969 // check for Exif rotation
970 if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, *dib)) {
971 FIBITMAP *rotated = NULL;
972 // process Exif rotation
973 FITAG *tag = NULL;
974 FreeImage_GetMetadata(FIMD_EXIF_MAIN, *dib, "Orientation", &tag);
975 if((tag != NULL) && (FreeImage_GetTagID(tag) == TAG_ORIENTATION)) {
976 const WORD orientation = *((WORD *)FreeImage_GetTagValue(tag));
977 switch (orientation) {
978 case 1: // "top, left side" => 0�
979 break;
980 case 2: // "top, right side" => flip left-right
981 FreeImage_FlipHorizontal(*dib);
982 break;
983 case 3: // "bottom, right side" => -180�
984 rotated = FreeImage_Rotate(*dib, 180);
985 FreeImage_Unload(*dib);
986 *dib = rotated;
987 break;
988 case 4: // "bottom, left side" => flip up-down
989 FreeImage_FlipVertical(*dib);
990 break;
991 case 5: // "left side, top" => +90� + flip up-down
992 rotated = FreeImage_Rotate(*dib, 90);
993 FreeImage_Unload(*dib);
994 *dib = rotated;
995 FreeImage_FlipVertical(*dib);
996 break;
997 case 6: // "right side, top" => -90�
998 rotated = FreeImage_Rotate(*dib, -90);
999 FreeImage_Unload(*dib);
1000 *dib = rotated;
1001 break;
1002 case 7: // "right side, bottom" => -90� + flip up-down
1003 rotated = FreeImage_Rotate(*dib, -90);
1004 FreeImage_Unload(*dib);
1005 *dib = rotated;
1006 FreeImage_FlipVertical(*dib);
1007 break;
1008 case 8: // "left side, bottom" => +90�
1009 rotated = FreeImage_Rotate(*dib, 90);
1010 FreeImage_Unload(*dib);
1011 *dib = rotated;
1012 break;
1013 default:
1014 break;
1015 }
1016 }
1017 }
1018 }
1019
1020 // ==========================================================
1021 // Exif TIFF JPEG-XR helper routines
1022 // ==========================================================
1023
1024 class PredicateTagIDCompare {
1025 public:
operator ()(FITAG * a,FITAG * b)1026 bool operator()(FITAG *a, FITAG *b) {
1027 WORD tag_id_a = FreeImage_GetTagID(a);
1028 WORD tag_id_b = FreeImage_GetTagID(b);
1029 return (tag_id_a < tag_id_b);
1030 }
1031 };
1032
1033 /**
1034 Write a metadata model as a TIF IFD to a FIMEMORY handle.
1035 The entries in the TIF IFD are sorted in ascending order by tag id.
1036 The last entry is written as 0 (4 bytes) which means no more IFD to follow.
1037 Supported metadata models are
1038 <ul>
1039 <li>FIMD_EXIF_MAIN
1040 <li>FIMD_EXIF_EXIF
1041 <li>FIMD_EXIF_GPS
1042 <li>FIMD_EXIF_INTEROP
1043 </ul>
1044 The end of the buffer is filled with 4 bytes equal to 0 (end of IFD offset)
1045
1046 @param dib Input FIBITMAP
1047 @param md_model Metadata model to write
1048 @param hmem Memory handle
1049 @return Returns TRUE if successful, FALSE otherwise
1050 @see tiff_get_ifd_profile
1051 */
1052 static BOOL
tiff_write_ifd(FIBITMAP * dib,FREE_IMAGE_MDMODEL md_model,FIMEMORY * hmem)1053 tiff_write_ifd(FIBITMAP *dib, FREE_IMAGE_MDMODEL md_model, FIMEMORY *hmem) {
1054 FITAG *tag = NULL;
1055 FIMETADATA *mdhandle = NULL;
1056 std::vector<FITAG*> vTagList;
1057 TagLib::MDMODEL internal_md_model;
1058
1059 DWORD ifd_offset = 0; // WORD-aligned IFD value offset
1060
1061 const BYTE empty_byte = 0;
1062
1063 // start of the file
1064 const long start_of_file = FreeImage_TellMemory(hmem);
1065
1066 // get the metadata count
1067 unsigned metadata_count = FreeImage_GetMetadataCount(md_model, dib);
1068 if(metadata_count == 0) {
1069 return FALSE;
1070 }
1071
1072 TagLib& s = TagLib::instance();
1073
1074 // check for supported metadata models
1075 switch(md_model) {
1076 case FIMD_EXIF_MAIN:
1077 internal_md_model = TagLib::EXIF_MAIN;
1078 break;
1079 case FIMD_EXIF_EXIF:
1080 internal_md_model = TagLib::EXIF_EXIF;
1081 break;
1082 case FIMD_EXIF_GPS:
1083 internal_md_model = TagLib::EXIF_GPS;
1084 break;
1085 case FIMD_EXIF_INTEROP:
1086 internal_md_model = TagLib::EXIF_INTEROP;
1087 break;
1088 default:
1089 return FALSE;
1090 }
1091
1092 try {
1093 // 1) according to the TIFF specifications,
1094 // the entries in a TIF IFD must be sorted in ascending order by tag id
1095
1096 // store the tags into a vector
1097 vTagList.reserve(metadata_count);
1098 mdhandle = FreeImage_FindFirstMetadata(md_model, dib, &tag);
1099 if(mdhandle) {
1100 // parse the tags and store them inside vTagList
1101 do {
1102 // rewrite the tag id using FreeImage internal database
1103 // (in case the tag id is wrong or missing)
1104 const char *key = FreeImage_GetTagKey(tag);
1105 int tag_id = s.getTagID(internal_md_model, key);
1106 if(tag_id != -1) {
1107 // this is a known tag, set the tag ID
1108 FreeImage_SetTagID(tag, (WORD)tag_id);
1109 // record the tag
1110 vTagList.push_back(tag);
1111 }
1112 // else ignore this tag
1113 } while(FreeImage_FindNextMetadata(mdhandle, &tag));
1114
1115 FreeImage_FindCloseMetadata(mdhandle);
1116
1117 // sort the vector by tag id
1118 std::sort(vTagList.begin(), vTagList.end(), PredicateTagIDCompare());
1119
1120 // update the metadata_count
1121 metadata_count = (unsigned)vTagList.size();
1122
1123 } else {
1124 throw(1);
1125 }
1126
1127 // 2) prepare the place for each IFD entries.
1128
1129 /*
1130 An Image File Directory (IFD) consists of a 2-byte count of the number of directory entries (i.e., the number of fields),
1131 followed by a sequence of 12-byte field entries,
1132 followed by a 4-byte offset of the next IFD (or 0 if none). Do not forget to write the 4 bytes of 0 after the last IFD.
1133 */
1134
1135 {
1136 // prepare place for 2 bytes for number of entries + 12 bytes for each entry
1137 unsigned ifd_size = 2 + 12 * metadata_count;
1138 FreeImage_WriteMemory(&empty_byte, 1, ifd_size, hmem);
1139 // record the offset used to write values > 4-bytes
1140 ifd_offset = FreeImage_TellMemory(hmem);
1141 // rewind
1142 FreeImage_SeekMemory(hmem, start_of_file, SEEK_SET);
1143 }
1144
1145 // 3) write each IFD entry in tag id ascending order
1146
1147 // number of directory entries
1148 WORD nde = (WORD)metadata_count;
1149 FreeImage_WriteMemory(&nde, 1, 2, hmem);
1150
1151 // for each entry ...
1152 for(unsigned i = 0; i < metadata_count; i++) {
1153 FITAG *tag = vTagList[i];
1154 // tag id
1155 WORD tag_id = FreeImage_GetTagID(tag);
1156 FreeImage_WriteMemory(&tag_id, 1, 2, hmem);
1157 // tag type (compliant with TIFF specification)
1158 WORD tag_type = (WORD)FreeImage_GetTagType(tag);
1159 FreeImage_WriteMemory(&tag_type, 1, 2, hmem);
1160 // tag count
1161 DWORD tag_count = FreeImage_GetTagCount(tag);
1162 FreeImage_WriteMemory(&tag_count, 1, 4, hmem);
1163 // tag value or offset (results are in BYTE's units)
1164 unsigned tag_length = FreeImage_GetTagLength(tag);
1165 if(tag_length <= 4) {
1166 // 4 bytes or less, write the value (left justified)
1167 const BYTE *tag_value = (BYTE*)FreeImage_GetTagValue(tag);
1168 FreeImage_WriteMemory(tag_value, 1, tag_length, hmem);
1169 for(unsigned k = tag_length; k < 4; k++) {
1170 FreeImage_WriteMemory(&empty_byte, 1, 1, hmem);
1171 }
1172 } else {
1173 // write an offset
1174 FreeImage_WriteMemory(&ifd_offset, 1, 4, hmem);
1175 // write the value
1176 long current_position = FreeImage_TellMemory(hmem);
1177 FreeImage_SeekMemory(hmem, ifd_offset, SEEK_SET);
1178 FreeImage_WriteMemory(FreeImage_GetTagValue(tag), 1, tag_length, hmem);
1179 if(tag_length & 1) {
1180 // align to the next WORD boundary
1181 FreeImage_WriteMemory(&empty_byte, 1, 1, hmem);
1182 }
1183 // next offset to use
1184 ifd_offset = FreeImage_TellMemory(hmem);
1185 // rewind
1186 FreeImage_SeekMemory(hmem, current_position, SEEK_SET);
1187 }
1188 }
1189
1190 // end-of-IFD or next IFD (0 == none)
1191 FreeImage_SeekMemory(hmem, ifd_offset, SEEK_SET);
1192 FreeImage_WriteMemory(&empty_byte, 1, 4, hmem);
1193
1194 return TRUE;
1195 }
1196 catch(int) {
1197 return FALSE;
1198 }
1199 }
1200
1201 /**
1202 Write a metadata model as a TIF IFD, returns the IFD as a buffer.
1203 The buffer is allocated by the function and must be freed by the caller, using 'free'.
1204 @param dib Input FIBITMAP
1205 @param md_model Metadata model to write
1206 @param ppbProfile Returned buffer
1207 @param uProfileLength Returned buffer size
1208 @return Returns TRUE if successful, FALSE otherwise
1209 @see tiff_write_ifd
1210 */
1211 BOOL
tiff_get_ifd_profile(FIBITMAP * dib,FREE_IMAGE_MDMODEL md_model,BYTE ** ppbProfile,unsigned * uProfileLength)1212 tiff_get_ifd_profile(FIBITMAP *dib, FREE_IMAGE_MDMODEL md_model, BYTE **ppbProfile, unsigned *uProfileLength) {
1213 FIMEMORY *hmem = NULL;
1214
1215 try {
1216 // open a memory stream
1217 hmem = FreeImage_OpenMemory(NULL, 0);
1218 if(!hmem) {
1219 throw(1);
1220 }
1221
1222 // write the metadata model as a TIF IFD
1223 BOOL bResult = tiff_write_ifd(dib, md_model, hmem);
1224
1225 if(bResult) {
1226 BYTE *data = NULL;
1227 DWORD size_in_bytes = 0;
1228
1229 // get a pointer to the stream buffer
1230 FreeImage_AcquireMemory(hmem, &data, &size_in_bytes);
1231
1232 // (re-)allocate output buffer
1233 BYTE *pbProfile = *ppbProfile;
1234 pbProfile = (BYTE*)realloc(pbProfile, size_in_bytes);
1235 if(!pbProfile) {
1236 throw(1);
1237 } else {
1238 // copy IFD
1239 memcpy(pbProfile, data, size_in_bytes);
1240 *ppbProfile = pbProfile;
1241 *uProfileLength = size_in_bytes;
1242 }
1243 }
1244
1245 // free the memory stream
1246 FreeImage_CloseMemory(hmem);
1247
1248 return bResult;
1249
1250 } catch(int) {
1251 FreeImage_CloseMemory(hmem);
1252 return FALSE;
1253 }
1254 }
1255
1256 // ----------------------------------------------------------
1257 // Exif PSD routines
1258 // ----------------------------------------------------------
1259
1260 /**
1261 Read and decode PSD image resource (Exif profile)
1262 @param dib Input FIBITMAP
1263 @param data Pointer to the resource data
1264 @param length Resource length
1265 @return Returns TRUE if successful, FALSE otherwise
1266 */
1267 BOOL
psd_read_exif_profile(FIBITMAP * dib,const BYTE * data,unsigned int length)1268 psd_read_exif_profile(FIBITMAP *dib, const BYTE *data, unsigned int length) {
1269 BYTE lsb_first[4] = { 0x49, 0x49, 0x2A, 0x00 }; // Classic TIFF signature - little-endian order
1270 BYTE msb_first[4] = { 0x4D, 0x4D, 0x00, 0x2A }; // Classic TIFF signature - big-endian order
1271
1272 // profile size is up to 32-bit
1273 DWORD dwProfileLength = (DWORD)length;
1274 BYTE *pbProfile = (BYTE*)data;
1275
1276 // This is an Exif profile
1277 // should contain a TIFF header with up to 2 IFDs (IFD stands for 'Image File Directory')
1278 // 0th IFD : the image attributes, 1st IFD : may be used for thumbnail
1279
1280 // read the TIFF header (8 bytes)
1281
1282 // check the endianess order
1283
1284 BOOL bBigEndian = TRUE;
1285
1286 if(memcmp(pbProfile, lsb_first, sizeof(lsb_first)) == 0) {
1287 // Exif section is in little-endian order
1288 bBigEndian = FALSE;
1289 } else {
1290 if(memcmp(pbProfile, msb_first, sizeof(msb_first)) == 0) {
1291 // Exif section is in big-endian order
1292 bBigEndian = TRUE;
1293 } else {
1294 // Invalid Exif alignment marker
1295 return FALSE;
1296 }
1297 }
1298
1299 // this is the offset to the first IFD (Image File Directory)
1300 DWORD dwFirstOffset = ReadUint32(bBigEndian, pbProfile + 4);
1301 if (dwFirstOffset > dwProfileLength) {
1302 // bad Exif data
1303 return FALSE;
1304 }
1305
1306 // process Exif directories, starting with Exif-TIFF IFD
1307 return jpeg_read_exif_dir(dib, pbProfile, dwFirstOffset, dwProfileLength, 0, bBigEndian, TagLib::EXIF_MAIN);
1308 }
1309
1310 /**
1311 Read PSD image resource (Exif profile)
1312 @param dib Input FIBITMAP
1313 @param dataptr Pointer to the resource data
1314 @param datalen Resource length
1315 @return Returns TRUE if successful, FALSE otherwise
1316 */
1317 BOOL
psd_read_exif_profile_raw(FIBITMAP * dib,const BYTE * profile,unsigned length)1318 psd_read_exif_profile_raw(FIBITMAP *dib, const BYTE *profile, unsigned length) {
1319 // marker identifying string for Exif = "Exif\0\0"
1320 // used by JPEG not PSD
1321 BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
1322
1323 if(NULL == profile || length == 0) {
1324 return FALSE;
1325 }
1326
1327 DWORD dwProfileLength = (DWORD)length + sizeof(exif_signature);
1328 BYTE *pbProfile = (BYTE*)malloc(dwProfileLength);
1329 if(NULL == pbProfile) {
1330 // out of memory ...
1331 return FALSE;
1332 }
1333 memcpy(pbProfile, exif_signature, sizeof(exif_signature));
1334 memcpy(pbProfile + sizeof(exif_signature), profile, length);
1335
1336 // create a tag
1337 FITAG *tag = FreeImage_CreateTag();
1338 BOOL bSuccess = FALSE;
1339 if(tag) {
1340 FreeImage_SetTagKey(tag, g_TagLib_ExifRawFieldName);
1341 FreeImage_SetTagLength(tag, dwProfileLength);
1342 FreeImage_SetTagCount(tag, dwProfileLength);
1343 FreeImage_SetTagType(tag, FIDT_BYTE);
1344 FreeImage_SetTagValue(tag, pbProfile);
1345
1346 // store the tag
1347 FreeImage_SetMetadata(FIMD_EXIF_RAW, dib, FreeImage_GetTagKey(tag), tag);
1348
1349 // destroy the tag
1350 FreeImage_DeleteTag(tag);
1351
1352 bSuccess = TRUE;
1353 }
1354 free(pbProfile);
1355
1356 return bSuccess;
1357 }
1358