~ubuntu-branches/ubuntu/trusty/freeimage/trusty-proposed

« back to all changes in this revision

Viewing changes to Source/Metadata/Exif.cpp

  • Committer: Package Import Robot
  • Author(s): Scott Howard
  • Date: 2014-01-13 21:57:45 UTC
  • mfrom: (8.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140113215745-3y21c8ro0ih30hfg
Tags: 3.15.4-1
* QA Upload
* New upstream minor release 
  - Includes fix to build on !linux (Closes: #650485)
* Refreshed patches (line endings had to change)
  - Remove document-mode.patch (accepted upstream)
* Lintian fixes: S-V 3.9.5, DM-Upload-Allowed removed
* Remove document-mode.patch (accepted upstream)

Show diffs side-by-side

added added

removed removed

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