8 imexif.c - EXIF support for Imager
12 if (i_int_decode_exif(im, app1data, app1datasize)) {
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.
25 typedef enum tiff_type_tag {
43 ift_last = 12 /* keep the same as the highest type code */
46 static int type_sizes[] =
83 #define PASTE(left, right) PASTE_(left, right)
84 #define PASTE_(left, right) left##right
85 #define QUOTE(value) #value
87 #define VALUE_MAP_ENTRY(name) \
90 "exif_" QUOTE(name) "_name", \
91 PASTE(name, _values), \
92 ARRAY_COUNT(PASTE(name, _values)) \
95 /* we don't process every tag */
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
108 #define tag_exif_ifd 34665
109 #define tag_gps_ifd 34853
111 #define resunit_none 1
112 #define resunit_inch 2
113 #define resunit_centimeter 3
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
173 /* don't use this on pointers */
174 #define ARRAY_COUNT(array) (sizeof(array)/sizeof(*array))
176 /* in memory tiff structure */
178 /* the data we use as a tiff */
182 /* intel or motorola byte order */
185 /* initial ifd offset */
186 unsigned long first_ifd_offset;
188 /* size (in entries) and data */
191 unsigned long next_ifd;
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,
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);
211 copy_string_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count);
213 copy_int_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count);
215 copy_rat_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count);
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);
221 =head1 PUBLIC FUNCTIONS
223 These functions are available to other parts of Imager. They aren't
224 intended to be called from outside of Imager.
228 =item i_int_decode_exit
230 i_int_decode_exif(im, data_base, data_size);
232 The data from data_base for data_size bytes will be scanned for EXIF
235 Any data found will be used to set tags in the supplied image.
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
241 Returns true if an Exif header was seen.
246 i_int_decode_exif(i_img *im, unsigned char *data, size_t length) {
248 unsigned long exif_ifd_offset = 0;
249 unsigned long ifd1_offset;
250 /* basic checks - must start with "Exif\0\0" */
252 if (length < 6 || memcmp(data, "Exif\0\0", 6) != 0) {
259 if (!tiff_init(&tiff, data, length)) {
260 mm_log((2, "Exif header found, but no valid TIFF header\n"));
263 if (!tiff_load_ifd(&tiff, tiff.first_ifd_offset)) {
264 mm_log((2, "Exif header found, but could not load IFD 0\n"));
269 save_ifd0_tags(im, &tiff, &exif_ifd_offset);
271 if (exif_ifd_offset) {
272 if (tiff_load_ifd(&tiff, exif_ifd_offset)) {
273 save_exif_ifd_tags(im, &tiff);
276 mm_log((2, "Could not load Exif IFD\n"));
289 =head1 INTERNAL FUNCTIONS
291 =head2 EXIF Processing
297 save_ifd0_tags(im, tiff, &exif_ifd_offset)
299 Scans the currently loaded IFD for tags expected in IFD0 and sets them
302 Sets *exif_ifd_offset to the offset of the EXIF IFD if found.
308 static tag_map ifd0_string_tags[] =
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",
319 static const int ifd0_string_tag_count = ARRAY_COUNT(ifd0_string_tags);
321 static tag_map ifd0_int_tags[] =
323 { tag_orientation, "exif_orientation", },
324 { tag_resolution_unit, "exif_resolution_unit" },
327 static const int ifd0_int_tag_count = ARRAY_COUNT(ifd0_int_tags);
329 static tag_map ifd0_rat_tags[] =
331 { tag_x_resolution, "exif_x_resolution" },
332 { tag_y_resolution, "exif_y_resolution" },
335 static tag_map resolution_unit_values[] =
339 { 3, "centimeters" },
342 static tag_value_map ifd0_values[] =
344 VALUE_MAP_ENTRY(resolution_unit),
348 save_ifd0_tags(i_img *im, imtiff *tiff, unsigned long *exif_ifd_offset) {
353 for (tag_index = 0, entry = tiff->ifd;
354 tag_index < tiff->ifd_size; ++tag_index, ++entry) {
355 switch (entry->tag) {
357 if (tiff_get_tag_int(tiff, tag_index, &work))
358 *exif_ifd_offset = work;
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));
370 =item save_exif_ifd_tags
372 save_exif_ifd_tags(im, tiff)
374 Scans the currently loaded IFD for the tags expected in the EXIF IFD
375 and sets them as tags in the image.
381 static tag_map exif_ifd_string_tags[] =
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" },
395 static const int exif_ifd_string_tag_count = ARRAY_COUNT(exif_ifd_string_tags);
397 static tag_map exif_ifd_int_tags[] =
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" },
420 static const int exif_ifd_int_tag_count = ARRAY_COUNT(exif_ifd_int_tags);
422 static tag_map exif_ifd_rat_tags[] =
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" },
441 static const int exif_ifd_rat_tag_count = ARRAY_COUNT(exif_ifd_rat_tags);
443 static tag_map exposure_mode_values[] =
445 { 0, "Auto exposure" },
446 { 1, "Manual exposure" },
447 { 2, "Auto bracket" },
449 static tag_map color_space_values[] =
452 { 0xFFFF, "Uncalibrated" },
455 static tag_map exposure_program_values[] =
457 { 0, "Not defined" },
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" },
468 static tag_map metering_mode_values[] =
472 { 2, "CenterWeightedAverage" },
480 static tag_map light_source_values[] =
484 { 2, "Fluorescent" },
485 { 3, "Tungsten (incandescent light)" },
487 { 9, "Fine weather" },
488 { 10, "Cloudy weather" },
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" },
501 { 24, "ISO studio tungsten" },
502 { 255, "other light source" },
505 static tag_map flash_values[] =
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" },
531 static tag_map sensing_method_values[] =
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" },
542 static tag_map custom_rendered_values[] =
544 { 0, "Normal process" },
545 { 1, "Custom process" },
548 static tag_map white_balance_values[] =
550 { 0, "Auto white balance" },
551 { 1, "Manual white balance" },
554 static tag_map scene_capture_type_values[] =
559 { 3, "Night scene" },
562 static tag_map gain_control_values[] =
565 { 1, "Low gain up" },
566 { 2, "High gain up" },
567 { 3, "Low gain down" },
568 { 4, "High gain down" },
571 static tag_map contrast_values[] =
578 static tag_map saturation_values[] =
581 { 1, "Low saturation" },
582 { 2, "High saturation" },
585 static tag_map sharpness_values[] =
592 static tag_map subject_distance_range_values[] =
597 { 3, "Distant view" },
600 #define focal_plane_resolution_unit_values resolution_unit_values
602 static tag_value_map exif_ifd_values[] =
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),
623 save_exif_ifd_tags(i_img *im, imtiff *tiff) {
628 unsigned long maker_note_offset = 0;
629 size_t maker_note_size = 0;
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] = ' ';
644 /* find the actual end of the string */
645 while (i < entry->size && user_comment[i])
647 i_tags_add(&im->tags, "exif_user_comment", 0, user_comment, i, 0);
648 myfree(user_comment);
652 maker_note_offset = entry->offset;
653 maker_note_size = entry->size;
656 /* the following aren't processed yet */
658 case tag_spatial_frequency_response:
659 case tag_file_source:
661 case tag_cfa_pattern:
662 case tag_device_setting_description:
663 case tag_subject_area:
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));
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);
680 =item process_maker_note
682 This is a stub for processing the maker note tag.
684 Maker notes aren't covered by EXIF itself and in general aren't
685 documented by the manufacturers.
691 process_maker_note(i_img *im, imtiff *tiff, unsigned long offset, size_t size) {
692 /* this will be added in a future release */
698 =head2 High level TIFF functions
700 To avoid relying upon tifflib when we're not processing an image we
701 have some simple in-memory TIFF file management.
708 if (tiff_init(tiff, data_base, data_size)) {
712 Initialize the tiff data structure.
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.
721 tiff_init(imtiff *tiff, unsigned char *data, size_t length) {
726 if (length < 8) /* well... would have to be much bigger to be useful */
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;
733 return 0; /* invalid header */
735 version = tiff_get16(tiff, 2);
739 tiff->first_ifd_offset = tiff_get32(tiff, 4);
740 if (tiff->first_ifd_offset > length || tiff->first_ifd_offset < 8)
755 Clean up the tiff structure initialized by tiff_init()
761 tiff_final(imtiff *tiff) {
762 tiff_clear_ifd(tiff);
768 if (tiff_load_ifd(tiff, offset)) {
772 Loads the IFD from the given offset into the tiff objects ifd.
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.
777 Returns true on success.
783 tiff_load_ifd(imtiff *tiff, unsigned long offset) {
786 ifd_entry *entries = NULL;
790 tiff_clear_ifd(tiff);
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"));
798 count = tiff_get16(tiff, offset);
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"));
807 entries = mymalloc(count * sizeof(ifd_entry));
808 memset(entries, 0, count * sizeof(ifd_entry));
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;
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"));
837 tiff->ifd_size = count;
839 tiff->next_ifd = tiff_get32(tiff, base);
849 Releases any memory associated with the stored IFD and resets the IFD
852 This is called by tiff_load_ifd() and tiff_final().
858 tiff_clear_ifd(imtiff *tiff) {
861 if (tiff->ifd_size && tiff->ifd) {
869 =item tiff_get_tag_double
872 if (tiff_get_tag(tiff, index, &value)) {
876 Attempts to retrieve a double value from the given index in the
879 The value must have a count of 1.
885 tiff_get_tag_double(imtiff *tiff, int index, double *result) {
887 if (index < 0 || index >= tiff->ifd_size) {
888 m_fatal(3, "tiff_get_tag_double() index out of range");
891 entry = tiff->ifd + index;
892 if (entry->count != 1) {
893 mm_log((3, "tiff_get_tag_double() called on tag with multiple values"));
897 switch (entry->type) {
899 *result = tiff_get16(tiff, entry->offset);
903 *result = tiff_get32(tiff, entry->offset);
907 *result = tiff_get_rat(tiff, entry->offset);
911 *result = tiff_get16s(tiff, entry->offset);
915 *result = tiff_get32s(tiff, entry->offset);
919 *result = tiff_get_rats(tiff, entry->offset);
927 =item tiff_get_tag_int
930 if (tiff_get_tag_int(tiff, index, &value)) {
934 Attempts to retrieve an integer value from the given index in the
937 The value must have a count of 1.
943 tiff_get_tag_int(imtiff *tiff, int index, int *result) {
945 if (index < 0 || index >= tiff->ifd_size) {
946 m_fatal(3, "tiff_get_tag_int() index out of range");
949 entry = tiff->ifd + index;
950 if (entry->count != 1) {
951 mm_log((3, "tiff_get_tag_int() called on tag with multiple values"));
955 switch (entry->type) {
957 *result = tiff_get16(tiff, entry->offset);
961 *result = tiff_get32(tiff, entry->offset);
965 *result = tiff_get16s(tiff, entry->offset);
969 *result = tiff_get32s(tiff, entry->offset);
979 =head2 Table-based tag setters
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.
989 Scans the IFD for integer tags and sets them in the image,
995 copy_int_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count) {
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) {
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);
1015 Scans the IFD for rational tags and sets them in the image.
1021 copy_rat_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count) {
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) {
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);
1039 =item copy_string_tags
1041 Scans the IFD for string tags and sets them in the image.
1047 copy_string_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count) {
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);
1065 =item copy_name_tags
1067 This function maps integer values to descriptions for those values.
1069 In general we handle the integer value through copy_int_tags() and
1070 then the same tage with a "_name" suffix here.
1076 copy_name_tags(i_img *im, imtiff *tiff, tag_value_map *map, int map_count) {
1077 int i, j, tag_index;
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) {
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;
1094 i_tags_add(&im->tags, map[i].name, 0, found->name, -1, 0);
1106 =head2 Low level data access functions
1108 These functions use the byte order in the tiff object to extract
1109 various types of data from the tiff data.
1111 These functions will abort if called with an out of range offset.
1113 The intent is that any offset checks should have been done by the caller.
1119 Retrieve a 16 bit unsigned integer from offset.
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);
1129 if (tiff->type == tt_intel)
1130 return tiff->base[offset] + 0x100 * tiff->base[offset+1];
1132 return tiff->base[offset+1] + 0x100 * tiff->base[offset];
1138 Retrieve a 32-bit unsigned integer from offset.
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);
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];
1152 return tiff->base[offset+3] + 0x100 * tiff->base[offset+2]
1153 + 0x10000 * tiff->base[offset+1] + 0x1000000 * tiff->base[offset];
1157 =item tiff_get_bytes
1159 Retrieve a byte string from offset.
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.
1168 tiff_get_bytes(imtiff *tiff, unsigned char *data, size_t offset,
1170 if (offset + size > tiff->size)
1173 memcpy(data, tiff->base+offset, size);
1181 Retrieve a 16-bit signed integer from offset.
1187 tiff_get16s(imtiff *tiff, unsigned long offset) {
1190 if (offset + 2 > tiff->size)
1191 m_fatal(3, "attempt to get16 at %uld in %uld image", offset, tiff->size);
1193 if (tiff->type == tt_intel)
1194 result = tiff->base[offset] + 0x100 * tiff->base[offset+1];
1196 result = tiff->base[offset+1] + 0x100 * tiff->base[offset];
1198 if (result > 0x7FFF)
1207 Retrieve a 32-bit signed integer from offset.
1213 tiff_get32s(imtiff *tiff, unsigned long offset) {
1216 if (offset + 4 > tiff->size)
1217 m_fatal(3, "attempt to get16 at %uld in %uld image", offset, tiff->size);
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];
1223 work = tiff->base[offset+3] + 0x100 * tiff->base[offset+2]
1224 + 0x10000 * tiff->base[offset+1] + 0x1000000 * tiff->base[offset];
1226 /* not really needed on 32-bit int machines */
1227 if (work > 0x7FFFFFFFUL)
1228 return work - 0x80000000UL;
1236 Retrieve an unsigned rational from offset.
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);
1247 numer = tiff_get32(tiff, offset);
1248 denom = tiff_get32(tiff, offset+4);
1254 return (double)numer / denom;
1260 Retrieve an signed rational from offset.
1266 tiff_get_rats(imtiff *tiff, unsigned long offset) {
1268 if (offset + 8 > tiff->size)
1269 m_fatal(3, "attempt to get_rat at %lu in %lu image", offset, tiff->size);
1271 numer = tiff_get32s(tiff, offset);
1272 denom = tiff_get32s(tiff, offset+4);
1278 return (double)numer / denom;
1288 http://www.exif.org/
1292 Tony Cook <tony@imager.perl.org>