Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
[geeqie.git] / src / format_nikon.c
1 /*
2  *  GQView
3  *  (C) 2005 John Ellis
4  *
5  * This software is released under the GNU General Public License (GNU GPL).
6  * Please read the included file COPYING for more information.
7  * This software comes with no warranty of any kind, use at your own risk!
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #  include "config.h"
12 #endif
13
14
15 #include <stdio.h>
16 #include <string.h>
17 #include <unistd.h>
18
19 #include <glib.h>
20
21 #include "intl.h"
22
23 #include "format_nikon.h"
24
25 #include "exif.h"
26
27
28 /*
29  *-----------------------------------------------------------------------------
30  * EXIF Makernote for Nikon
31  *-----------------------------------------------------------------------------
32  */
33
34 static ExifTextList NikonTagQuality[]= {
35         { 1,    "VGA basic" },
36         { 2,    "VGA normal" },
37         { 3,    "VGA fine" },
38         { 4,    "SXGA basic" },
39         { 5,    "SXGA normal" },
40         { 6,    "SXGA fine" },
41         { 7,    "XGA basic (?)" },
42         { 8,    "XGA normal (?)" },
43         { 9,    "XGA fine (?)" },
44         { 10,   "UXGA basic" },
45         { 11,   "UXGA normal" },
46         { 12,   "UXGA fine" },
47         EXIF_TEXT_LIST_END
48 };
49
50 static ExifTextList NikonTagColorMode[]= {
51         { 1,    "color" },
52         { 2,    "monochrome" },
53         EXIF_TEXT_LIST_END
54 };
55
56 static ExifTextList NikonTagImgAdjust[]= {
57         { 0,    "normal" },
58         { 1,    "bright+" },
59         { 2,    "bright-" },
60         { 3,    "contrast+" },
61         { 4,    "contrast-" },
62         EXIF_TEXT_LIST_END
63 };
64
65 static ExifTextList NikonTagISOSensitivity[]= {
66         { 0,    "80" },
67         { 2,    "160" },
68         { 4,    "320" },
69         { 5,    "100" },
70         EXIF_TEXT_LIST_END
71 };
72
73 static ExifTextList NikonTagWhiteBalance[]= {
74         { 0,    "auto" },
75         { 1,    "preset" },
76         { 2,    "daylight" },
77         { 3,    "incandescent" },
78         { 4,    "fluorescence" },
79         { 5,    "cloudy" },
80         { 6,    "speedlight" },
81         EXIF_TEXT_LIST_END
82 };
83
84 static ExifTextList NikonTagConverter[]= {
85         { 0,    "none" },
86         { 1,    "Fisheye" },
87         EXIF_TEXT_LIST_END
88 };
89
90 #if 0
91 static ExifTextList NikonTag[]= {
92         { ,     "" },
93         { ,     "" },
94         EXIF_TEXT_LIST_END
95 };
96 #endif
97
98 static ExifMarker NikonExifMarkersList1[] = {
99 { 0x0002, EXIF_FORMAT_STRING, 6,                "MkN.Nikon.unknown",    NULL,           NULL },
100 { 0x0003, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "MkN.Nikon.Quality",    "Quality",      NikonTagQuality },
101 { 0x0004, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "MkN.Nikon.ColorMode",  "Color mode",   NikonTagColorMode },
102 { 0x0005, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "MkN.Nikon.ImageAdjustment",
103                                                                 "Image adjustment",     NikonTagImgAdjust },
104 { 0x0006, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "MkN.Nikon.ISOSensitivity",
105                                                                 "ISO sensitivity",      NikonTagISOSensitivity },
106 { 0x0007, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "MkN.Nikon.WhiteBalance",
107                                                                 "White balance",        NikonTagWhiteBalance },
108 { 0x0008, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,     "MkN.Nikon.Focus",      "Focus",        NULL },
109 { 0x000a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,     "MkN.Nikon.DigitalZoom","Digital zoom", NULL },
110 { 0x000b, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "MkN.Nikon.Converter",  "Converter",    NikonTagConverter },
111 EXIF_MARKER_LIST_END
112 };
113
114 static ExifTextList NikonTag2FlashComp[]= {
115         { 0x06, "+1.0 EV" },
116         { 0x04, "+0.7 EV" },
117         { 0x03, "+0.5 EV" },
118         { 0x02, "+0.3 EV" },
119         { 0x00, "0.0 EV" },
120         { 0xfe, "-0.3 EV" },
121         { 0xfd, "-0.5 EV" },
122         { 0xfc, "-0.7 EV" },
123         { 0xfa, "-1.0 EV" },
124         { 0xf8, "-1.3 EV" },
125         { 0xf7, "-1.5 EV" },
126         { 0xf6, "-1.7 EV" },
127         { 0xf4, "-2.0 EV" },
128         { 0xf2, "-2.3 EV" },
129         { 0xf1, "-2.5 EV" },
130         { 0xf0, "-2.7 EV" },
131         { 0xee, "-3.0 EV" },
132         EXIF_TEXT_LIST_END
133 };
134
135 static ExifTextList NikonTag2FlashUsed[]= {
136         { 0,    "no" },
137         { 9,    "yes" },
138         EXIF_TEXT_LIST_END
139 };
140
141 #if 0
142 static ExifTextList NikonTagi2Saturation[]= {
143         { -3,   "black and white" },
144         { -2,   "-2" },
145         { -1,   "-1" },
146         { 0,    "normal" },
147         { 1,    "+1" },
148         { 2,    "+2" },
149         EXIF_TEXT_LIST_END
150 };
151 #endif
152
153 static ExifMarker NikonExifMarkersList2[] = {
154 { 0x0002, EXIF_FORMAT_SHORT_UNSIGNED, 2,        "MkN.Nikon.ISOSpeed",   "ISO speed",    NULL },
155 { 0x0003, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.ColorMode",  "Color mode",   NULL },
156 { 0x0004, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.Quality",    "Quality",      NULL },
157 { 0x0005, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.WhiteBalance",
158                                                                 "White balance",        NULL },
159 { 0x0006, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.Sharpening", "Sharpening",   NULL },
160 { 0x0007, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.FocusMode",  "Focus mode",   NULL },
161 { 0x0008, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.FlashSetting",
162                                                                 "Flash setting",        NULL },
163 { 0x0009, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.AutoFlashMode","Auto flash mode",NULL },
164 { 0x000b, EXIF_FORMAT_SHORT, 1,                 "MkN.Nikon.WhiteBalanceBias",
165                                                         "White balance bias value",     NULL },
166 /* { 0x000c, EXIF_FORMAT_SHORT_UNSIGNED, 1,     "MkN.Nikon.WhiteBalanceCoeff",
167                                                 "White balance red/blue coefficents",   NULL }, */
168 /* { 0x000f, EXIF_FORMAT_STRING, -1,            "MkN.Nikon.ISOSelect",  "ISO selection",NULL }, */
169 { 0x0012, EXIF_FORMAT_UNDEFINED, 4,             "MkN.Nikon.FlashCompensation",
170                                                                 "Flash compensation",   NikonTag2FlashComp },
171 { 0x0013, EXIF_FORMAT_SHORT_UNSIGNED, 2,        "MkN.Nikon.ISOSpeedRequest",
172                                                                 "ISO speed requested",  NULL },
173 { 0x0016, EXIF_FORMAT_SHORT_UNSIGNED, 4,        "MkN.Nikon.CornerCoord",
174                                                                 "Corner coordinates",   NULL },
175 { 0x0018, EXIF_FORMAT_UNDEFINED, 4,             "MkN.Nikon.FlashBracketCompensation",
176                                                         "Flash bracket compensation",   NikonTag2FlashComp },
177 { 0x0019, EXIF_FORMAT_RATIONAL, 1,              "MkN.Nikon.AEBracketCompensation",
178                                                         "AE bracket compensation",      NULL },
179 { 0x0080, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.ImageAdjustment",
180                                                                 "Image adjustment",     NULL },
181 { 0x0081, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.Contrast",   "Contrast",     NULL },
182 { 0x0082, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.AuxLens","Aux lens adapter", NULL },
183 { 0x0083, EXIF_FORMAT_BYTE_UNSIGNED, -1,        "MkN.Nikon.LensType",   "Lens type",    NULL },
184 { 0x0084, EXIF_FORMAT_RATIONAL_UNSIGNED, -1,    "MkN.Nikon.LensFocalLength",
185                                                         "Lens min/max focal length and aperture", NULL },
186 { 0x0085, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "MkN.Nikon.ManualFocusDistance",
187                                                         "Manual focus distance",        NULL },
188 { 0x0086, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "MkN.Nikon.DigitalZoomFactor",
189                                                         "Digital zoom facotr",          NULL },
190 { 0x0087, EXIF_FORMAT_BYTE_UNSIGNED, 1,         "MkN.Nikon.FlashUsed",  "Flash used",   NikonTag2FlashUsed },
191 { 0x0088, EXIF_FORMAT_UNDEFINED, -1,            "MkN.Nikon.AutoFocusArea", NULL,        NULL },
192 /* { 0x0089, EXIF_FORMAT_SHORT_UNSIGNED, -1,    "MkN.Nikon.Bracket/ShootingMode", NULL, NULL }, */
193 { 0x008d, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.ColorMode",  "Color mode",   NULL },
194 { 0x008f, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "MkN.Nikon.SceneMode",  NULL,           NULL },
195 { 0x0090, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.LightingType", "Lighting type", NULL },
196 { 0x0092, EXIF_FORMAT_SHORT, 1,                 "MkN.Nikon.HueAdjust",  "Hue adjustment", NULL },
197 /* { 0x0094, EXIF_FORMAT_SHORT_UNSIGNED, 1,     "MkN.Nikon.Saturation", "Saturation",   NikonTag2Saturation }, */
198 { 0x0095, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.NoiseReduction", "Noise reduction", NULL },
199 { 0x00a7, EXIF_FORMAT_LONG_UNSIGNED, 1,         "MkN.Nikon.ShutterCount", "Shutter release count", NULL },
200 { 0x00a9, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.ImageOptimization", "Image optimization", NULL },
201 { 0x00aa, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.Saturation", "Saturation",   NULL },
202 { 0x00ab, EXIF_FORMAT_STRING, -1,               "MkN.Nikon.DigitalVariProg", "Digital Vari-program", NULL },
203 EXIF_MARKER_LIST_END
204 };
205
206
207 gint format_nikon_makernote(ExifData *exif, unsigned char *tiff, guint offset,
208                             guint size, ExifByteOrder byte_order)
209 {
210         unsigned char *data;
211
212         if (offset + 8 + 4 >= size) return FALSE;
213
214         data = tiff + offset;
215         if (memcmp(data, "Nikon\x00\x01\x00", 8) == 0)
216                 {
217                 if (exif_parse_IFD_table(exif, tiff, offset + 8, size,
218                                          byte_order, NikonExifMarkersList1) != 0)
219                         {
220                         return FALSE;
221                         }
222                 return TRUE;
223                 }
224
225         if (memcmp(data, "Nikon\x00\x02\x00\x00\x00", 10) == 0 ||
226             memcmp(data, "Nikon\x00\x02\x10\x00\x00", 10) == 0)
227                 {
228                 guint tiff_header;
229
230                 tiff_header = offset + 10;
231                 if (exif_parse_TIFF(exif, tiff + tiff_header, size - tiff_header,
232                     NikonExifMarkersList2) != 0)
233                         {
234                         return FALSE;
235                         }
236                 return TRUE;
237                 }
238
239         /* fixme: support E990 and D1 */
240         if (exif_parse_IFD_table(exif, tiff, offset, size,
241                                  byte_order, NikonExifMarkersList2) != 0)
242                 {
243                 return FALSE;
244                 }
245
246         return FALSE;
247 }
248