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