1 /*--------------------------------------------------------------------------
2 This file contains subroutines for use by Jpegtopnm to handle the
3 EXIF header.
4
5 The code is adapted from the program Jhead by Matthaias Wandel
6 December 1999 - August 2000, and contributed to the public domain.
7 Bryan Henderson adapted it to Netpbm in September 2001. Bryan
8 added more of Wandel's code, from Jhead 1.9 dated December 2002 in
9 January 2003.
10
11 An EXIF header is a JFIF APP1 marker. It is generated by some
12 digital cameras and contains information about the circumstances of
13 the creation of the image (camera settings, etc.).
14
15 The EXIF header uses the TIFF format, only it contains only tag
16 values and no actual image.
17
18 Note that the image format called EXIF is simply JFIF with an EXIF
19 header, i.e. a subformat of JFIF.
20
21 See the EXIF specs at http://exif.org (2001.09.01).
22
23 --------------------------------------------------------------------------*/
24 #include "pm_config.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <math.h>
28 #include <string.h>
29 #include <time.h>
30 #include <errno.h>
31 #include <limits.h>
32 #include <ctype.h>
33
34 #if MSVCRT
35 #include <sys/utime.h>
36 #else
37 #include <utime.h>
38 #include <sys/types.h>
39 #include <unistd.h>
40 #include <errno.h>
41 #endif
42
43 #include "pm_c_util.h"
44 #include "pm.h"
45 #include "nstring.h"
46
47 #include "exif.h"
48
49 static const unsigned char * DirWithThumbnailPtrs;
50 static double FocalplaneXRes;
51 bool HaveXRes;
52 static double FocalplaneUnits;
53 static int ExifImageWidth;
54
55 typedef struct {
56 unsigned short Tag;
57 const char * Desc;
58 } TagTable;
59
60
61
62 /* Describes format descriptor */
63 static int const bytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
64 #define NUM_FORMATS 12
65
66 #define FMT_BYTE 1
67 #define FMT_STRING 2
68 #define FMT_USHORT 3
69 #define FMT_ULONG 4
70 #define FMT_URATIONAL 5
71 #define FMT_SBYTE 6
72 #define FMT_UNDEFINED 7
73 #define FMT_SSHORT 8
74 #define FMT_SLONG 9
75 #define FMT_SRATIONAL 10
76 #define FMT_SINGLE 11
77 #define FMT_DOUBLE 12
78
79 /* Describes tag values */
80
81 #define TAG_EXIF_OFFSET 0x8769
82 #define TAG_INTEROP_OFFSET 0xa005
83
84 #define TAG_MAKE 0x010F
85 #define TAG_MODEL 0x0110
86
87 #define TAG_ORIENTATION 0x0112
88
89 #define TAG_XRESOLUTION 0x011A
90 #define TAG_YRESOLUTION 0x011B
91
92 #define TAG_EXPOSURETIME 0x829A
93 #define TAG_FNUMBER 0x829D
94
95 #define TAG_SHUTTERSPEED 0x9201
96 #define TAG_APERTURE 0x9202
97 #define TAG_MAXAPERTURE 0x9205
98 #define TAG_FOCALLENGTH 0x920A
99
100 #define TAG_DATETIME_ORIGINAL 0x9003
101 #define TAG_USERCOMMENT 0x9286
102
103 #define TAG_SUBJECT_DISTANCE 0x9206
104 #define TAG_FLASH 0x9209
105
106 #define TAG_FOCALPLANEXRES 0xa20E
107 #define TAG_FOCALPLANEUNITS 0xa210
108 #define TAG_EXIF_IMAGEWIDTH 0xA002
109 #define TAG_EXIF_IMAGELENGTH 0xA003
110
111 /* the following is added 05-jan-2001 vcs */
112 #define TAG_EXPOSURE_BIAS 0x9204
113 #define TAG_WHITEBALANCE 0x9208
114 #define TAG_METERING_MODE 0x9207
115 #define TAG_EXPOSURE_PROGRAM 0x8822
116 #define TAG_ISO_EQUIVALENT 0x8827
117 #define TAG_COMPRESSION_LEVEL 0x9102
118
119 #define TAG_THUMBNAIL_OFFSET 0x0201
120 #define TAG_THUMBNAIL_LENGTH 0x0202
121
122 static TagTable const tagTable[] = {
123 { 0x100, "ImageWidth"},
124 { 0x101, "ImageLength"},
125 { 0x102, "BitsPerSample"},
126 { 0x103, "Compression"},
127 { 0x106, "PhotometricInterpretation"},
128 { 0x10A, "FillOrder"},
129 { 0x10D, "DocumentName"},
130 { 0x10E, "ImageDescription"},
131 { 0x10F, "Make"},
132 { 0x110, "Model"},
133 { 0x111, "StripOffsets"},
134 { 0x112, "Orientation"},
135 { 0x115, "SamplesPerPixel"},
136 { 0x116, "RowsPerStrip"},
137 { 0x117, "StripByteCounts"},
138 { 0x11A, "XResolution"},
139 { 0x11B, "YResolution"},
140 { 0x11C, "PlanarConfiguration"},
141 { 0x128, "ResolutionUnit"},
142 { 0x12D, "TransferFunction"},
143 { 0x131, "Software"},
144 { 0x132, "DateTime"},
145 { 0x13B, "Artist"},
146 { 0x13E, "WhitePoint"},
147 { 0x13F, "PrimaryChromaticities"},
148 { 0x156, "TransferRange"},
149 { 0x200, "JPEGProc"},
150 { 0x201, "ThumbnailOffset"},
151 { 0x202, "ThumbnailLength"},
152 { 0x211, "YCbCrCoefficients"},
153 { 0x212, "YCbCrSubSampling"},
154 { 0x213, "YCbCrPositioning"},
155 { 0x214, "ReferenceBlackWhite"},
156 { 0x828D, "CFARepeatPatternDim"},
157 { 0x828E, "CFAPattern"},
158 { 0x828F, "BatteryLevel"},
159 { 0x8298, "Copyright"},
160 { 0x829A, "ExposureTime"},
161 { 0x829D, "FNumber"},
162 { 0x83BB, "IPTC/NAA"},
163 { 0x8769, "ExifOffset"},
164 { 0x8773, "InterColorProfile"},
165 { 0x8822, "ExposureProgram"},
166 { 0x8824, "SpectralSensitivity"},
167 { 0x8825, "GPSInfo"},
168 { 0x8827, "ISOSpeedRatings"},
169 { 0x8828, "OECF"},
170 { 0x9000, "ExifVersion"},
171 { 0x9003, "DateTimeOriginal"},
172 { 0x9004, "DateTimeDigitized"},
173 { 0x9101, "ComponentsConfiguration"},
174 { 0x9102, "CompressedBitsPerPixel"},
175 { 0x9201, "ShutterSpeedValue"},
176 { 0x9202, "ApertureValue"},
177 { 0x9203, "BrightnessValue"},
178 { 0x9204, "ExposureBiasValue"},
179 { 0x9205, "MaxApertureValue"},
180 { 0x9206, "SubjectDistance"},
181 { 0x9207, "MeteringMode"},
182 { 0x9208, "LightSource"},
183 { 0x9209, "Flash"},
184 { 0x920A, "FocalLength"},
185 { 0x927C, "MakerNote"},
186 { 0x9286, "UserComment"},
187 { 0x9290, "SubSecTime"},
188 { 0x9291, "SubSecTimeOriginal"},
189 { 0x9292, "SubSecTimeDigitized"},
190 { 0xA000, "FlashPixVersion"},
191 { 0xA001, "ColorSpace"},
192 { 0xA002, "ExifImageWidth"},
193 { 0xA003, "ExifImageLength"},
194 { 0xA005, "InteroperabilityOffset"},
195 { 0xA20B, "FlashEnergy"}, /* 0x920B in TIFF/EP */
196 { 0xA20C, "SpatialFrequencyResponse"}, /* 0x920C - - */
197 { 0xA20E, "FocalPlaneXResolution"}, /* 0x920E - - */
198 { 0xA20F, "FocalPlaneYResolution"}, /* 0x920F - - */
199 { 0xA210, "FocalPlaneResolutionUnit"}, /* 0x9210 - - */
200 { 0xA214, "SubjectLocation"}, /* 0x9214 - - */
201 { 0xA215, "ExposureIndex"}, /* 0x9215 - - */
202 { 0xA217, "SensingMethod"}, /* 0x9217 - - */
203 { 0xA300, "FileSource"},
204 { 0xA301, "SceneType"},
205 { 0, NULL}
206 } ;
207
208
209
210 typedef enum { NORMAL, MOTOROLA } ByteOrder;
211
212
213
214 static uint16_t
get16u(const void * const data,ByteOrder const byteOrder)215 get16u(const void * const data,
216 ByteOrder const byteOrder) {
217 /*--------------------------------------------------------------------------
218 Convert a 16 bit unsigned value from file's native byte order
219 --------------------------------------------------------------------------*/
220 if (byteOrder == MOTOROLA){
221 return (((const unsigned char *)data)[0] << 8) |
222 ((const unsigned char *)data)[1];
223 }else{
224 return (((const unsigned char *)data)[1] << 8) |
225 ((const unsigned char *)data)[0];
226 }
227 }
228
229
230
231 static int32_t
get32s(const void * const data,ByteOrder const byteOrder)232 get32s(const void * const data,
233 ByteOrder const byteOrder) {
234 /*--------------------------------------------------------------------------
235 Convert a 32 bit signed value from file's native byte order
236 --------------------------------------------------------------------------*/
237 if (byteOrder == MOTOROLA){
238 return
239 (((const char *)data)[0] << 24) |
240 (((const unsigned char *)data)[1] << 16) |
241 (((const unsigned char *)data)[2] << 8 ) |
242 (((const unsigned char *)data)[3] << 0 );
243 } else {
244 return
245 (((const char *)data)[3] << 24) |
246 (((const unsigned char *)data)[2] << 16) |
247 (((const unsigned char *)data)[1] << 8 ) |
248 (((const unsigned char *)data)[0] << 0 );
249 }
250 }
251
252
253
254 static uint32_t
get32u(const void * const data,ByteOrder const byteOrder)255 get32u(const void * const data,
256 ByteOrder const byteOrder) {
257 /*--------------------------------------------------------------------------
258 Convert a 32 bit unsigned value from file's native byte order
259 --------------------------------------------------------------------------*/
260 return (uint32_t)get32s(data, byteOrder) & 0xffffffff;
261 }
262
263
264
265 static void
printFormatNumber(FILE * const fileP,const void * const ValuePtr,int const Format,int const ByteCount,ByteOrder const byteOrder)266 printFormatNumber(FILE * const fileP,
267 const void * const ValuePtr,
268 int const Format,
269 int const ByteCount,
270 ByteOrder const byteOrder) {
271 /*--------------------------------------------------------------------------
272 Display a number as one of its many formats
273 --------------------------------------------------------------------------*/
274 switch(Format){
275 case FMT_SBYTE:
276 case FMT_BYTE:
277 fprintf(fileP, "%02x\n", *(unsigned char *)ValuePtr);
278 break;
279 case FMT_USHORT:
280 fprintf(fileP, "%d\n",get16u(ValuePtr, byteOrder));
281 break;
282 case FMT_ULONG:
283 case FMT_SLONG:
284 fprintf(fileP, "%d\n",get32s(ValuePtr, byteOrder));
285 break;
286 case FMT_SSHORT:
287 fprintf(fileP, "%hd\n",(signed short)get16u(ValuePtr, byteOrder));
288 break;
289 case FMT_URATIONAL:
290 case FMT_SRATIONAL:
291 fprintf(fileP, "%d/%d\n",get32s(ValuePtr, byteOrder),
292 get32s(4+(char *)ValuePtr, byteOrder));
293 break;
294 case FMT_SINGLE:
295 fprintf(fileP, "%f\n",(double)*(float *)ValuePtr);
296 break;
297 case FMT_DOUBLE:
298 fprintf(fileP, "%f\n",*(double *)ValuePtr);
299 break;
300 default:
301 fprintf(fileP, "Unknown format %d:", Format);
302 {
303 unsigned int a;
304 for (a = 0; a < ByteCount && a < 16; ++a)
305 printf("%02x", ((unsigned char *)ValuePtr)[a]);
306 }
307 fprintf(fileP, "\n");
308 }
309 }
310
311
312
313 static double
convertAnyFormat(const void * const ValuePtr,int const Format,ByteOrder const byteOrder)314 convertAnyFormat(const void * const ValuePtr,
315 int const Format,
316 ByteOrder const byteOrder) {
317 /*--------------------------------------------------------------------------
318 Evaluate number, be it int, rational, or float from directory.
319 --------------------------------------------------------------------------*/
320 double Value;
321 Value = 0;
322
323 switch(Format){
324 case FMT_SBYTE:
325 Value = *(signed char *)ValuePtr;
326 break;
327 case FMT_BYTE:
328 Value = *(unsigned char *)ValuePtr;
329 break;
330 case FMT_USHORT:
331 Value = get16u(ValuePtr, byteOrder);
332 break;
333 case FMT_ULONG:
334 Value = get32u(ValuePtr, byteOrder);
335 break;
336 case FMT_URATIONAL:
337 case FMT_SRATIONAL: {
338 int num, den;
339 num = get32s(ValuePtr, byteOrder);
340 den = get32s(4+(char *)ValuePtr, byteOrder);
341 Value = den == 0 ? 0 : (double)(num/den);
342 } break;
343 case FMT_SSHORT:
344 Value = (signed short)get16u(ValuePtr, byteOrder);
345 break;
346 case FMT_SLONG:
347 Value = get32s(ValuePtr, byteOrder);
348 break;
349
350 /* Not sure if this is correct (never seen float used in Exif format) */
351 case FMT_SINGLE:
352 Value = (double)*(float *)ValuePtr;
353 break;
354 case FMT_DOUBLE:
355 Value = *(double *)ValuePtr;
356 break;
357 }
358 return Value;
359 }
360
361
362
363 static void
traceTag(int const tag,int const format,const unsigned char * const valuePtr,unsigned int const byteCount,ByteOrder const byteOrder)364 traceTag(int const tag,
365 int const format,
366 const unsigned char * const valuePtr,
367 unsigned int const byteCount,
368 ByteOrder const byteOrder) {
369
370 /* Show tag name */
371 unsigned int a;
372 bool found;
373 for (a = 0, found = false; !found; ++a){
374 if (tagTable[a].Tag == 0){
375 fprintf(stderr, " Unknown Tag %04x Value = ", tag);
376 found = true;
377 }
378 if (tagTable[a].Tag == tag){
379 fprintf(stderr, " %s = ",tagTable[a].Desc);
380 found = true;
381 }
382 }
383
384 /* Show tag value. */
385 switch(format){
386
387 case FMT_UNDEFINED:
388 /* Undefined is typically an ascii string. */
389
390 case FMT_STRING: {
391 /* String arrays printed without function call
392 (different from int arrays)
393 */
394 bool noPrint;
395 printf("\"");
396 for (a = 0, noPrint = false; a < byteCount; ++a){
397 if (ISPRINT((valuePtr)[a])){
398 fprintf(stderr, "%c", valuePtr[a]);
399 noPrint = false;
400 } else {
401 /* Avoiding indicating too many unprintable characters of
402 proprietary bits of binary information this program may not
403 know how to parse.
404 */
405 if (!noPrint){
406 fprintf(stderr, "?");
407 noPrint = true;
408 }
409 }
410 }
411 fprintf(stderr, "\"\n");
412 } break;
413
414 default:
415 /* Handle arrays of numbers later (will there ever be?)*/
416 printFormatNumber(stderr, valuePtr, format, byteCount, byteOrder);
417 }
418 }
419
420
421
422 /* Forward declaration for recursion */
423
424 static void
425 processExifDir(const unsigned char * const ExifData,
426 unsigned int const ExifLength,
427 unsigned int const DirOffset,
428 exif_ImageInfo * const imageInfoP,
429 ByteOrder const byteOrder,
430 bool const wantTagTrace,
431 const unsigned char ** const LastExifRefdP);
432
433
434 static void
processDirEntry(const unsigned char * const dirEntry,const unsigned char * const exifData,unsigned int const exifLength,ByteOrder const byteOrder,bool const wantTagTrace,exif_ImageInfo * const imageInfoP,unsigned int * const thumbnailOffsetP,unsigned int * const thumbnailSizeP,bool * const haveThumbnailP,const unsigned char ** const lastExifRefdP)435 processDirEntry(const unsigned char * const dirEntry,
436 const unsigned char * const exifData,
437 unsigned int const exifLength,
438 ByteOrder const byteOrder,
439 bool const wantTagTrace,
440 exif_ImageInfo * const imageInfoP,
441 unsigned int * const thumbnailOffsetP,
442 unsigned int * const thumbnailSizeP,
443 bool * const haveThumbnailP,
444 const unsigned char ** const lastExifRefdP) {
445
446 int const tag = get16u(&dirEntry[0], byteOrder);
447 int const format = get16u(&dirEntry[2], byteOrder);
448 int const components = get32u(&dirEntry[4], byteOrder);
449
450 const unsigned char * valuePtr;
451 /* This actually can point to a variety of things; it must be cast to
452 other types when used. But we use it as a byte-by-byte cursor, so
453 we declare it as a pointer to a generic byte here.
454 */
455 unsigned int byteCount;
456
457 if ((format-1) >= NUM_FORMATS) {
458 /* (-1) catches illegal zero case as unsigned underflows
459 to positive large.
460 */
461 pm_message("Illegal number format %d for tag %04x", format, tag);
462 return;
463 }
464
465 byteCount = components * bytesPerFormat[format];
466
467 if (byteCount > 4){
468 unsigned const offsetVal = get32u(&dirEntry[8], byteOrder);
469 /* If its bigger than 4 bytes, the dir entry contains an offset.*/
470 if (offsetVal + byteCount > exifLength){
471 /* Bogus pointer offset and / or bytecount value */
472 pm_message("Illegal pointer offset value in EXIF "
473 "for tag %04x. "
474 "Offset %d bytes %d ExifLen %d\n",
475 tag, offsetVal, byteCount, exifLength);
476 return;
477 }
478 valuePtr = &exifData[offsetVal];
479 } else {
480 /* 4 bytes or less and value is in the dir entry itself */
481 valuePtr = &dirEntry[8];
482 }
483
484 if (*lastExifRefdP < valuePtr + byteCount){
485 /* Keep track of last byte in the exif header that was actually
486 referenced. That way, we know where the discardable thumbnail data
487 begins.
488 */
489 *lastExifRefdP = valuePtr + byteCount;
490 }
491
492 if (wantTagTrace)
493 traceTag(tag, format, valuePtr, byteCount, byteOrder);
494
495 *haveThumbnailP = (tag == TAG_THUMBNAIL_OFFSET);
496
497 /* Extract useful components of tag */
498 switch (tag){
499
500 case TAG_MAKE:
501 STRSCPY(imageInfoP->CameraMake, (const char*)valuePtr);
502 break;
503
504 case TAG_MODEL:
505 STRSCPY(imageInfoP->CameraModel, (const char*)valuePtr);
506 break;
507
508 case TAG_XRESOLUTION:
509 imageInfoP->XResolution =
510 convertAnyFormat(valuePtr, format, byteOrder);
511 break;
512
513 case TAG_YRESOLUTION:
514 imageInfoP->YResolution =
515 convertAnyFormat(valuePtr, format, byteOrder);
516 break;
517
518 case TAG_DATETIME_ORIGINAL:
519 STRSCPY(imageInfoP->DateTime, (const char*)valuePtr);
520 imageInfoP->DatePointer = (const char*)valuePtr;
521 break;
522
523 case TAG_USERCOMMENT: {
524 /* Olympus has this padded with trailing spaces. We stop the copy
525 where those start.
526 */
527 const char * const value = (const char *)valuePtr;
528
529 unsigned int cursor;
530 unsigned int outCursor;
531 unsigned int end;
532
533 for (end = byteCount; end > 0 && value[end] == ' '; --end);
534
535 /* Skip "ASCII" if it is there */
536 if (end >= 5 && MEMEQ(value, "ASCII", 5))
537 cursor = 5;
538 else
539 cursor = 0;
540
541 /* Skip consecutive blanks and NULs */
542
543 for (;
544 cursor < byteCount &&
545 (value[cursor] == '\0' || value[cursor] == ' ');
546 ++cursor);
547
548 /* Copy the rest as the comment */
549
550 for (outCursor = 0;
551 cursor < end && outCursor < MAX_COMMENT-1;
552 ++cursor)
553 imageInfoP->Comments[outCursor++] = value[cursor];
554
555 imageInfoP->Comments[outCursor++] = '\0';
556 } break;
557
558 case TAG_FNUMBER:
559 /* Simplest way of expressing aperture, so I trust it the most.
560 (overwrite previously computd value if there is one)
561 */
562 imageInfoP->ApertureFNumber =
563 (float)convertAnyFormat(valuePtr, format, byteOrder);
564 break;
565
566 case TAG_APERTURE:
567 case TAG_MAXAPERTURE:
568 /* More relevant info always comes earlier, so only use this field if
569 we don't have appropriate aperture information yet.
570 */
571 if (imageInfoP->ApertureFNumber == 0){
572 imageInfoP->ApertureFNumber = (float)
573 exp(convertAnyFormat(valuePtr, format, byteOrder)
574 * log(2) * 0.5);
575 }
576 break;
577
578 case TAG_FOCALLENGTH:
579 /* Nice digital cameras actually save the focal length
580 as a function of how farthey are zoomed in.
581 */
582
583 imageInfoP->FocalLength =
584 (float)convertAnyFormat(valuePtr, format, byteOrder);
585 break;
586
587 case TAG_SUBJECT_DISTANCE:
588 /* Inidcates the distacne the autofocus camera is focused to.
589 Tends to be less accurate as distance increases.
590 */
591 imageInfoP->Distance =
592 (float)convertAnyFormat(valuePtr, format, byteOrder);
593 break;
594
595 case TAG_EXPOSURETIME:
596 /* Simplest way of expressing exposure time, so I
597 trust it most. (overwrite previously computd value
598 if there is one)
599 */
600 imageInfoP->ExposureTime =
601 (float)convertAnyFormat(valuePtr, format, byteOrder);
602 break;
603
604 case TAG_SHUTTERSPEED:
605 /* More complicated way of expressing exposure time,
606 so only use this value if we don't already have it
607 from somewhere else.
608 */
609 if (imageInfoP->ExposureTime == 0){
610 imageInfoP->ExposureTime = (float)
611 (1/exp(convertAnyFormat(valuePtr, format, byteOrder)
612 * log(2)));
613 }
614 break;
615
616 case TAG_FLASH:
617 if ((int)convertAnyFormat(valuePtr, format, byteOrder) & 0x7){
618 imageInfoP->FlashUsed = TRUE;
619 }else{
620 imageInfoP->FlashUsed = FALSE;
621 }
622 break;
623
624 case TAG_ORIENTATION:
625 imageInfoP->Orientation =
626 (int)convertAnyFormat(valuePtr, format, byteOrder);
627 if (imageInfoP->Orientation < 1 ||
628 imageInfoP->Orientation > 8){
629 pm_message("Undefined rotation value %d",
630 imageInfoP->Orientation);
631 imageInfoP->Orientation = 0;
632 }
633 break;
634
635 case TAG_EXIF_IMAGELENGTH:
636 case TAG_EXIF_IMAGEWIDTH:
637 /* Use largest of height and width to deal with images
638 that have been rotated to portrait format.
639 */
640 ExifImageWidth =
641 MIN(ExifImageWidth,
642 (int)convertAnyFormat(valuePtr, format, byteOrder));
643 break;
644
645 case TAG_FOCALPLANEXRES:
646 HaveXRes = TRUE;
647 FocalplaneXRes = convertAnyFormat(valuePtr, format, byteOrder);
648 break;
649
650 case TAG_FOCALPLANEUNITS:
651 switch((int)convertAnyFormat(valuePtr, format, byteOrder)){
652 case 1: FocalplaneUnits = 25.4; break; /* 1 inch */
653 case 2:
654 /* According to the information I was using, 2
655 means meters. But looking at the Cannon
656 powershot's files, inches is the only
657 sensible value.
658 */
659 FocalplaneUnits = 25.4;
660 break;
661
662 case 3: FocalplaneUnits = 10; break; /* 1 centimeter*/
663 case 4: FocalplaneUnits = 1; break; /* 1 millimeter*/
664 case 5: FocalplaneUnits = .001; break; /* 1 micrometer*/
665 }
666 break;
667
668 /* Remaining cases contributed by: Volker C. Schoech
669 (schoech@gmx.de)
670 */
671
672 case TAG_EXPOSURE_BIAS:
673 imageInfoP->ExposureBias =
674 (float) convertAnyFormat(valuePtr, format, byteOrder);
675 break;
676
677 case TAG_WHITEBALANCE:
678 imageInfoP->Whitebalance =
679 (int)convertAnyFormat(valuePtr, format, byteOrder);
680 break;
681
682 case TAG_METERING_MODE:
683 imageInfoP->MeteringMode =
684 (int)convertAnyFormat(valuePtr, format, byteOrder);
685 break;
686
687 case TAG_EXPOSURE_PROGRAM:
688 imageInfoP->ExposureProgram =
689 (int)convertAnyFormat(valuePtr, format, byteOrder);
690 break;
691
692 case TAG_ISO_EQUIVALENT:
693 imageInfoP->ISOequivalent =
694 (int)convertAnyFormat(valuePtr, format, byteOrder);
695 if ( imageInfoP->ISOequivalent < 50 )
696 imageInfoP->ISOequivalent *= 200;
697 break;
698
699 case TAG_COMPRESSION_LEVEL:
700 imageInfoP->CompressionLevel =
701 (int)convertAnyFormat(valuePtr, format, byteOrder);
702 break;
703
704 case TAG_THUMBNAIL_OFFSET:
705 *thumbnailOffsetP = (unsigned int)
706 convertAnyFormat(valuePtr, format, byteOrder);
707 break;
708
709 case TAG_THUMBNAIL_LENGTH:
710 *thumbnailSizeP = (unsigned int)
711 convertAnyFormat(valuePtr, format, byteOrder);
712 break;
713
714 case TAG_EXIF_OFFSET:
715 case TAG_INTEROP_OFFSET: {
716 unsigned int const subdirOffset = get32u(valuePtr, byteOrder);
717 if (subdirOffset >= exifLength)
718 pm_message("Illegal exif or interop offset "
719 "directory link. Offset is %u, "
720 "but Exif data is only %u bytes.",
721 subdirOffset, exifLength);
722 else
723 processExifDir(exifData, exifLength, subdirOffset,
724 imageInfoP, byteOrder, wantTagTrace,
725 lastExifRefdP);
726 } break;
727 }
728 }
729
730
731
732 static void
processExifDir(const unsigned char * const exifData,unsigned int const exifLength,unsigned int const dirOffset,exif_ImageInfo * const imageInfoP,ByteOrder const byteOrder,bool const wantTagTrace,const unsigned char ** const lastExifRefdP)733 processExifDir(const unsigned char * const exifData,
734 unsigned int const exifLength,
735 unsigned int const dirOffset,
736 exif_ImageInfo * const imageInfoP,
737 ByteOrder const byteOrder,
738 bool const wantTagTrace,
739 const unsigned char ** const lastExifRefdP) {
740 /*--------------------------------------------------------------------------
741 Process one of the nested EXIF directories.
742 --------------------------------------------------------------------------*/
743 const unsigned char * const dirStart = exifData + dirOffset;
744 unsigned int const numDirEntries = get16u(&dirStart[0], byteOrder);
745 unsigned int de;
746 bool haveThumbnail;
747 unsigned int thumbnailOffset;
748 unsigned int thumbnailSize;
749
750 #define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry))
751
752 {
753 const unsigned char * const dirEnd =
754 DIR_ENTRY_ADDR(dirStart, numDirEntries);
755 if (dirEnd + 4 > (exifData + exifLength)){
756 if (dirEnd + 2 == exifData + exifLength ||
757 dirEnd == exifData + exifLength){
758 /* Version 1.3 of jhead would truncate a bit too much.
759 This also caught later on as well.
760 */
761 }else{
762 /* Note: Files that had thumbnails trimmed with jhead
763 1.3 or earlier might trigger this.
764 */
765 pm_message("Illegal directory entry size");
766 return;
767 }
768 }
769 *lastExifRefdP = MAX(*lastExifRefdP, dirEnd);
770 }
771
772 if (wantTagTrace)
773 pm_message("Directory with %d entries", numDirEntries);
774
775 haveThumbnail = false; /* initial value */
776 thumbnailOffset = 0; /* initial value */
777 thumbnailSize = 0; /* initial value */
778
779 for (de = 0; de < numDirEntries; ++de)
780 processDirEntry(DIR_ENTRY_ADDR(dirStart, de), exifData, exifLength,
781 byteOrder, wantTagTrace, imageInfoP,
782 &thumbnailOffset, &thumbnailSize, &haveThumbnail,
783 lastExifRefdP);
784
785 if (haveThumbnail)
786 DirWithThumbnailPtrs = dirStart;
787
788 {
789 /* In addition to linking to subdirectories via exif tags,
790 there's also a potential link to another directory at the end
791 of each directory. This has got to be the result of a
792 committee!
793 */
794 if (DIR_ENTRY_ADDR(dirStart, numDirEntries) + 4 <=
795 exifData + exifLength){
796 unsigned int const subdirOffset =
797 get32u(dirStart + 2 + 12*numDirEntries, byteOrder);
798 if (subdirOffset){
799 const unsigned char * const subdirStart =
800 exifData + subdirOffset;
801 if (subdirStart > exifData + exifLength){
802 if (subdirStart < exifData + exifLength + 20){
803 /* Jhead 1.3 or earlier would crop the whole directory!
804 As Jhead produces this form of format incorrectness,
805 I'll just let it pass silently.
806 */
807 if (wantTagTrace)
808 printf("Thumbnail removed with "
809 "Jhead 1.3 or earlier\n");
810 }else{
811 pm_message("Illegal subdirectory link");
812 }
813 }else{
814 if (subdirOffset <= exifLength)
815 processExifDir(exifData, exifLength, subdirOffset,
816 imageInfoP, byteOrder, wantTagTrace,
817 lastExifRefdP);
818 }
819 }
820 }else{
821 /* The exif header ends before the last next directory pointer. */
822 }
823 }
824
825 if (thumbnailSize && thumbnailOffset){
826 if (thumbnailSize + thumbnailOffset <= exifLength){
827 /* The thumbnail pointer appears to be valid. Store it. */
828 imageInfoP->ThumbnailPointer = exifData + thumbnailOffset;
829 imageInfoP->ThumbnailSize = thumbnailSize;
830
831 if (wantTagTrace){
832 fprintf(stderr, "Thumbnail size: %u bytes\n", thumbnailSize);
833 }
834 }
835 }
836 }
837
838
839
840 void
exif_parse(const unsigned char * const exifData,unsigned int const length,exif_ImageInfo * const imageInfoP,bool const wantTagTrace,const char ** const errorP)841 exif_parse(const unsigned char * const exifData,
842 unsigned int const length,
843 exif_ImageInfo * const imageInfoP,
844 bool const wantTagTrace,
845 const char ** const errorP) {
846 /*--------------------------------------------------------------------------
847 Interpret an EXIF APP1 marker
848
849 'exifData' is the actual Exif data; it does not include the
850 "Exif" identifier and length field that often prefix Exif data.
851
852 'length' is the length of the Exif section.
853 --------------------------------------------------------------------------*/
854 ByteOrder byteOrder;
855 int FirstOffset;
856 const unsigned char * lastExifRefd;
857
858 *errorP = NULL; /* initial assumption */
859
860 if (wantTagTrace)
861 fprintf(stderr, "Exif header %d bytes long\n",length);
862
863 if (MEMEQ(exifData + 0, "II" , 2)) {
864 if (wantTagTrace)
865 fprintf(stderr, "Exif header in Intel order\n");
866 byteOrder = NORMAL;
867 } else {
868 if (MEMEQ(exifData + 0, "MM", 2)) {
869 if (wantTagTrace)
870 fprintf(stderr, "Exif header in Motorola order\n");
871 byteOrder = MOTOROLA;
872 } else {
873 pm_asprintf(errorP, "Invalid alignment marker in Exif "
874 "data. First two bytes are '%c%c' (0x%02x%02x) "
875 "instead of 'II' or 'MM'.",
876 exifData[0], exifData[1], exifData[0], exifData[1]);
877 }
878 }
879 if (!*errorP) {
880 unsigned short const start = get16u(exifData + 2, byteOrder);
881 /* Check the next value for correctness. */
882 if (start != 0x002a){
883 pm_asprintf(errorP, "Invalid Exif header start. "
884 "two bytes after the alignment marker "
885 "should be 0x002a, but is 0x%04x",
886 start);
887 }
888 }
889 if (!*errorP) {
890 FirstOffset = get32u(exifData + 4, byteOrder);
891 if (FirstOffset < 8 || FirstOffset > 16){
892 /* I used to ensure this was set to 8 (website I used
893 indicated its 8) but PENTAX Optio 230 has it set
894 differently, and uses it as offset. (Sept 11 2002)
895 */
896 pm_message("Suspicious offset of first IFD value in Exif header");
897 }
898
899 imageInfoP->Comments[0] = '\0'; /* Initial value - null string */
900
901 HaveXRes = FALSE; /* Initial assumption */
902 FocalplaneUnits = 0;
903 ExifImageWidth = 0;
904
905 lastExifRefd = exifData;
906 DirWithThumbnailPtrs = NULL;
907
908 processExifDir(exifData, length, FirstOffset,
909 imageInfoP, byteOrder, wantTagTrace, &lastExifRefd);
910
911 /* Compute the CCD width, in millimeters. */
912 if (HaveXRes){
913 imageInfoP->HaveCCDWidth = 1;
914 imageInfoP->CCDWidth =
915 (float)(ExifImageWidth * FocalplaneUnits / FocalplaneXRes);
916 } else
917 imageInfoP->HaveCCDWidth = 0;
918
919 if (wantTagTrace){
920 fprintf(stderr,
921 "Non-settings part of Exif header: %lu bytes\n",
922 (unsigned long)(exifData + length - lastExifRefd));
923 }
924 }
925 }
926
927
928
929 void
exif_showImageInfo(const exif_ImageInfo * const imageInfoP,FILE * const fileP)930 exif_showImageInfo(const exif_ImageInfo * const imageInfoP,
931 FILE * const fileP) {
932 /*--------------------------------------------------------------------------
933 Show the collected image info, displaying camera F-stop and shutter
934 speed in a consistent and legible fashion.
935 --------------------------------------------------------------------------*/
936 if (imageInfoP->CameraMake[0]) {
937 fprintf(fileP, "Camera make : %s\n", imageInfoP->CameraMake);
938 fprintf(fileP, "Camera model : %s\n", imageInfoP->CameraModel);
939 }
940 if (imageInfoP->DateTime[0])
941 fprintf(fileP, "Date/Time : %s\n", imageInfoP->DateTime);
942
943 fprintf(fileP, "Resolution : %f x %f\n",
944 imageInfoP->XResolution, imageInfoP->YResolution);
945
946 if (imageInfoP->Orientation > 1) {
947
948 /* Only print orientation if one was supplied, and if its not
949 1 (normal orientation)
950
951 1 - The 0th row is at the visual top of the image
952 and the 0th column is the visual left-hand side.
953 2 - The 0th row is at the visual top of the image
954 and the 0th column is the visual right-hand side.
955 3 - The 0th row is at the visual bottom of the image
956 and the 0th column is the visual right-hand side.
957 4 - The 0th row is at the visual bottom of the image
958 and the 0th column is the visual left-hand side.
959 5 - The 0th row is the visual left-hand side of of the image
960 and the 0th column is the visual top.
961 6 - The 0th row is the visual right-hand side of of the image
962 and the 0th column is the visual top.
963 7 - The 0th row is the visual right-hand side of of the image
964 and the 0th column is the visual bottom.
965 8 - The 0th row is the visual left-hand side of of the image
966 and the 0th column is the visual bottom.
967
968 Note: The descriptions here are the same as the name of the
969 command line option to pass to jpegtran to right the image
970 */
971 static const char * OrientTab[9] = {
972 "Undefined",
973 "Normal", /* 1 */
974 "flip horizontal", /* left right reversed mirror */
975 "rotate 180", /* 3 */
976 "flip vertical", /* upside down mirror */
977 "transpose", /* Flipped about top-left <--> bottom-right axis.*/
978 "rotate 90", /* rotate 90 cw to right it. */
979 "transverse", /* flipped about top-right <--> bottom-left axis */
980 "rotate 270", /* rotate 270 to right it. */
981 };
982
983 fprintf(fileP, "Orientation : %s\n",
984 OrientTab[imageInfoP->Orientation]);
985 }
986
987 if (imageInfoP->IsColor == 0)
988 fprintf(fileP, "Color/bw : Black and white\n");
989
990 if (imageInfoP->FlashUsed >= 0)
991 fprintf(fileP, "Flash used : %s\n",
992 imageInfoP->FlashUsed ? "Yes" :"No");
993
994 if (imageInfoP->FocalLength) {
995 fprintf(fileP, "Focal length : %4.1fmm",
996 (double)imageInfoP->FocalLength);
997 if (imageInfoP->HaveCCDWidth){
998 fprintf(fileP, " (35mm equivalent: %dmm)",
999 (int)
1000 (imageInfoP->FocalLength/imageInfoP->CCDWidth*36 + 0.5));
1001 }
1002 fprintf(fileP, "\n");
1003 }
1004
1005 if (imageInfoP->HaveCCDWidth)
1006 fprintf(fileP, "CCD width : %2.4fmm\n",
1007 (double)imageInfoP->CCDWidth);
1008
1009 if (imageInfoP->ExposureTime) {
1010 if (imageInfoP->ExposureTime < 0.010){
1011 fprintf(fileP,
1012 "Exposure time: %6.4f s ",
1013 (double)imageInfoP->ExposureTime);
1014 }else{
1015 fprintf(fileP,
1016 "Exposure time: %5.3f s ",
1017 (double)imageInfoP->ExposureTime);
1018 }
1019 if (imageInfoP->ExposureTime <= 0.5){
1020 fprintf(fileP, " (1/%d)",(int)(0.5 + 1/imageInfoP->ExposureTime));
1021 }
1022 fprintf(fileP, "\n");
1023 }
1024 if (imageInfoP->ApertureFNumber){
1025 fprintf(fileP, "Aperture : f/%3.1f\n",
1026 (double)imageInfoP->ApertureFNumber);
1027 }
1028 if (imageInfoP->Distance){
1029 if (imageInfoP->Distance < 0){
1030 fprintf(fileP, "Focus dist. : Infinite\n");
1031 }else{
1032 fprintf(fileP, "Focus dist. :%5.2fm\n",
1033 (double)imageInfoP->Distance);
1034 }
1035 }
1036
1037 if (imageInfoP->ISOequivalent){ /* 05-jan-2001 vcs */
1038 fprintf(fileP, "ISO equiv. : %2d\n",(int)imageInfoP->ISOequivalent);
1039 }
1040 if (imageInfoP->ExposureBias){ /* 05-jan-2001 vcs */
1041 fprintf(fileP, "Exposure bias:%4.2f\n",
1042 (double)imageInfoP->ExposureBias);
1043 }
1044
1045 if (imageInfoP->Whitebalance){ /* 05-jan-2001 vcs */
1046 switch(imageInfoP->Whitebalance) {
1047 case 1:
1048 fprintf(fileP, "Whitebalance : sunny\n");
1049 break;
1050 case 2:
1051 fprintf(fileP, "Whitebalance : fluorescent\n");
1052 break;
1053 case 3:
1054 fprintf(fileP, "Whitebalance : incandescent\n");
1055 break;
1056 default:
1057 fprintf(fileP, "Whitebalance : cloudy\n");
1058 }
1059 }
1060 if (imageInfoP->MeteringMode){ /* 05-jan-2001 vcs */
1061 switch(imageInfoP->MeteringMode) {
1062 case 2:
1063 fprintf(fileP, "Metering Mode: center weight\n");
1064 break;
1065 case 3:
1066 fprintf(fileP, "Metering Mode: spot\n");
1067 break;
1068 case 5:
1069 fprintf(fileP, "Metering Mode: matrix\n");
1070 break;
1071 }
1072 }
1073 if (imageInfoP->ExposureProgram){ /* 05-jan-2001 vcs */
1074 switch(imageInfoP->ExposureProgram) {
1075 case 2:
1076 fprintf(fileP, "Exposure : program (auto)\n");
1077 break;
1078 case 3:
1079 fprintf(fileP, "Exposure : aperture priority (semi-auto)\n");
1080 break;
1081 case 4:
1082 fprintf(fileP, "Exposure : shutter priority (semi-auto)\n");
1083 break;
1084 }
1085 }
1086 if (imageInfoP->CompressionLevel){ /* 05-jan-2001 vcs */
1087 switch(imageInfoP->CompressionLevel) {
1088 case 1:
1089 fprintf(fileP, "Jpeg Quality : basic\n");
1090 break;
1091 case 2:
1092 fprintf(fileP, "Jpeg Quality : normal\n");
1093 break;
1094 case 4:
1095 fprintf(fileP, "Jpeg Quality : fine\n");
1096 break;
1097 }
1098 }
1099
1100 /* Print the comment. Print 'Comment:' for each new line of comment. */
1101 if (imageInfoP->Comments[0]) {
1102 unsigned int a;
1103
1104 fprintf(fileP, "Comment : ");
1105
1106 for (a = 0; a < MAX_COMMENT && imageInfoP->Comments[a]; ++a) {
1107 char const c = imageInfoP->Comments[a];
1108 if (c == '\n'){
1109 /* Do not start a new line if the string ends with a cr */
1110 if (imageInfoP->Comments[a+1] != '\0')
1111 fprintf(fileP, "\nComment : ");
1112 else
1113 fprintf(fileP, "\n");
1114 } else
1115 putc(c, fileP);
1116 }
1117 fprintf(fileP, "\n");
1118 }
1119
1120 fprintf(fileP, "\n");
1121 }
1122
1123
1124