]> git.imager.perl.org - imager.git/blob - imexif.c
- clean up Imager::Font documentation:
[imager.git] / imexif.c
1 #include "imexif.h"
2 #include <stdlib.h>
3 #include <float.h>
4
5 /*
6 =head1 NAME
7
8 imexif.c - EXIF support for Imager
9
10 =head1 SYNOPSIS
11
12   if (i_int_decode_exif(im, app1data, app1datasize)) {
13     // exif block seen
14   }
15
16 =head1 DESCRIPTION
17
18 This code provides a basic EXIF data decoder.  It is intended to be
19 called from the JPEG reader code when an APP1 data block is found, and
20 will set tags in the supplied image.
21
22 =cut
23 */
24
25 typedef enum tiff_type_tag {
26   tt_intel = 'I',
27   tt_motorola = 'M'
28 } tiff_type;
29
30 typedef enum {
31   ift_byte = 1,
32   ift_ascii = 2,
33   ift_short = 3,
34   ift_long = 4,
35   ift_rational = 5,
36   ift_sbyte = 6,
37   ift_undefined = 7,
38   ift_sshort = 8,
39   ift_slong = 9,
40   ift_srational = 10,
41   ift_float = 11,
42   ift_double = 12,
43   ift_last = 12 /* keep the same as the highest type code */
44 } ifd_entry_type;
45
46 static int type_sizes[] =
47   {
48     0, /* not used */
49     1, /* byte */
50     1, /* ascii */
51     2, /* short */
52     4, /* long */
53     8, /* rational */
54     1, /* sbyte */
55     1, /* undefined */
56     2, /* sshort */
57     4, /* slong */
58     8, /* srational */
59     4, /* float */
60     8, /* double */
61   };
62
63 typedef struct {
64   int tag;
65   int type;
66   int count;
67   int size;
68   int offset;
69 } ifd_entry;
70
71 typedef struct {
72   int tag;
73   char const *name;
74 } tag_map;
75
76 typedef struct {
77   int tag;
78   char const *name;
79   tag_map const *map;
80   int map_count;
81 } tag_value_map;
82
83 #define PASTE(left, right) PASTE_(left, right)
84 #define PASTE_(left, right) left##right
85 #define QUOTE(value) #value
86
87 #define VALUE_MAP_ENTRY(name) \
88   { \
89     PASTE(tag_, name), \
90     "exif_" QUOTE(name) "_name", \
91     PASTE(name, _values), \
92     ARRAY_COUNT(PASTE(name, _values)) \
93   }
94
95 /* we don't process every tag */
96 #define tag_make 271
97 #define tag_model 272
98 #define tag_orientation 274
99 #define tag_x_resolution 282
100 #define tag_y_resolution 283
101 #define tag_resolution_unit 296
102 #define tag_copyright 33432
103 #define tag_software 305
104 #define tag_artist 315
105 #define tag_date_time 306
106 #define tag_image_description 270
107
108 #define tag_exif_ifd 34665
109 #define tag_gps_ifd 34853
110
111 #define resunit_none 1
112 #define resunit_inch 2
113 #define resunit_centimeter 3
114
115 /* tags from the EXIF ifd */
116 #define tag_exif_version 0x9000
117 #define tag_flashpix_version 0xA000
118 #define tag_color_space 0xA001
119 #define tag_component_configuration 0x9101
120 #define tag_component_bits_per_pixel 0x9102
121 #define tag_pixel_x_dimension 0xA002
122 #define tag_pixel_y_dimension 0xA003
123 #define tag_maker_note 0x927C
124 #define tag_user_comment 0x9286
125 #define tag_related_sound_file 0xA004
126 #define tag_date_time_original 0x9003
127 #define tag_date_time_digitized 0x9004
128 #define tag_sub_sec_time 0x9290
129 #define tag_sub_sec_time_original 0x9291
130 #define tag_sub_sec_time_digitized 0x9292
131 #define tag_image_unique_id 0xA420
132 #define tag_exposure_time 0x829a
133 #define tag_f_number 0x829D
134 #define tag_exposure_program 0x8822
135 #define tag_spectral_sensitivity 0x8824
136 #define tag_iso_speed_rating 0x8827
137 #define tag_oecf 0x8828
138 #define tag_shutter_speed 0x9201
139 #define tag_aperture 0x9202
140 #define tag_brightness 0x9203
141 #define tag_exposure_bias 0x9204
142 #define tag_max_aperture 0x9205
143 #define tag_subject_distance 0x9206
144 #define tag_metering_mode 0x9207
145 #define tag_light_source 0x9208
146 #define tag_flash 0x9209
147 #define tag_focal_length 0x920a
148 #define tag_subject_area 0x9214
149 #define tag_flash_energy 0xA20B
150 #define tag_spatial_frequency_response 0xA20C
151 #define tag_focal_plane_x_resolution 0xA20e
152 #define tag_focal_plane_y_resolution 0xA20F
153 #define tag_focal_plane_resolution_unit 0xA210
154 #define tag_subject_location 0xA214
155 #define tag_exposure_index 0xA215
156 #define tag_sensing_method 0xA217
157 #define tag_file_source 0xA300
158 #define tag_scene_type 0xA301
159 #define tag_cfa_pattern 0xA302
160 #define tag_custom_rendered 0xA401
161 #define tag_exposure_mode 0xA402
162 #define tag_white_balance 0xA403
163 #define tag_digital_zoom_ratio 0xA404
164 #define tag_focal_length_in_35mm_film 0xA405
165 #define tag_scene_capture_type 0xA406
166 #define tag_gain_control 0xA407
167 #define tag_contrast 0xA408
168 #define tag_saturation 0xA409
169 #define tag_sharpness 0xA40A
170 #define tag_device_setting_description 0xA40B
171 #define tag_subject_distance_range 0xA40C
172
173 /* don't use this on pointers */
174 #define ARRAY_COUNT(array) (sizeof(array)/sizeof(*array))
175
176 /* in memory tiff structure */
177 typedef struct {
178   /* the data we use as a tiff */
179   unsigned char *base;
180   size_t size;
181
182   /* intel or motorola byte order */
183   tiff_type type;
184
185   /* initial ifd offset */
186   unsigned long first_ifd_offset;
187   
188   /* size (in entries) and data */
189   int ifd_size; 
190   ifd_entry *ifd;
191   unsigned long next_ifd;
192 } imtiff;
193
194 static int tiff_init(imtiff *tiff, unsigned char *base, size_t length);
195 static int tiff_load_ifd(imtiff *tiff, unsigned long offset);
196 static void tiff_final(imtiff *tiff);
197 static void tiff_clear_ifd(imtiff *tiff);
198 static int tiff_get_bytes(imtiff *tiff, unsigned char *to, size_t offset, 
199                           size_t count);
200 static int tiff_get_tag_double(imtiff *, int index, double *result);
201 static int tiff_get_tag_int(imtiff *, int index, int *result);
202 static unsigned tiff_get16(imtiff *, unsigned long offset);
203 static unsigned tiff_get32(imtiff *, unsigned long offset);
204 static int tiff_get16s(imtiff *, unsigned long offset);
205 static int tiff_get32s(imtiff *, unsigned long offset);
206 static double tiff_get_rat(imtiff *, unsigned long offset);
207 static double tiff_get_rats(imtiff *, unsigned long offset);
208 static void save_ifd0_tags(i_img *im, imtiff *tiff, unsigned long *exif_ifd_offset);
209 static void save_exif_ifd_tags(i_img *im, imtiff *tiff);
210 static void
211 copy_string_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count);
212 static void
213 copy_int_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count);
214 static void
215 copy_rat_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count);
216 static void
217 copy_name_tags(i_img *im, imtiff *tiff, tag_value_map *map, int map_count);
218 static void process_maker_note(i_img *im, imtiff *tiff, unsigned long offset, size_t size);
219
220 /*
221 =head1 PUBLIC FUNCTIONS
222
223 These functions are available to other parts of Imager.  They aren't
224 intended to be called from outside of Imager.
225
226 =over
227
228 =item i_int_decode_exit
229
230 i_int_decode_exif(im, data_base, data_size);
231
232 The data from data_base for data_size bytes will be scanned for EXIF
233 data.
234
235 Any data found will be used to set tags in the supplied image.
236
237 The intent is that invalid EXIF data will simply fail to set tags, and
238 write to the log.  In no case should this code exit when supplied
239 invalid data.
240
241 Returns true if an Exif header was seen.
242
243 */
244
245 int
246 i_int_decode_exif(i_img *im, unsigned char *data, size_t length) {
247   imtiff tiff;
248   unsigned long exif_ifd_offset = 0;
249   unsigned long ifd1_offset;
250   /* basic checks - must start with "Exif\0\0" */
251
252   if (length < 6 || memcmp(data, "Exif\0\0", 6) != 0) {
253     return 0;
254   }
255
256   data += 6;
257   length -= 6;
258
259   if (!tiff_init(&tiff, data, length)) {
260     mm_log((2, "Exif header found, but no valid TIFF header\n"));
261     return 1;
262   }
263   if (!tiff_load_ifd(&tiff, tiff.first_ifd_offset)) {
264     mm_log((2, "Exif header found, but could not load IFD 0\n"));
265     tiff_final(&tiff);
266     return 1;
267   }
268
269   save_ifd0_tags(im, &tiff, &exif_ifd_offset);
270
271   if (exif_ifd_offset) {
272     if (tiff_load_ifd(&tiff, exif_ifd_offset)) {
273       save_exif_ifd_tags(im, &tiff);
274     }
275     else {
276       mm_log((2, "Could not load Exif IFD\n"));
277     }
278   }
279
280   tiff_final(&tiff);
281
282   return 1;
283 }
284
285 /*
286
287 =back
288
289 =head1 INTERNAL FUNCTIONS
290
291 =head2 EXIF Processing 
292
293 =over
294
295 =item save_ifd0_tags
296
297 save_ifd0_tags(im, tiff, &exif_ifd_offset)
298
299 Scans the currently loaded IFD for tags expected in IFD0 and sets them
300 in the image.
301
302 Sets *exif_ifd_offset to the offset of the EXIF IFD if found.
303
304 =cut
305
306 */
307
308 static tag_map ifd0_string_tags[] =
309   {
310     tag_make, "exif_make",
311     tag_model, "exif_model",
312     tag_copyright, "exif_copyright",
313     tag_software, "exif_software",
314     tag_artist, "exif_artist",
315     tag_date_time, "exif_date_time",
316     tag_image_description, "exif_image_description",
317   };
318
319 static const int ifd0_string_tag_count = ARRAY_COUNT(ifd0_string_tags);
320
321 static tag_map ifd0_int_tags[] =
322   {
323     { tag_orientation, "exif_orientation", },
324     { tag_resolution_unit, "exif_resolution_unit" },
325   };
326
327 static const int ifd0_int_tag_count = ARRAY_COUNT(ifd0_int_tags);
328
329 static tag_map ifd0_rat_tags[] =
330   {
331     { tag_x_resolution, "exif_x_resolution" },
332     { tag_y_resolution, "exif_y_resolution" },
333   };
334
335 static tag_map resolution_unit_values[] =
336   {
337     { 1, "none" },
338     { 2, "inches" },
339     { 3, "centimeters" },
340   };
341
342 static tag_value_map ifd0_values[] =
343   {
344     VALUE_MAP_ENTRY(resolution_unit),
345   };
346
347 static void
348 save_ifd0_tags(i_img *im, imtiff *tiff, unsigned long *exif_ifd_offset) {
349   int i, tag_index;
350   int work;
351   ifd_entry *entry;
352
353   for (tag_index = 0, entry = tiff->ifd; 
354        tag_index < tiff->ifd_size; ++tag_index, ++entry) {
355     switch (entry->tag) {
356     case tag_exif_ifd:
357       if (tiff_get_tag_int(tiff, tag_index, &work))
358         *exif_ifd_offset = work;
359       break;
360     }
361   }
362
363   copy_string_tags(im, tiff, ifd0_string_tags, ifd0_string_tag_count);
364   copy_int_tags(im, tiff, ifd0_int_tags, ifd0_int_tag_count);
365   copy_rat_tags(im, tiff, ifd0_rat_tags, ARRAY_COUNT(ifd0_rat_tags));
366   copy_name_tags(im, tiff, ifd0_values, ARRAY_COUNT(ifd0_values));
367 }
368
369 /*
370 =item save_exif_ifd_tags
371
372 save_exif_ifd_tags(im, tiff)
373
374 Scans the currently loaded IFD for the tags expected in the EXIF IFD
375 and sets them as tags in the image.
376
377 =cut
378
379 */
380
381 static tag_map exif_ifd_string_tags[] =
382   {
383     { tag_exif_version, "exif_version", },
384     { tag_flashpix_version, "exif_flashpix_version", },
385     { tag_related_sound_file, "exif_related_sound_file", },
386     { tag_date_time_original, "exif_date_time_original", },
387     { tag_date_time_digitized, "exif_date_time_digitized", },
388     { tag_sub_sec_time, "exif_sub_sec_time" },
389     { tag_sub_sec_time_original, "exif_sub_sec_time_original" },
390     { tag_sub_sec_time_digitized, "exif_sub_sec_time_digitized" },
391     { tag_image_unique_id, "exif_image_unique_id" },
392     { tag_spectral_sensitivity, "exif_spectral_sensitivity" },
393   };
394
395 static const int exif_ifd_string_tag_count = ARRAY_COUNT(exif_ifd_string_tags);
396
397 static tag_map exif_ifd_int_tags[] =
398   {
399     { tag_color_space, "exif_color_space" },
400     { tag_exposure_program, "exif_exposure_program" },
401     { tag_iso_speed_rating, "exif_iso_speed_rating" },
402     { tag_metering_mode, "exif_metering_mode" },
403     { tag_light_source, "exif_light_source" },
404     { tag_flash, "exif_flash" },
405     { tag_focal_plane_resolution_unit, "exif_focal_plane_resolution_unit" },
406     { tag_subject_location, "exif_subject_location" },
407     { tag_sensing_method, "exif_sensing_method" },
408     { tag_custom_rendered, "exif_custom_rendered" },
409     { tag_exposure_mode, "exif_exposure_mode" },
410     { tag_white_balance, "exif_white_balance" },
411     { tag_focal_length_in_35mm_film, "exif_focal_length_in_35mm_film" },
412     { tag_scene_capture_type, "exif_scene_capture_type" },
413     { tag_contrast, "exif_contrast" },
414     { tag_saturation, "exif_saturation" },
415     { tag_sharpness, "exif_sharpness" },
416     { tag_subject_distance_range, "exif_subject_distance_range" },
417   };
418
419
420 static const int exif_ifd_int_tag_count = ARRAY_COUNT(exif_ifd_int_tags);
421
422 static tag_map exif_ifd_rat_tags[] =
423   {
424     { tag_exposure_time, "exif_exposure_time" },
425     { tag_f_number, "exif_f_number" },
426     { tag_shutter_speed, "exif_shutter_speed" },
427     { tag_aperture, "exif_aperture" },
428     { tag_brightness, "exif_brightness" },
429     { tag_exposure_bias, "exif_exposure_bias" },
430     { tag_max_aperture, "exif_max_aperture" },
431     { tag_subject_distance, "exif_subject_distance" },
432     { tag_focal_length, "exif_focal_length" },
433     { tag_flash_energy, "exif_flash_energy" },
434     { tag_focal_plane_x_resolution, "exif_focal_plane_x_resolution" },
435     { tag_focal_plane_y_resolution, "exif_focal_plane_y_resolution" },
436     { tag_exposure_index, "exif_exposure_index" },
437     { tag_digital_zoom_ratio, "exif_digital_zoom_ratio" },
438     { tag_gain_control, "exif_gain_control" },
439   };
440
441 static const int exif_ifd_rat_tag_count = ARRAY_COUNT(exif_ifd_rat_tags);
442
443 static tag_map exposure_mode_values[] =
444   {
445     { 0, "Auto exposure" },
446     { 1, "Manual exposure" },
447     { 2, "Auto bracket" },
448   };
449 static tag_map color_space_values[] =
450   {
451     { 1, "sRGB" },
452     { 0xFFFF, "Uncalibrated" },
453   };
454
455 static tag_map exposure_program_values[] =
456   {
457     { 0, "Not defined" },
458     { 1, "Manual" },
459     { 2, "Normal program" },
460     { 3, "Aperture priority" },
461     { 4, "Shutter priority" },
462     { 5, "Creative program" },
463     { 6, "Action program" },
464     { 7, "Portrait mode" },
465     { 8, "Landscape mode" },
466   };
467
468 static tag_map metering_mode_values[] =
469   {
470     { 0, "unknown" },
471     { 1, "Average" },
472     { 2, "CenterWeightedAverage" },
473     { 3, "Spot" },
474     { 4, "MultiSpot" },
475     { 5, "Pattern" },
476     { 6, "Partial" },
477     { 255, "other" },
478   };
479
480 static tag_map light_source_values[] =
481   {
482     { 0, "unknown" },
483     { 1, "Daylight" },
484     { 2, "Fluorescent" },
485     { 3, "Tungsten (incandescent light)" },
486     { 4, "Flash" },
487     { 9, "Fine weather" },
488     { 10, "Cloudy weather" },
489     { 11, "Shade" },
490     { 12, "Daylight fluorescent (D 5700 Ã 7100K)" },
491     { 13, "Day white fluorescent (N 4600 Ã 5400K)" },
492     { 14, "Cool white fluorescent (W 3900 Ã 4500K)" },
493     { 15, "White fluorescent (WW 3200 Ã 3700K)" },
494     { 17, "Standard light A" },
495     { 18, "Standard light B" },
496     { 19, "Standard light C" },
497     { 20, "D55" },
498     { 21, "D65" },
499     { 22, "D75" },
500     { 23, "D50" },
501     { 24, "ISO studio tungsten" },
502     { 255, "other light source" },
503   };
504
505 static tag_map flash_values[] =
506   {
507     { 0x0000, "Flash did not fire." },
508     { 0x0001, "Flash fired." },
509     { 0x0005, "Strobe return light not detected." },
510     { 0x0007, "Strobe return light detected." },
511     { 0x0009, "Flash fired, compulsory flash mode" },
512     { 0x000D, "Flash fired, compulsory flash mode, return light not detected" },
513     { 0x000F, "Flash fired, compulsory flash mode, return light detected" },
514     { 0x0010, "Flash did not fire, compulsory flash mode" },
515     { 0x0018, "Flash did not fire, auto mode" },
516     { 0x0019, "Flash fired, auto mode" },
517     { 0x001D, "Flash fired, auto mode, return light not detected" },
518     { 0x001F, "Flash fired, auto mode, return light detected" },
519     { 0x0020, "No flash function" },
520     { 0x0041, "Flash fired, red-eye reduction mode" },
521     { 0x0045, "Flash fired, red-eye reduction mode, return light not detected" },
522     { 0x0047, "Flash fired, red-eye reduction mode, return light detected" },
523     { 0x0049, "Flash fired, compulsory flash mode, red-eye reduction mode" },
524     { 0x004D, "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected" },
525     { 0x004F, "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected" },
526     { 0x0059, "Flash fired, auto mode, red-eye reduction mode" },
527     { 0x005D, "Flash fired, auto mode, return light not detected, red-eye reduction mode" },
528     { 0x005F, "Flash fired, auto mode, return light detected, red-eye reduction mode" },
529   };
530
531 static tag_map sensing_method_values[] =
532   {
533     { 1, "Not defined" },
534     { 2, "One-chip color area sensor" },
535     { 3, "Two-chip color area sensor" },
536     { 4, "Three-chip color area sensor" },
537     { 5, "Color sequential area sensor" },
538     { 7, "Trilinear sensor" },
539     { 8, "Color sequential linear sensor" },
540   };
541
542 static tag_map custom_rendered_values[] =
543   {
544     { 0, "Normal process" },
545     { 1, "Custom process" },
546   };
547
548 static tag_map white_balance_values[] =
549   {
550     { 0, "Auto white balance" },
551     { 1, "Manual white balance" },
552   };
553
554 static tag_map scene_capture_type_values[] =
555   {
556     { 0, "Standard" },
557     { 1, "Landscape" },
558     { 2, "Portrait" },
559     { 3, "Night scene" },
560   };
561
562 static tag_map gain_control_values[] =
563   {
564     { 0, "None" },
565     { 1, "Low gain up" },
566     { 2, "High gain up" },
567     { 3, "Low gain down" },
568     { 4, "High gain down" },
569   };
570
571 static tag_map contrast_values[] =
572   {
573     { 0, "Normal" },
574     { 1, "Soft" },
575     { 2, "Hard" },
576   };
577
578 static tag_map saturation_values[] =
579   {
580     { 0, "Normal" },
581     { 1, "Low saturation" },
582     { 2, "High saturation" },
583   };
584
585 static tag_map sharpness_values[] =
586   {
587     { 0, "Normal" },
588     { 1, "Soft" },
589     { 2, "Hard" },
590   };
591
592 static tag_map subject_distance_range_values[] =
593   {
594     { 0, "unknown" },
595     { 1, "Macro" },
596     { 2, "Close view" },
597     { 3, "Distant view" },
598   };
599
600 #define focal_plane_resolution_unit_values resolution_unit_values
601
602 static tag_value_map exif_ifd_values[] =
603   {
604     VALUE_MAP_ENTRY(exposure_mode),
605     VALUE_MAP_ENTRY(color_space),
606     VALUE_MAP_ENTRY(exposure_program),
607     VALUE_MAP_ENTRY(metering_mode),
608     VALUE_MAP_ENTRY(light_source),
609     VALUE_MAP_ENTRY(flash),
610     VALUE_MAP_ENTRY(sensing_method),
611     VALUE_MAP_ENTRY(custom_rendered),
612     VALUE_MAP_ENTRY(white_balance),
613     VALUE_MAP_ENTRY(scene_capture_type),
614     VALUE_MAP_ENTRY(gain_control),
615     VALUE_MAP_ENTRY(contrast),
616     VALUE_MAP_ENTRY(saturation),
617     VALUE_MAP_ENTRY(sharpness),
618     VALUE_MAP_ENTRY(subject_distance_range),
619     VALUE_MAP_ENTRY(focal_plane_resolution_unit),
620   };
621
622 static void
623 save_exif_ifd_tags(i_img *im, imtiff *tiff) {
624   int i, tag_index;
625   int work;
626   ifd_entry *entry;
627   char *user_comment;
628   unsigned long maker_note_offset = 0;
629   size_t maker_note_size = 0;
630
631   for (tag_index = 0, entry = tiff->ifd; 
632        tag_index < tiff->ifd_size; ++tag_index, ++entry) {
633     switch (entry->tag) {
634     case tag_user_comment:
635       /* I don't want to trash the source, so work on a copy */
636       user_comment = mymalloc(entry->size);
637       memcpy(user_comment, tiff->base + entry->offset, entry->size);
638       /* the first 8 bytes indicate the encoding, make them into spaces
639          for better presentation */
640       for (i = 0; i < 8; ++i) {
641         if (user_comment[i] == '\0')
642           user_comment[i] = ' ';
643       }
644       /* find the actual end of the string */
645       while (i < entry->size && user_comment[i])
646         ++i;
647       i_tags_add(&im->tags, "exif_user_comment", 0, user_comment, i, 0);
648       myfree(user_comment);
649       break;
650
651     case tag_maker_note:
652       maker_note_offset = entry->offset;
653       maker_note_size = entry->size;
654       break;
655
656       /* the following aren't processed yet */
657     case tag_oecf:
658     case tag_spatial_frequency_response:
659     case tag_file_source:
660     case tag_scene_type:
661     case tag_cfa_pattern:
662     case tag_device_setting_description:
663     case tag_subject_area:
664       break;
665     }
666   }
667
668   copy_string_tags(im, tiff, exif_ifd_string_tags, exif_ifd_string_tag_count);
669   copy_int_tags(im, tiff, exif_ifd_int_tags, exif_ifd_int_tag_count);
670   copy_rat_tags(im, tiff, exif_ifd_rat_tags, exif_ifd_rat_tag_count);
671   copy_name_tags(im, tiff, exif_ifd_values, ARRAY_COUNT(exif_ifd_values));
672
673   /* This trashes the IFD - make sure it's done last */
674   if (maker_note_offset) {
675     process_maker_note(im, tiff, maker_note_offset, maker_note_size);
676   }
677 }
678
679 /*
680 =item process_maker_note
681
682 This is a stub for processing the maker note tag.
683
684 Maker notes aren't covered by EXIF itself and in general aren't
685 documented by the manufacturers.
686
687 =cut
688 */
689
690 static void
691 process_maker_note(i_img *im, imtiff *tiff, unsigned long offset, size_t size) {
692   /* this will be added in a future release */
693 }
694
695 /*
696 =back
697
698 =head2 High level TIFF functions
699
700 To avoid relying upon tifflib when we're not processing an image we
701 have some simple in-memory TIFF file management.
702
703 =over
704
705 =item tiff_init
706
707 imtiff tiff;
708 if (tiff_init(tiff, data_base, data_size)) {
709   // success
710 }
711
712 Initialize the tiff data structure.
713
714 Scans for the byte order and version markers, and stores the offset to
715 the first IFD (IFD0 in EXIF) in first_ifd_offset.
716
717 =cut
718 */
719
720 static int
721 tiff_init(imtiff *tiff, unsigned char *data, size_t length) {
722   int version;
723
724   tiff->base = data;
725   tiff->size = length;
726   if (length < 8) /* well... would have to be much bigger to be useful */
727     return 0;
728   if (data[0] == 'M' && data[1] == 'M')
729     tiff->type = tt_motorola;
730   else if (data[0] == 'I' && data[1] == 'I') 
731     tiff->type = tt_intel;
732   else
733     return 0; /* invalid header */
734
735   version = tiff_get16(tiff, 2);
736   if (version != 42)
737     return 0;
738
739   tiff->first_ifd_offset = tiff_get32(tiff, 4);
740   if (tiff->first_ifd_offset > length || tiff->first_ifd_offset < 8)
741     return 0;
742
743   tiff->ifd_size = 0;
744   tiff->ifd = NULL;
745   tiff->next_ifd = 0;
746
747   return 1;
748 }
749
750 /*
751 =item tiff_final
752
753 tiff_final(&tiff)
754
755 Clean up the tiff structure initialized by tiff_init()
756
757 =cut
758 */
759
760 static void
761 tiff_final(imtiff *tiff) {
762   tiff_clear_ifd(tiff);
763 }
764
765 /*
766 =item tiff_load_ifd
767
768 if (tiff_load_ifd(tiff, offset)) {
769   // process the ifd
770 }
771
772 Loads the IFD from the given offset into the tiff objects ifd.
773
774 This can fail if the IFD extends beyond end of file, or if any data
775 offsets combined with their sizes, extends beyond end of file.
776
777 Returns true on success.
778
779 =cut
780 */
781
782 static int
783 tiff_load_ifd(imtiff *tiff, unsigned long offset) {
784   unsigned count;
785   int ifd_size;
786   ifd_entry *entries = NULL;
787   int i;
788   unsigned long base;
789
790   tiff_clear_ifd(tiff);
791
792   /* rough check count + 1 entry + next offset */
793   if (offset + (2+12+4) > tiff->size) {
794     mm_log((2, "offset %uld beyond end off Exif block"));
795     return 0;
796   }
797
798   count = tiff_get16(tiff, offset);
799   
800   /* check we can fit the whole thing */
801   ifd_size = 2 + count * 12 + 4; /* count + count entries + next offset */
802   if (offset + ifd_size > tiff->size) {
803     mm_log((2, "offset %uld beyond end off Exif block"));
804     return 0;
805   }
806
807   entries = mymalloc(count * sizeof(ifd_entry));
808   memset(entries, 0, count * sizeof(ifd_entry));
809   base = offset + 2;
810   for (i = 0; i < count; ++i) {
811     ifd_entry *entry = entries + i;
812     entry->tag = tiff_get16(tiff, base);
813     entry->type = tiff_get16(tiff, base+2);
814     entry->count = tiff_get32(tiff, base+4);
815     if (entry->type >= 1 || entry->type <= ift_last) {
816       int data_size = type_sizes[entry->type] * entry->count;
817       entry->size = data_size;
818       if (data_size <= 4) {
819         entry->offset = base + 8;
820       }
821       else {
822         entry->offset = tiff_get32(tiff, base+8);
823         if (entry->offset + data_size > tiff->size) {
824           mm_log((2, "Invalid data offset processing IFD"));
825           myfree(entries);
826           return 0;
827         }
828       }
829     }
830     else {
831       entry->size = 0;
832       entry->offset = 0;
833     }
834     base += 12;
835   }
836
837   tiff->ifd_size = count;
838   tiff->ifd = entries;
839   tiff->next_ifd = tiff_get32(tiff, base);
840
841   return 1;
842 }
843
844 /*
845 =item tiff_clear_ifd
846
847 tiff_clear_ifd(tiff)
848
849 Releases any memory associated with the stored IFD and resets the IFD
850 pointers.
851
852 This is called by tiff_load_ifd() and tiff_final().
853
854 =cut
855 */
856
857 static void
858 tiff_clear_ifd(imtiff *tiff) {
859   int i;
860  
861   if (tiff->ifd_size && tiff->ifd) {
862     myfree(tiff->ifd);
863     tiff->ifd_size = 0;
864     tiff->ifd = NULL;
865   }
866 }
867
868 /*
869 =item tiff_get_tag_double
870
871   double value;
872   if (tiff_get_tag(tiff, index, &value)) {
873     // process value
874   }
875
876 Attempts to retrieve a double value from the given index in the
877 current IFD.
878
879 The value must have a count of 1.
880
881 =cut
882 */
883
884 static int
885 tiff_get_tag_double(imtiff *tiff, int index, double *result) {
886   ifd_entry *entry;
887   if (index < 0 || index >= tiff->ifd_size) {
888     m_fatal(3, "tiff_get_tag_double() index out of range");
889   }
890   
891   entry = tiff->ifd + index;
892   if (entry->count != 1) {
893     mm_log((3, "tiff_get_tag_double() called on tag with multiple values"));
894     return 0;
895   }
896
897   switch (entry->type) {
898   case ift_short:
899     *result = tiff_get16(tiff, entry->offset);
900     return 1;
901    
902   case ift_long:
903     *result = tiff_get32(tiff, entry->offset);
904     return 1;
905
906   case ift_rational:
907     *result = tiff_get_rat(tiff, entry->offset);
908     return 1;
909
910   case ift_sshort:
911     *result = tiff_get16s(tiff, entry->offset);
912     return 1;
913
914   case ift_slong:
915     *result = tiff_get32s(tiff, entry->offset);
916     return 1;
917
918   case ift_srational:
919     *result = tiff_get_rats(tiff, entry->offset);
920     return 1;
921   }
922
923   return 0;
924 }
925
926 /*
927 =item tiff_get_tag_int
928
929   int value;
930   if (tiff_get_tag_int(tiff, index, &value)) {
931     // process value
932   }
933
934 Attempts to retrieve an integer value from the given index in the
935 current IFD.
936
937 The value must have a count of 1.
938
939 =cut
940 */
941
942 static int
943 tiff_get_tag_int(imtiff *tiff, int index, int *result) {
944   ifd_entry *entry;
945   if (index < 0 || index >= tiff->ifd_size) {
946     m_fatal(3, "tiff_get_tag_int() index out of range");
947   }
948   
949   entry = tiff->ifd + index;
950   if (entry->count != 1) {
951     mm_log((3, "tiff_get_tag_int() called on tag with multiple values"));
952     return 0;
953   }
954
955   switch (entry->type) {
956   case ift_short:
957     *result = tiff_get16(tiff, entry->offset);
958     return 1;
959    
960   case ift_long:
961     *result = tiff_get32(tiff, entry->offset);
962     return 1;
963
964   case ift_sshort:
965     *result = tiff_get16s(tiff, entry->offset);
966     return 1;
967
968   case ift_slong:
969     *result = tiff_get32s(tiff, entry->offset);
970     return 1;
971   }
972
973   return 0;
974 }
975
976 /*
977 =back
978
979 =head2 Table-based tag setters
980
981 This set of functions checks for matches between the current IFD and
982 tags supplied in an array, when there's a match it sets the
983 appropriate tag in the image.
984
985 =over
986
987 =item copy_int_tags
988
989 Scans the IFD for integer tags and sets them in the image,
990
991 =cut
992 */
993
994 static void
995 copy_int_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count) {
996   int i, tag_index;
997   ifd_entry *entry;
998
999   for (tag_index = 0, entry = tiff->ifd; 
1000        tag_index < tiff->ifd_size; ++tag_index, ++entry) {
1001     for (i = 0; i < map_count; ++i) {
1002       int value;
1003       if (map[i].tag == entry->tag
1004           && tiff_get_tag_int(tiff, tag_index, &value)) {
1005         i_tags_addn(&im->tags, map[i].name, 0, value);
1006         break;
1007       }
1008     }
1009   }
1010 }
1011
1012 /*
1013 =item copy_rat_tags
1014
1015 Scans the IFD for rational tags and sets them in the image.
1016
1017 =cut
1018 */
1019
1020 static void
1021 copy_rat_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count) {
1022   int i, tag_index;
1023   ifd_entry *entry;
1024
1025   for (tag_index = 0, entry = tiff->ifd; 
1026        tag_index < tiff->ifd_size; ++tag_index, ++entry) {
1027     for (i = 0; i < map_count; ++i) {
1028       double value;
1029       if (map[i].tag == entry->tag
1030           && tiff_get_tag_double(tiff, tag_index, &value)) {
1031         i_tags_set_float2(&im->tags, map[i].name, 0, value, 6);
1032         break;
1033       }
1034     }
1035   }
1036 }
1037
1038 /*
1039 =item copy_string_tags
1040
1041 Scans the IFD for string tags and sets them in the image.
1042
1043 =cut
1044 */
1045
1046 static void
1047 copy_string_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count) {
1048   int i, tag_index;
1049   ifd_entry *entry;
1050
1051   for (tag_index = 0, entry = tiff->ifd; 
1052        tag_index < tiff->ifd_size; ++tag_index, ++entry) {
1053     for (i = 0; i < map_count; ++i) {
1054       if (map[i].tag == entry->tag) {
1055         int len = entry->type == ift_ascii ? entry->size - 1 : entry->size;
1056         i_tags_add(&im->tags, map[i].name, 0,
1057                    (char const *)(tiff->base + entry->offset), len, 0);
1058         break;
1059       }
1060     }
1061   }
1062 }
1063
1064 /*
1065 =item copy_name_tags
1066
1067 This function maps integer values to descriptions for those values.
1068
1069 In general we handle the integer value through copy_int_tags() and
1070 then the same tage with a "_name" suffix here.
1071
1072 =cut
1073 */
1074
1075 static void
1076 copy_name_tags(i_img *im, imtiff *tiff, tag_value_map *map, int map_count) {
1077   int i, j, tag_index;
1078   ifd_entry *entry;
1079
1080   for (tag_index = 0, entry = tiff->ifd; 
1081        tag_index < tiff->ifd_size; ++tag_index, ++entry) {
1082     for (i = 0; i < map_count; ++i) {
1083       int value;
1084       if (map[i].tag == entry->tag
1085           && tiff_get_tag_int(tiff, tag_index, &value)) {
1086         tag_map const *found = NULL;
1087         for (j = 0; j < map[i].map_count; ++j) {
1088           if (value == map[i].map[j].tag) {
1089             found = map[i].map + j;
1090             break;
1091           }
1092         }
1093         if (found) {
1094           i_tags_add(&im->tags, map[i].name, 0, found->name, -1, 0);
1095         }
1096         break;
1097       }
1098     }
1099   }
1100 }
1101
1102
1103 /*
1104 =back
1105
1106 =head2 Low level data access functions
1107
1108 These functions use the byte order in the tiff object to extract
1109 various types of data from the tiff data.
1110
1111 These functions will abort if called with an out of range offset.
1112
1113 The intent is that any offset checks should have been done by the caller.
1114
1115 =over
1116
1117 =item tiff_get16
1118
1119 Retrieve a 16 bit unsigned integer from offset.
1120
1121 =cut
1122 */
1123
1124 static unsigned
1125 tiff_get16(imtiff *tiff, unsigned long offset) {
1126   if (offset + 2 > tiff->size)
1127     m_fatal(3, "attempt to get16 at %uld in %uld image", offset, tiff->size);
1128
1129   if (tiff->type == tt_intel) 
1130     return tiff->base[offset] + 0x100 * tiff->base[offset+1];
1131   else
1132     return tiff->base[offset+1] + 0x100 * tiff->base[offset];
1133 }
1134
1135 /*
1136 =item tiff_get32
1137
1138 Retrieve a 32-bit unsigned integer from offset.
1139
1140 =cut
1141 */
1142
1143 static unsigned
1144 tiff_get32(imtiff *tiff, unsigned long offset) {
1145   if (offset + 4 > tiff->size)
1146     m_fatal(3, "attempt to get16 at %uld in %uld image", offset, tiff->size);
1147
1148   if (tiff->type == tt_intel) 
1149     return tiff->base[offset] + 0x100 * tiff->base[offset+1] 
1150       + 0x10000 * tiff->base[offset+2] + 0x1000000 * tiff->base[offset+3];
1151   else
1152     return tiff->base[offset+3] + 0x100 * tiff->base[offset+2]
1153       + 0x10000 * tiff->base[offset+1] + 0x1000000 * tiff->base[offset];
1154 }
1155
1156 /*
1157 =item tiff_get_bytes
1158
1159 Retrieve a byte string from offset.
1160
1161 This isn't used much, you can usually deal with the data in-situ.
1162 This is intended for use when you need to modify the data in some way.
1163
1164 =cut
1165 */
1166
1167 static int
1168 tiff_get_bytes(imtiff *tiff, unsigned char *data, size_t offset, 
1169                size_t size) {
1170   if (offset + size > tiff->size)
1171     return 0;
1172
1173   memcpy(data, tiff->base+offset, size);
1174
1175   return 1;
1176 }
1177
1178 /*
1179 =item tiff_get16s
1180
1181 Retrieve a 16-bit signed integer from offset.
1182
1183 =cut
1184 */
1185
1186 static int
1187 tiff_get16s(imtiff *tiff, unsigned long offset) {
1188   int result;
1189
1190   if (offset + 2 > tiff->size)
1191     m_fatal(3, "attempt to get16 at %uld in %uld image", offset, tiff->size);
1192
1193   if (tiff->type == tt_intel) 
1194     result = tiff->base[offset] + 0x100 * tiff->base[offset+1];
1195   else
1196     result = tiff->base[offset+1] + 0x100 * tiff->base[offset];
1197
1198   if (result > 0x7FFF)
1199     result -= 0x10000;
1200
1201   return result;
1202 }
1203
1204 /*
1205 =item tiff_get32s
1206
1207 Retrieve a 32-bit signed integer from offset.
1208
1209 =cut
1210 */
1211
1212 static int
1213 tiff_get32s(imtiff *tiff, unsigned long offset) {
1214   unsigned work;
1215
1216   if (offset + 4 > tiff->size)
1217     m_fatal(3, "attempt to get16 at %uld in %uld image", offset, tiff->size);
1218
1219   if (tiff->type == tt_intel) 
1220     work = tiff->base[offset] + 0x100 * tiff->base[offset+1] 
1221       + 0x10000 * tiff->base[offset+2] + 0x1000000 * tiff->base[offset+3];
1222   else
1223     work = tiff->base[offset+3] + 0x100 * tiff->base[offset+2]
1224       + 0x10000 * tiff->base[offset+1] + 0x1000000 * tiff->base[offset];
1225
1226   /* not really needed on 32-bit int machines */
1227   if (work > 0x7FFFFFFFUL)
1228     return work - 0x80000000UL;
1229   else
1230     return work;
1231 }
1232
1233 /*
1234 =item tiff_get_rat
1235
1236 Retrieve an unsigned rational from offset.
1237
1238 =cut
1239 */
1240
1241 static double
1242 tiff_get_rat(imtiff *tiff, unsigned long offset) {
1243   unsigned long numer, denom;
1244   if (offset + 8 > tiff->size)
1245     m_fatal(3, "attempt to get_rat at %lu in %lu image", offset, tiff->size);
1246
1247   numer = tiff_get32(tiff, offset);
1248   denom = tiff_get32(tiff, offset+4);
1249
1250   if (denom == 0) {
1251     return -DBL_MAX;
1252   }
1253
1254   return (double)numer / denom;
1255 }
1256
1257 /*
1258 =item tiff_get_rats
1259
1260 Retrieve an signed rational from offset.
1261
1262 =cut
1263 */
1264
1265 static double
1266 tiff_get_rats(imtiff *tiff, unsigned long offset) {
1267   long numer, denom;
1268   if (offset + 8 > tiff->size)
1269     m_fatal(3, "attempt to get_rat at %lu in %lu image", offset, tiff->size);
1270
1271   numer = tiff_get32s(tiff, offset);
1272   denom = tiff_get32s(tiff, offset+4);
1273
1274   if (denom == 0) {
1275     return -DBL_MAX;
1276   }
1277
1278   return (double)numer / denom;
1279 }
1280
1281 /*
1282 =back
1283
1284 =head1 SEE ALSO
1285
1286 L<Imager>, jpeg.c
1287
1288 http://www.exif.org/
1289
1290 =head1 AUTHOR
1291
1292 Tony Cook <tony@imager.perl.org>
1293
1294 =head1 REVISION
1295
1296 $Revision$
1297
1298 =cut
1299 */