1 /*
2  * Copyright (c) 2001-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: olympus.c,v 1.17 2004/12/23 20:38:52 ejohnst Exp $
33  */
34 
35 /*
36  * Exif tag definitions for Olympus maker notes.
37  * XXX Support here is somewhat mediocre -- my example image doesn't seem
38  * to have proper values for most tags.
39  *
40  */
41 
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 
46 #include "makers.h"
47 
48 
49 /* Macro mode. */
50 
51 static struct descrip olympus_macro[] = {
52 	{ 0,	"Normal" },
53 	{ 1,	"Macro" },
54 	{ -1,	"Unknown" },
55 };
56 
57 
58 /* Quality. */
59 
60 static struct descrip olympus_quality[] = {
61 	{ 1,	"SQ" },
62 	{ 2,	"HQ" },
63 	{ 3,	"SHQ" },
64 	{ -1,	"Unknown" },
65 };
66 
67 
68 /* Maker note IFD tags. */
69 
70 static struct exiftag olympus_tags[] = {
71 	{ 0x0200, TIFF_LONG, 3, ED_UNK, "OlympusShootMode",
72 	  "Shooting Mode", NULL },
73 	{ 0x0201, TIFF_SHORT, 1, ED_IMG, "OlympusQuality",
74 	  "Compression Setting", olympus_quality },
75 	{ 0x0202, TIFF_SHORT, 1, ED_IMG, "OlympusMacroMode",
76 	  "Macro Mode", olympus_macro },
77 	{ 0x0204, TIFF_RTNL, 1, ED_UNK, "OlympusDigiZoom",
78 	  "Digital Zoom", NULL },
79 	{ 0x0207, TIFF_ASCII, 5, ED_UNK, "FirmwareVer",
80 	  "Firmware Version", NULL },
81 	{ 0x0208, TIFF_ASCII, 52, ED_UNK, "OlympusPicInfo",
82 	  "Picture Info", NULL },
83 	{ 0x0209, TIFF_UNKN, 32, ED_UNK, "OlympusCameraID",
84 	  "Camera ID", NULL },
85 	{ 0xffff, TIFF_UNKN, 0, ED_UNK, "Unknown",
86 	  "Olympus Unknown", NULL },
87 };
88 
89 
90 /*
91  * Process Olympus maker note tags.
92  */
93 void
olympus_prop(struct exifprop * prop,struct exiftags * t)94 olympus_prop(struct exifprop *prop, struct exiftags *t)
95 {
96 	u_int32_t a, b;
97 	unsigned char *offset;
98 	struct exifprop *aprop;
99 
100 	switch (prop->tag) {
101 
102 	/* Various image data. */
103 
104 	case 0x0200:
105 		offset = t->mkrmd.btiff + prop->value;
106 
107 		/*
108 		 * XXX Would be helpful to test this with a panoramic.
109 		 * According to Peter Esherick these values are unsigned
110 		 * longs; however, it appears they may be shorts.  Need to
111 		 * experiment.
112 		 */
113 
114 		/* Picture taking mode. */
115 
116 		aprop = childprop(prop);
117 		aprop->value = exif4byte(offset, t->mkrmd.order);
118 		aprop->name = "OlympusPicMode";
119 		aprop->descr = "Picture Mode";
120 		aprop->lvl = ED_UNK;
121 
122 		/* Sequence number. */
123 
124 		aprop = childprop(prop);
125 		aprop->value = exif4byte(offset + 4, t->mkrmd.order);
126 		aprop->name = "OlympusSeqNum";
127 		aprop->descr = "Sequence Number";
128 		aprop->lvl = ED_UNK;
129 
130 		/* Panorama direction. */
131 
132 		aprop = childprop(prop);
133 		aprop->value = exif4byte(offset + 8, t->mkrmd.order);
134 		aprop->name = "OlympusPanDir";
135 		aprop->descr = "Panoramic Direction";
136 		aprop->lvl = ED_UNK;
137 
138 		break;
139 
140 	/* Digital zoom. */
141 
142 	case 0x0204:
143 		a = exif4byte(t->mkrmd.btiff + prop->value, t->mkrmd.order);
144 		b = exif4byte(t->mkrmd.btiff + prop->value + 4, t->mkrmd.order);
145 
146 		if (a == b)
147 			snprintf(prop->str, 31, "None");
148 		else
149 			snprintf(prop->str, 31, "x%.1f", (float)a / (float)b);
150 		break;
151 
152 	/* Image number. */
153 
154 	case 0x0008:
155 		exifstralloc(&prop->str, 32);
156 		snprintf(prop->str, 31, "%03d-%04d", prop->value / 10000,
157 		    prop->value % 10000);
158 		break;
159 	}
160 }
161 
162 
163 /*
164  * Try to read an Olympus maker note IFD.
165  */
166 struct ifd *
olympus_ifd(u_int32_t offset,struct tiffmeta * md)167 olympus_ifd(u_int32_t offset, struct tiffmeta *md)
168 {
169 	struct ifd *myifd;
170 
171 	/*
172 	 * Seems that Olympus maker notes start with an ID string.  Therefore,
173 	 * try reading the IFD starting at offset + 8 ("OLYMP" + 3).
174 	 */
175 
176 	if (!strcmp((const char *)(md->btiff + offset), "OLYMP"))
177 		readifd(offset + strlen("OLYMP") + 3, &myifd, olympus_tags, md);
178 	else
179 		readifd(offset, &myifd, olympus_tags, md);
180 
181 	return (myifd);
182 }
183