1 /*
2  * Copyright (c) 2004, 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: leica.c,v 1.4 2004/04/20 22:12:51 ejohnst Exp $
33  */
34 
35 /*
36  * Exif tag definitions for Leica maker notes.  Values were derived from
37  * a Digilux 2.
38  *
39  * Note that the Digilux 4.3's maker notes are identical to Fuji's.
40  */
41 
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 
46 #include "makers.h"
47 
48 
49 /* White balance. */
50 
51 static struct descrip leica_white[] = {
52 	{ 1,	"Auto" },
53 	{ 2,	"Sunshine" },
54 	{ 3,	"Cloudy" },
55 	{ 4,	"Halogen" },
56 	{ 5,	"Manual" },
57 	{ 8,	"Electronic Flash" },
58 	{ 10,	"Black & White" },
59 	{ -1,	"Unknown" },
60 };
61 
62 
63 /* Compression rate. */
64 
65 static struct descrip leica_compress[] = {
66 	{ 2,	"Low" },
67 	{ 3,	"Normal" },
68 	{ 6,	"Very Low" },
69 	{ 7,	"Raw" },
70 	{ -1,	"Unknown" },
71 };
72 
73 
74 /* Generic boolean. */
75 
76 static struct descrip leica_bool[] = {
77 	{ 1,	"On" },
78 	{ 2,	"Off" },
79 	{ -1,	"Unknown" },
80 };
81 
82 
83 /* Focus mode. */
84 
85 static struct descrip leica_focus[] = {
86 	{ 1,	"Auto" },
87 	{ 2,	"Manual" },
88 	{ -1,	"Unknown" },
89 };
90 
91 
92 /* Flash exposure compensation. */
93 
94 static struct descrip leica_flashev[] = {
95 	{ 0,		"0 EV" },
96 	{ 1,		"0.33 EV" },
97 	{ 2,		"0.67 EV" },
98 	{ 3,		"1 EV" },
99 	{ 4,		"1.33 EV" },
100 	{ 5,		"1.67 EV" },
101 	{ 6,		"2 EV" },
102 	{ 0xfffa,	"-2 EV" },
103 	{ 0xfffb,	"-1.67 EV" },
104 	{ 0xfffc,	"-1.33 EV" },
105 	{ 0xfffd,	"-1 EV" },
106 	{ 0xfffe,	"-0.67 EV" },
107 	{ 0xffff,	"-0.33 EV" },
108 	{ -1,		"Unknown" },
109 };
110 
111 
112 /* Contrast. */
113 
114 static struct descrip leica_contrast[] = {
115 	{ 0x100,	"Low" },
116 	{ 0x110,	"Standard" },
117 	{ 0x120,	"High" },
118 	{ -1,		"Unknown" },
119 };
120 
121 
122 /* Aperture mode. */
123 
124 static struct descrip leica_aperture[] = {
125 	{ 6,	"Auto" },
126 	{ 7,	"Manual" },
127 	{ -1,	"Unknown" },
128 };
129 
130 
131 /* Spot autofocus. */
132 
133 static struct descrip leica_spotaf[] = {
134 	{ 256,	"On" },
135 	{ 4096,	"Off" },
136 	{ -1,	"Unknown" },
137 };
138 
139 
140 /* Maker note IFD tags. */
141 
142 static struct exiftag leica_tags[] = {
143 	{ 0x0001, TIFF_ASCII, 8, ED_IMG, "LeicaCompress",
144 	  "Compression Rate", leica_compress },
145 	{ 0x0003, TIFF_SHORT, 1, ED_IMG, "LeicaWhiteBal",
146 	  "White Balance", leica_white },
147 	{ 0x0007, TIFF_SHORT, 1, ED_IMG, "LeicaFocusMode",
148 	  "Focus Mode", leica_focus },
149 	{ 0x000f, TIFF_SHORT, 1, ED_IMG, "LeicaSpotAF",
150 	  "Spot Autofocus", leica_spotaf },
151 	{ 0x001c, TIFF_SHORT, 1, ED_IMG, "LeicaMacro",
152 	  "Macro Mode", leica_bool },
153 	{ 0x001f, TIFF_SHORT, 1, ED_IMG, "LeicaAperture",
154 	  "Aperture Mode", leica_aperture },
155 	{ 0x0024, TIFF_SHORT, 1, ED_IMG, "LeicaFlashEV",
156 	  "Flash Compensation", leica_flashev },
157 	{ 0x002c, TIFF_SHORT, 1, ED_IMG, "LeicaContrast",
158 	  "Contrast", leica_contrast },
159 	{ 0xffff, TIFF_UNKN, 0, ED_UNK, "LeicaUnknown",
160 	  "Leica Unknown", NULL },
161 };
162 
163 
164 /*
165  * Process Leica maker note tags.
166  */
167 void
leica_prop(struct exifprop * prop,struct exiftags * t)168 leica_prop(struct exifprop *prop, struct exiftags *t)
169 {
170 
171 	/*
172 	 * Assume that if the property's tag set is not our Leica one,
173 	 * it must be Fuji's.
174 	 */
175 
176 	if (prop->tagset != leica_tags) {
177 		fuji_prop(prop, t);
178 		return;
179 	}
180 
181 	/* Override a couple of standard tags. */
182 
183 	switch (prop->tag) {
184 
185 	/* White balance. */
186 
187 	case 0x0003:
188 		prop->override = EXIF_T_WHITEBAL;
189 		break;
190 
191 	/* Contrast. */
192 
193 	case 0x002c:
194 		prop->override = EXIF_T_CONTRAST;
195 		break;
196 	}
197 }
198 
199 
200 /*
201  * Try to read a Leica maker note IFD.
202  */
203 struct ifd *
leica_ifd(u_int32_t offset,struct tiffmeta * md)204 leica_ifd(u_int32_t offset, struct tiffmeta *md)
205 {
206 
207 	/*
208 	 * Leica maker notes start with an ID string, followed by an IFD
209 	 * offset relative to the MakerNote tag.
210 	 *
211 	 * The Digilux 4.3 seems to just spit out Fuji maker notes.  So,
212 	 * go ahead and use the Fuji functions...
213 	 */
214 
215 	if (!strncmp((const char *)(md->btiff + offset), "FUJIFILM", 8))
216 		return (fuji_ifd(offset, md));
217 
218 	if (!strncmp((const char *)(md->btiff + offset), "LEICA", 5))
219 		return (readifds(offset + 8, leica_tags, md));
220 
221 	return (readifds(offset, leica_tags, md));
222 }
223