1 /*
2 * Copyright (c) 2003, Eric M. Johnston <emj@postal.net>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Eric M. Johnston.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $Id: sanyo.c,v 1.4 2004/12/23 20:38:52 ejohnst Exp $
33 */
34
35 /*
36 * Exif tag definitions for Sanyo maker notes.
37 * Developed from http://www.exif.org/makernotes/SanyoMakerNote.html.
38 *
39 */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "makers.h"
46
47
48 /* Macro mode. */
49
50 static struct descrip sanyo_macro[] = {
51 { 0, "Normal" },
52 { 1, "Macro" },
53 { -1, "Unknown" },
54 };
55
56
57 /* Quality. */
58
59 static struct descrip sanyo_quality[] = {
60 { 0, "Normal" },
61 { 1, "Fine" },
62 { 2, "Superfine" },
63 { -1, "Unknown" },
64 };
65
66
67 /* Resolution. */
68
69 static struct descrip sanyo_res[] = {
70 { 0, "Very Low Resolution" },
71 { 1, "Low Resolution" },
72 { 2, "Medium Low Resolution" },
73 { 3, "Medium Resolution" },
74 { 4, "Medium High Resolution" },
75 { 5, "High Resolution" },
76 { 6, "Very High Resolution" },
77 { 7, "Super High Resolution" },
78 { -1, "Unknown Resolution" },
79 };
80
81
82 /* Sequential shot method. */
83
84 static struct descrip sanyo_seqshot[] = {
85 { 0, "None" },
86 { 1, "Standard" },
87 { 2, "Best" },
88 { 3, "Adjust Exposure" },
89 { -1, "Unknown" },
90 };
91
92
93 /* Boolean value. */
94
95 static struct descrip sanyo_offon[] = {
96 { 0, "Off" },
97 { 1, "On" },
98 { -1, "Unknown" },
99 };
100
101
102 /* Record shutter release. */
103
104 static struct descrip sanyo_shutter[] = {
105 { 0, "Record While Held" },
106 { 1, "Press to Start, Stop" },
107 { -1, "Unknown" },
108 };
109
110
111 /* Enabled/disabled value. */
112
113 static struct descrip sanyo_toggle[] = {
114 { 0, "Disabled" },
115 { 1, "Enabled" },
116 { -1, "Unknown" },
117 };
118
119
120 /* Yes/no value. */
121
122 static struct descrip sanyo_noyes[] = {
123 { 0, "No" },
124 { 1, "Yes" },
125 { -1, "Unknown" },
126 };
127
128
129 /* Scene selection. */
130
131 static struct descrip sanyo_scene[] = {
132 { 0, "Off" },
133 { 1, "Sport" },
134 { 2, "TV" },
135 { 3, "Night" },
136 { 4, "User 1" },
137 { 5, "User 2" },
138 { -1, "Unknown" },
139 };
140
141
142 /* Sequential shot interval. */
143
144 static struct descrip sanyo_interval[] = {
145 { 0, "5 frames/sec" },
146 { 1, "10 frames/sec" },
147 { 2, "15 frames/sec" },
148 { 3, "20 frames/sec" },
149 { -1, "Unknown" },
150 };
151
152
153 /* Flash mode. */
154
155 static struct descrip sanyo_flash[] = {
156 { 0, "Auto" },
157 { 1, "Force" },
158 { 2, "Disabled" },
159 { 3, "Red-Eye" },
160 { -1, "Unknown" },
161 };
162
163
164 /* Maker note IFD tags. */
165
166 static struct exiftag sanyo_tags[] = {
167 { 0x0100, TIFF_UNKN, 0, ED_UNK, "SanyoThumb",
168 "JPEG Thumbnail", NULL },
169 { 0x0200, TIFF_LONG, 3, ED_VRB, "SanyoShootMode",
170 "Shooting Mode", NULL },
171 { 0x0201, TIFF_SHORT, 1, ED_IMG, "SanyoQuality",
172 "Quality Setting", NULL },
173 { 0x0202, TIFF_SHORT, 1, ED_IMG, "SanyoMacroMode",
174 "Macro Mode", sanyo_macro },
175 { 0x0204, TIFF_RTNL, 1, ED_IMG, "SanyoDigiZoom",
176 "Digital Zoom", NULL },
177 { 0x0207, TIFF_ASCII, 5, ED_IMG, "SanyoFirmware",
178 "Firmware Version", NULL },
179 { 0x0208, TIFF_ASCII, 52, ED_IMG, "SanyoPicInfo",
180 "Picture Info", NULL },
181 { 0x0209, TIFF_UNKN, 32, ED_UNK, "SanyoCameraID",
182 "Camera ID", NULL },
183 { 0x020e, TIFF_SHORT, 1, ED_IMG, "SanyoSeqShot",
184 "Sequential Shot Method", sanyo_seqshot },
185 { 0x020f, TIFF_SHORT, 1, ED_IMG, "SanyoWideRange",
186 "Wide Range", sanyo_offon },
187 { 0x0210, TIFF_SHORT, 1, ED_IMG, "SanyoColorAdjust",
188 "Color Adjustment", NULL },
189 { 0x0213, TIFF_SHORT, 1, ED_IMG, "SanyoQuickShot",
190 "Quick Shot", sanyo_offon },
191 { 0x0214, TIFF_SHORT, 1, ED_IMG, "SanyoSelfTime",
192 "Self Timer", sanyo_offon },
193 { 0x0216, TIFF_SHORT, 1, ED_IMG, "SanyoVoiceMemo",
194 "Voice Memo", sanyo_offon },
195 { 0x0217, TIFF_SHORT, 1, ED_IMG, "SanyoRecShutter",
196 "Record Shutter Release", sanyo_shutter },
197 { 0x0218, TIFF_SHORT, 1, ED_IMG, "SanyoFlicker",
198 "Flicker Reduce", sanyo_offon },
199 { 0x0219, TIFF_SHORT, 1, ED_IMG, "SanyoOpticalZoom",
200 "Optical Zoom", sanyo_toggle },
201 { 0x021b, TIFF_SHORT, 1, ED_IMG, "SanyoDigiZoom",
202 "Digital Zoom", sanyo_toggle },
203 { 0x021d, TIFF_SHORT, 1, ED_IMG, "SanyoLightSrc",
204 "Special Light Source", sanyo_offon },
205 { 0x021e, TIFF_SHORT, 1, ED_IMG, "SanyoResaved",
206 "Image Re-saved", sanyo_noyes },
207 { 0x021f, TIFF_SHORT, 1, ED_IMG, "SanyoScene",
208 "Scene Selection", sanyo_scene },
209 { 0x0223, TIFF_SHORT, 1, ED_IMG, "SanyoFocalDist",
210 "Focal Distance", NULL },
211 { 0x0224, TIFF_SHORT, 1, ED_IMG, "SanyoSeqInterval",
212 "Sequential Shot Interval", sanyo_interval },
213 { 0x0225, TIFF_SHORT, 1, ED_IMG, "SanyoFlash",
214 "Flash Mode", sanyo_flash },
215 { 0x0e00, TIFF_UNKN, 0, ED_UNK, "SanyoPrintIM",
216 "Print IM Flags", NULL },
217 { 0x0f00, TIFF_UNKN, 0, ED_UNK, "SanyoDump",
218 "Data Dump", NULL },
219 { 0xffff, TIFF_UNKN, 0, ED_UNK, "SanyoUnknown",
220 "Sanyo Unknown", NULL },
221 };
222
223
224 /* Picture mode. */
225
226 static struct descrip sanyo_picmode[] = {
227 { 0, "Normal" },
228 { 2, "Fast" },
229 { 3, "Panorama" },
230 { -1, "Unknown" },
231 };
232
233
234 /* Panoramic direction. */
235
236 static struct descrip sanyo_pandir[] = {
237 { 1, "Left to Right" },
238 { 2, "Right to Left" },
239 { 3, "Bottom to Top" },
240 { 4, "Top to Bottom" },
241 { -1, "Unknown" },
242 };
243
244
245 /* Shooting mode subtags. */
246
247 static struct exiftag sanyo_shoottags[] = {
248 { 0x0000, TIFF_UNKN, 0, ED_IMG, "SanyoPicMode",
249 "Picture Mode", sanyo_picmode },
250 { 0x0001, TIFF_UNKN, 0, ED_IMG, "SanyoSeqNum",
251 "Sequence Number", NULL },
252 { 0x0002, TIFF_UNKN, 0, ED_IMG, "SanyoPanDir",
253 "Panoramic Direction", sanyo_pandir },
254 { 0xffff, TIFF_UNKN, 0, ED_UNK, "SanyoShootUnknown",
255 "Sanyo Shooting Unknown", NULL },
256 };
257
258
259 /*
260 * Process Sanyo maker note tags.
261 */
262 void
sanyo_prop(struct exifprop * prop,struct exiftags * t)263 sanyo_prop(struct exifprop *prop, struct exiftags *t)
264 {
265 int i, j;
266 u_int32_t a, b;
267 char *c1, *c2;
268 struct exifprop *aprop;
269
270 switch (prop->tag) {
271
272 /* Various image data. */
273
274 case 0x0200:
275 if (debug)
276 printf("Processing %s (0x%04X) directory, %d entries\n",
277 prop->name, prop->tag, prop->count);
278
279 for (i = 0; i < (int)prop->count; i++) {
280 a = exif4byte(t->mkrmd.btiff + prop->value + i * 2,
281 t->mkrmd.order);
282
283 aprop = childprop(prop);
284 aprop->value = a;
285 aprop->tag = i;
286 aprop->tagset = sanyo_shoottags;
287 aprop->type = prop->type;
288 aprop->count = 1;
289
290 /* Lookup property name and description. */
291
292 for (j = 0; sanyo_shoottags[j].tag < EXIF_T_UNKNOWN &&
293 sanyo_shoottags[j].tag != i; j++);
294 aprop->name = sanyo_shoottags[j].name;
295 aprop->descr = sanyo_shoottags[j].descr;
296 aprop->lvl = sanyo_shoottags[j].lvl;
297 if (sanyo_shoottags[j].table)
298 aprop->str =
299 finddescr(sanyo_shoottags[j].table,
300 (u_int16_t)a);
301
302 switch (aprop->tag) {
303 case 0x0001:
304 if (!aprop->value)
305 aprop->lvl = ED_VRB;
306 aprop->value += 1;
307 break;
308 }
309
310 dumpprop(aprop, NULL);
311 }
312 break;
313
314 /* Image quality & resolution. */
315
316 case 0x0201:
317 c1 = finddescr(sanyo_quality,
318 (u_int16_t)((prop->value >> 8) & 0xff));
319 c2 = finddescr(sanyo_res, (u_int16_t)(prop->value & 0xff));
320 exifstralloc(&prop->str, strlen(c1) + strlen(c2) + 3);
321 sprintf(prop->str, "%s, %s", c1, c2);
322 free(c1);
323 free(c2);
324 break;
325
326 /* Digital zoom. */
327
328 case 0x0204:
329 a = exif4byte(t->mkrmd.btiff + prop->value, t->mkrmd.order);
330 b = exif4byte(t->mkrmd.btiff + prop->value + 4, t->mkrmd.order);
331
332 if (!a || !b || a == b)
333 snprintf(prop->str, 31, "None");
334 else
335 snprintf(prop->str, 31, "x%.1f", (float)a / (float)b);
336 break;
337
338 /* Color adjust. */
339
340 case 0x0210:
341 prop->str = finddescr(sanyo_offon, (u_int16_t)(!!prop->value));
342 break;
343 }
344 }
345
346
347 /*
348 * Try to read a Sanyo maker note IFD.
349 */
350 struct ifd *
sanyo_ifd(u_int32_t offset,struct tiffmeta * md)351 sanyo_ifd(u_int32_t offset, struct tiffmeta *md)
352 {
353 struct ifd *myifd;
354
355 /*
356 * Seems that Sanyo maker notes start with an ID string. Therefore,
357 * try reading the IFD starting at offset + 8 ("SANYO" + 3).
358 */
359
360 if (!strcmp((const char *)(md->btiff + offset), "SANYO"))
361 readifd(offset + strlen("SANYO") + 3, &myifd, sanyo_tags, md);
362 else
363 readifd(offset, &myifd, sanyo_tags, md);
364
365 return (myifd);
366 }
367