PageRenderTime 57ms CodeModel.GetById 2ms app.highlight 48ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/Metadata/Exif.cpp

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