comparison src/format_olympus.c @ 101:847e4bc6b54c

Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net> * exif.c: Use new format_raw_exif_offset() function to find Exif in raw files. * filelist.c: Add orf and pef to displayed file types. * format_canon.h, format_fuji.h: Update to new #define format. * format_fuji.c: Use same offset for Exif as the jpeg image as the Exif is always embedded in the jpeg and assuming offset of 12 is just broken. * format_nikon.h: Update to new #define format, and add pentax here as finding the jpeg will be same code. * format_olympus.[ch]: Support Olympus raw files with embedded jpegs, not all raw files will have a jpeg, but all appear to have Exif tags. * format_raw.[ch]: Add new camera types, and add a debugging facility to easily list all tags within tiff files (see format_raw.h to enable).
author gqview
date Tue, 07 Nov 2006 21:00:50 +0000
parents deafec7cd99f
children 71e1ebee420e
comparison
equal deleted inserted replaced
100:deafec7cd99f 101:847e4bc6b54c
22 22
23 #include "format_olympus.h" 23 #include "format_olympus.h"
24 #include "format_raw.h" 24 #include "format_raw.h"
25 25
26 #include "exif.h" 26 #include "exif.h"
27
28
29 /*
30 *-----------------------------------------------------------------------------
31 * Raw ORF embedded jpeg extraction for Olympus
32 *-----------------------------------------------------------------------------
33 */
34
35 static guint olympus_tiff_table(unsigned char *data, const guint len, guint offset, ExifByteOrder bo,
36 gint level,
37 guint *image_offset, guint *exif_offset);
38
39
40 static void olympus_tiff_entry(unsigned char *data, const guint len, guint offset, ExifByteOrder bo,
41 gint level,
42 guint *image_offset, guint *exif_offset)
43 {
44 guint tag;
45 guint type;
46 guint count;
47 guint segment;
48 guint seg_len;
49
50 tag = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_TAG, bo);
51 type = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_FORMAT, bo);
52 count = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_COUNT, bo);
53
54 /* so far, we only care about tags with type long */
55 if (type != EXIF_FORMAT_LONG_UNSIGNED && type != EXIF_FORMAT_LONG) return;
56
57 seg_len = ExifFormatList[type].size * count;
58 if (seg_len > 4)
59 {
60 segment = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_DATA, bo);
61 if (segment + seg_len > len) return;
62 }
63 else
64 {
65 segment = offset + EXIF_TIFD_OFFSET_DATA;
66 }
67
68 if (tag == 0x201)
69 {
70 /* start of embedded jpeg, not all olympus cameras embed a jpeg */
71 *image_offset = exif_byte_get_int32(data + segment, bo);
72 }
73
74 if (tag == 0x8769)
75 {
76 /* This is the Exif info */
77 *exif_offset = exif_byte_get_int32(data + segment, bo);
78 }
79 }
80
81 static guint olympus_tiff_table(unsigned char *data, const guint len, guint offset, ExifByteOrder bo,
82 gint level,
83 guint *image_offset, guint *exif_offset)
84 {
85 guint count;
86 guint i;
87
88 if (level > EXIF_TIFF_MAX_LEVELS) return 0;
89
90 if (len < offset + 2) return FALSE;
91
92 count = exif_byte_get_int16(data + offset, bo);
93 offset += 2;
94 if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0;
95
96 for (i = 0; i < count; i++)
97 {
98 olympus_tiff_entry(data, len, offset + i * EXIF_TIFD_SIZE, bo, level,
99 image_offset, exif_offset);
100 }
101
102 return exif_byte_get_int32(data + offset + count * EXIF_TIFD_SIZE, bo);
103 }
104
105 gint format_olympus_raw(unsigned char *data, const guint len,
106 guint *image_offset, guint *exif_offset)
107 {
108 guint i_off = 0;
109 guint e_off = 0;
110 guint offset;
111 gint level;
112
113 if (len < 8) return FALSE;
114
115 /* these are in tiff file format with a different magick header */
116 if (memcmp(data, "IIR", 3) != 0) return FALSE;
117
118 offset = exif_byte_get_int32(data + 4, EXIF_BYTE_ORDER_INTEL);
119
120 level = 0;
121 while (offset && level < EXIF_TIFF_MAX_LEVELS)
122 {
123 offset = olympus_tiff_table(data, len, offset, EXIF_BYTE_ORDER_INTEL, 0, &i_off, &e_off);
124 level++;
125 }
126
127 if (i_off != 0 || e_off != 0)
128 {
129 if (image_offset) *image_offset = i_off;
130 if (exif_offset) *exif_offset = e_off;
131 return TRUE;
132 }
133
134 return FALSE;
135 }
27 136
28 137
29 /* 138 /*
30 *----------------------------------------------------------------------------- 139 *-----------------------------------------------------------------------------
31 * EXIF Makernote for Olympus 140 * EXIF Makernote for Olympus