Remove commented out code.
[geeqie.git] / src / format_nikon.c
1 /*
2  * Geeqie
3  * (C) 2005 John Ellis
4  * Copyright (C) 2008 - 2012 The Geeqie Team
5  *
6  *  Authors:
7  *    Raw NEF jpeg extraction based on nefextract.c by Joseph Heled,
8  *        in addition nefextract.c is based on dcraw by Dave Coffin.
9  *
10  * This software is released under the GNU General Public License (GNU GPL).
11  * Please read the included file COPYING for more information.
12  * This software comes with no warranty of any kind, use at your own risk!
13  */
14
15 #ifdef HAVE_CONFIG_H
16 #  include "config.h"
17 #endif
18
19 #ifndef HAVE_EXIV2
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #include <glib.h>
26
27 #include "intl.h"
28
29 #include "main.h"
30 #include "format_nikon.h"
31
32 #include "exif.h"
33
34
35 /*
36  *-----------------------------------------------------------------------------
37  * Raw NEF embedded jpeg extraction for Nikon
38  *-----------------------------------------------------------------------------
39  */
40
41 static guint nikon_tiff_table(guchar *data, const guint len, guint offset, ExifByteOrder bo,
42                               gint level,
43                               guint *image_offset, guint *jpeg_len);
44
45
46 static void nikon_tiff_entry(guchar *data, const guint len, guint offset, ExifByteOrder bo,
47                              gint level,
48                              guint *image_offset, guint *image_length, guint *jpeg_start, guint *jpeg_len)
49 {
50         guint tag;
51         guint type;
52         guint count;
53         guint segment;
54         guint seg_len;
55
56         tag = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_TAG, bo);
57         type = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_FORMAT, bo);
58         count = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_COUNT, bo);
59
60         /* so far, we only care about tags with type long */
61         if (type != EXIF_FORMAT_LONG_UNSIGNED && type != EXIF_FORMAT_LONG) return;
62
63         seg_len = ExifFormatList[type].size * count;
64         if (seg_len > 4)
65                 {
66                 segment = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_DATA, bo);
67                 if (segment + seg_len > len) return;
68                 }
69         else
70                 {
71                 segment = offset + EXIF_TIFD_OFFSET_DATA;
72                 }
73
74         if (tag == 0x14a)
75                 {
76                 /* sub IFD table */
77                 guint i;
78
79                 for (i = 0; i < count; i++)
80                         {
81                         guint subset;
82
83                         subset = exif_byte_get_int32(data + segment + i * 4, bo);
84                         nikon_tiff_table(data, len, subset, bo, level + 1, image_offset, image_length);
85                         }
86
87                 }
88         else if (tag == 0x201)
89                 {
90                 /* jpeg data start offset */
91                 *jpeg_start = exif_byte_get_int32(data + segment, bo);
92                 }
93         else if (tag == 0x202)
94                 {
95                 /* jpeg data length */
96                 *jpeg_len = exif_byte_get_int32(data + segment, bo);
97                 }
98 }
99
100 static guint nikon_tiff_table(guchar *data, const guint len, guint offset, ExifByteOrder bo,
101                               gint level,
102                               guint *image_offset, guint *image_length)
103 {
104         guint count;
105         guint i;
106         guint jpeg_start = 0;
107         guint jpeg_len = 0;
108
109         /* limit damage from infinite loops */
110         if (level > EXIF_TIFF_MAX_LEVELS) return 0;
111
112         if (len < offset + 2) return FALSE;
113
114         count = exif_byte_get_int16(data + offset, bo);
115         offset += 2;
116         if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0;
117
118         for (i = 0; i < count; i++)
119                 {
120                 nikon_tiff_entry(data, len, offset + i * EXIF_TIFD_SIZE, bo, level,
121                                  image_offset, image_length, &jpeg_start, &jpeg_len);
122                 }
123
124         if (jpeg_start > 0 &&
125             jpeg_len > *image_length)
126                 {
127                 *image_offset = jpeg_start;
128                 *image_length = jpeg_len;
129                 }
130
131         return exif_byte_get_int32(data + offset + count * EXIF_TIFD_SIZE, bo);
132 }
133
134 gboolean format_nikon_raw(guchar *data, const guint len,
135                           guint *image_offset, guint *exif_offset)
136 {
137         guint i_off = 0;
138         guint i_len = 0;
139         ExifByteOrder bo;
140         guint offset;
141         gint level;
142
143         if (!exif_tiff_directory_offset(data, len, &offset, &bo)) return FALSE;
144
145         level = 0;
146         while (offset && level < EXIF_TIFF_MAX_LEVELS)
147                 {
148                 offset = nikon_tiff_table(data, len, offset, bo, 0, &i_off, &i_len);
149                 level++;
150                 }
151
152         if (i_off != 0)
153                 {
154                 if (image_offset) *image_offset = i_off;
155                 return TRUE;
156                 }
157
158         return FALSE;
159 }
160
161
162 /*
163  *-----------------------------------------------------------------------------
164  * EXIF Makernote for Nikon
165  *-----------------------------------------------------------------------------
166  */
167
168 static ExifTextList NikonTagQuality[]= {
169         { 1,    "VGA basic" },
170         { 2,    "VGA normal" },
171         { 3,    "VGA fine" },
172         { 4,    "SXGA basic" },
173         { 5,    "SXGA normal" },
174         { 6,    "SXGA fine" },
175         { 7,    "XGA basic (?)" },
176         { 8,    "XGA normal (?)" },
177         { 9,    "XGA fine (?)" },
178         { 10,   "UXGA basic" },
179         { 11,   "UXGA normal" },
180         { 12,   "UXGA fine" },
181         EXIF_TEXT_LIST_END
182 };
183
184 static ExifTextList NikonTagColorMode[]= {
185         { 1,    "color" },
186         { 2,    "monochrome" },
187         EXIF_TEXT_LIST_END
188 };
189
190 static ExifTextList NikonTagImgAdjust[]= {
191         { 0,    "normal" },
192         { 1,    "bright+" },
193         { 2,    "bright-" },
194         { 3,    "contrast+" },
195         { 4,    "contrast-" },
196         EXIF_TEXT_LIST_END
197 };
198
199 static ExifTextList NikonTagISOSensitivity[]= {
200         { 0,    "80" },
201         { 2,    "160" },
202         { 4,    "320" },
203         { 5,    "100" },
204         EXIF_TEXT_LIST_END
205 };
206
207 static ExifTextList NikonTagWhiteBalance[]= {
208         { 0,    "auto" },
209         { 1,    "preset" },
210         { 2,    "daylight" },
211         { 3,    "incandescent" },
212         { 4,    "fluorescence" },
213         { 5,    "cloudy" },
214         { 6,    "speedlight" },
215         EXIF_TEXT_LIST_END
216 };
217
218 static ExifTextList NikonTagConverter[]= {
219         { 0,    "none" },
220         { 1,    "Fisheye" },
221         EXIF_TEXT_LIST_END
222 };
223
224 static ExifMarker NikonExifMarkersList1[] = {
225 { 0x0002, EXIF_FORMAT_STRING, 6,                "Nikon.unknown",        NULL,           NULL },
226 { 0x0003, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "Nikon.Quality",        "Quality",      NikonTagQuality },
227 { 0x0004, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "Nikon.ColorMode",      "Color mode",   NikonTagColorMode },
228 { 0x0005, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "Nikon.ImageAdjustment",
229                                                                 "Image adjustment",     NikonTagImgAdjust },
230 { 0x0006, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "Nikon.ISOSensitivity",
231                                                                 "ISO sensitivity",      NikonTagISOSensitivity },
232 { 0x0007, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "Nikon.WhiteBalance",   "White balance",NikonTagWhiteBalance },
233 { 0x0008, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,     "Nikon.Focus",          "Focus",        NULL },
234 { 0x000a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,     "Nikon.DigitalZoom",    "Digital zoom", NULL },
235 { 0x000b, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "Nikon.Converter",      "Converter",    NikonTagConverter },
236 EXIF_MARKER_LIST_END
237 };
238
239 static ExifTextList NikonTag2FlashComp[]= {
240         { 0x06, "+1.0 EV" },
241         { 0x04, "+0.7 EV" },
242         { 0x03, "+0.5 EV" },
243         { 0x02, "+0.3 EV" },
244         { 0x00, "0.0 EV" },
245         { 0xfe, "-0.3 EV" },
246         { 0xfd, "-0.5 EV" },
247         { 0xfc, "-0.7 EV" },
248         { 0xfa, "-1.0 EV" },
249         { 0xf8, "-1.3 EV" },
250         { 0xf7, "-1.5 EV" },
251         { 0xf6, "-1.7 EV" },
252         { 0xf4, "-2.0 EV" },
253         { 0xf2, "-2.3 EV" },
254         { 0xf1, "-2.5 EV" },
255         { 0xf0, "-2.7 EV" },
256         { 0xee, "-3.0 EV" },
257         EXIF_TEXT_LIST_END
258 };
259
260 static ExifTextList NikonTag2LensType[]= {
261         { 0,    "AF non D" },
262         { 1,    "manual" },
263         { 2,    "AF-D or AF-s" },
264         { 6,    "AF-D G" },
265         { 10,   "AF-D VR" },
266         EXIF_TEXT_LIST_END
267 };
268
269 static ExifTextList NikonTag2FlashUsed[]= {
270         { 0,    "no" },
271         { 4,    "unit unknown" },
272         { 7,    "external" },
273         { 9,    "yes" },
274         EXIF_TEXT_LIST_END
275 };
276
277
278 static ExifMarker NikonExifMarkersList2[] = {
279 { 0x0002, EXIF_FORMAT_SHORT_UNSIGNED, 2,        "Nikon.ISOSpeed",       "ISO speed",    NULL },
280 { 0x0003, EXIF_FORMAT_STRING, -1,               "Nikon.ColorMode",      "Color mode",   NULL },
281 { 0x0004, EXIF_FORMAT_STRING, -1,               "Nikon.Quality",        "Quality",      NULL },
282 { 0x0005, EXIF_FORMAT_STRING, -1,               "Nikon.WhiteBalance",   "White balance",NULL },
283 { 0x0006, EXIF_FORMAT_STRING, -1,               "Nikon.Sharpening",     "Sharpening",   NULL },
284 { 0x0007, EXIF_FORMAT_STRING, -1,               "Nikon.FocusMode",      "Focus mode",   NULL },
285 { 0x0008, EXIF_FORMAT_STRING, -1,               "Nikon.FlashSetting",   "Flash setting",NULL },
286 { 0x0009, EXIF_FORMAT_STRING, -1,               "Nikon.AutoFlashMode","Auto flash mode",NULL },
287 { 0x000b, EXIF_FORMAT_SHORT, 1,                 "Nikon.WhiteBalanceBias",
288                                                         "White balance bias value",     NULL },
289 /* { 0x000c, EXIF_FORMAT_SHORT_UNSIGNED, 1,     "Nikon.WhiteBalanceRB",
290                                                 "White balance red/blue coefficients",  NULL }, */
291 /* { 0x000f, EXIF_FORMAT_STRING, -1,            "Nikon.ISOSelect",      "ISO selection",NULL }, */
292 { 0x0012, EXIF_FORMAT_UNDEFINED, 4,             "Nikon.FlashCompensation",
293                                                                 "Flash compensation",   NikonTag2FlashComp },
294 { 0x0013, EXIF_FORMAT_SHORT_UNSIGNED, 2,        "Nikon.ISOSpeedRequest",
295                                                                 "ISO speed requested",  NULL },
296 { 0x0016, EXIF_FORMAT_SHORT_UNSIGNED, 4,        "Nikon.CornerCoord",
297                                                                 "Corner coordinates",   NULL },
298 { 0x0018, EXIF_FORMAT_UNDEFINED, 4,             "Nikon.FlashBracketCompensation",
299                                                         "Flash bracket compensation",   NikonTag2FlashComp },
300 { 0x0019, EXIF_FORMAT_RATIONAL, 1,              "Nikon.AEBracketCompensation",
301                                                         "AE bracket compensation",      NULL },
302 { 0x0080, EXIF_FORMAT_STRING, -1,               "Nikon.ImageAdjustment",
303                                                                 "Image adjustment",     NULL },
304 { 0x0081, EXIF_FORMAT_STRING, -1,               "Nikon.Contrast",       "Contrast",     NULL },
305 { 0x0082, EXIF_FORMAT_STRING, -1,               "Nikon.AuxLens", "Aux lens adapter",    NULL },
306 { 0x0083, EXIF_FORMAT_BYTE_UNSIGNED, -1,        "Nikon.LensType",       "Lens type",    NikonTag2LensType },
307 { 0x0084, EXIF_FORMAT_RATIONAL_UNSIGNED, -1,    "Nikon.LensFocalLength",
308                                                         "Lens min/max focal length and aperture", NULL },
309 { 0x0085, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "Nikon.ManualFocusDistance",
310                                                         "Manual focus distance",        NULL },
311 { 0x0086, EXIF_FORMAT_RATIONAL, 1,              "Nikon.DigitalZoomFactor",
312                                                         "Digital zoom factor",          NULL },
313 { 0x0087, EXIF_FORMAT_BYTE_UNSIGNED, 1,         "Nikon.FlashUsed",      "Flash used",   NikonTag2FlashUsed },
314 { 0x0088, EXIF_FORMAT_UNDEFINED, 4,             "Nikon.AutoFocusArea","Auto focus area",NULL },
315 /* { 0x0089, EXIF_FORMAT_SHORT_UNSIGNED, -1,    "Nikon.Bracket/ShootingMode", NULL,     NULL }, */
316 { 0x008d, EXIF_FORMAT_STRING, -1,               "Nikon.ColorMode",      "Color mode",   NULL },
317 { 0x008f, EXIF_FORMAT_SHORT_UNSIGNED, 1,        "Nikon.SceneMode",      "Scene mode",   NULL },
318 { 0x0090, EXIF_FORMAT_STRING, -1,               "Nikon.LightingType",   "Lighting type",NULL },
319 { 0x0092, EXIF_FORMAT_SHORT, 1,                 "Nikon.HueAdjust",      "Hue adjustment",NULL },
320 /* { 0x0094, EXIF_FORMAT_SHORT_UNSIGNED, 1,     "Nikon.Saturation",     "Saturation",   NikonTag2Saturation }, */
321 { 0x0095, EXIF_FORMAT_STRING, -1,               "Nikon.NoiseReduction", "Noise reduction", NULL },
322 { 0x00a7, EXIF_FORMAT_LONG_UNSIGNED, 1,         "Nikon.ShutterCount", "Shutter release count", NULL },
323 { 0x00a9, EXIF_FORMAT_STRING, -1,               "Nikon.ImageOptimization", "Image optimization", NULL },
324 { 0x00aa, EXIF_FORMAT_STRING, -1,               "Nikon.Saturation", "Saturation",       NULL },
325 { 0x00ab, EXIF_FORMAT_STRING, -1,               "Nikon.DigitalVariProg", "Digital Vari-program", NULL },
326 EXIF_MARKER_LIST_END
327 };
328
329 static ExifTextList NikonAFPoint[]= {
330         { 0,    "center" },
331         { 1,    "top" },
332         { 2,    "bottom" },
333         { 3,    "left" },
334         { 4,    "right" },
335         EXIF_TEXT_LIST_END
336 };
337
338
339 gboolean format_nikon_makernote(ExifData *exif, guchar *tiff, guint offset,
340                                 guint size, ExifByteOrder bo)
341 {
342         guchar *data;
343         ExifItem *item;
344
345         if (offset + 8 + 4 >= size) return FALSE;
346
347         data = tiff + offset;
348
349         /* Nikon tag format 1 */
350         if (memcmp(data, "Nikon\x00\x01\x00", 8) == 0)
351                 {
352                 if (exif_parse_IFD_table(exif, tiff, offset + 8, size,
353                                          bo, 0, NikonExifMarkersList1) != 0)
354                         {
355                         return FALSE;
356                         }
357                 return TRUE;
358                 }
359
360         /* Nikon tag format 2 uses Embedded tiff header */
361         if (memcmp(data, "Nikon\x00\x02\x00\x00\x00", 10) == 0 ||
362             memcmp(data, "Nikon\x00\x02\x10\x00\x00", 10) == 0)
363                 {
364                 guint tiff_header;
365
366                 tiff_header = offset + 10;
367                 if (exif_tiff_parse(exif, tiff + tiff_header, size - tiff_header,
368                     NikonExifMarkersList2) != 0)
369                         {
370                         return FALSE;
371                         }
372                 }
373         /* Nikon tag format 3 uses format 2 tags without "Nikon" and tiff header */
374         else if (exif_parse_IFD_table(exif, tiff, offset, size,
375                                       bo, 0, NikonExifMarkersList2) != 0)
376                 {
377                 return FALSE;
378                 }
379
380         item = exif_get_item(exif, "Nikon.AutoFocusArea");
381         if (item && item->data_len == 4 * sizeof(guchar))
382                 {
383                 static ExifMarker marker = { 0x0088, EXIF_FORMAT_STRING, -1,
384                                              "Nikon.AutoFocusPoint", "Auto focus point", NULL };
385                 guchar *array = item->data;
386                 gchar *text;
387                 gint l;
388
389                 text = exif_text_list_find_value(NikonAFPoint, (gint)array[1]);
390                 l = strlen(text) + 1;
391
392                 item = exif_item_new(marker.format, marker.tag, l, &marker);
393                 memcpy(item->data, text, l);
394
395                 g_free(text);
396
397                 exif->items = g_list_prepend(exif->items, item);
398                 }
399
400         item = exif_get_item(exif, "Nikon.ISOSpeed");
401         if (item && item->data_len == 2 * 2)
402                 {
403                 static ExifMarker marker = { 0x0002, EXIF_FORMAT_SHORT_UNSIGNED, 1,
404                                              "ISOSpeedRatings", "ISO speed", NULL };
405                 ExifItem *shadow;
406
407                 shadow = exif_item_new(marker.format, marker.tag, 1, &marker);
408                 memcpy(shadow->data, item->data + 2, 2);
409
410                 exif->items = g_list_prepend(exif->items, shadow);
411                 }
412
413         item = exif_get_item(exif, "Nikon.WhiteBalance");
414         if (item && item->format == EXIF_FORMAT_STRING)
415                 {
416                 static ExifMarker marker = { 0x0005, EXIF_FORMAT_STRING, -1,
417                                              "LightSource", "Light source", NULL };
418                 ExifItem *shadow;
419
420                 shadow = exif_item_new(marker.format, marker.tag, item->data_len, &marker);
421                 memcpy(shadow->data, item->data, item->data_len);
422
423                 exif->items = g_list_prepend(exif->items, shadow);
424                 }
425
426         return TRUE;
427 }
428
429 #endif
430 /* not HAVE_EXIV2 */
431 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */