796ab8b8d0e2bd993ce678f646f287cf352106a1
[geeqie.git] / src / format_fuji.c
1 /*
2  * Geeqie
3  * (C) 2005 John Ellis
4  * Copyright (C) 2008 - 2012 The Geeqie Team
5  *
6  *  Authors:
7  *    Original version 2005 Lars Ellenberg, base on dcraw by David coffin.
8  *
9  * This software is released under the GNU General Public License (GNU GPL).
10  * Please read the included file COPYING for more information.
11  * This software comes with no warranty of any kind, use at your own risk!
12  */
13
14 #ifdef HAVE_CONFIG_H
15 #  include "config.h"
16 #endif
17
18 #ifndef HAVE_EXIV2
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <unistd.h>
23
24 #include <glib.h>
25
26 #include "intl.h"
27
28 #include "main.h"
29 #include "format_fuji.h"
30 #include "format_raw.h"
31
32 #include "exif.h"
33
34
35 /*
36  *-----------------------------------------------------------------------------
37  * Raw (RAF) embedded jpeg extraction for Fujifilm
38  *-----------------------------------------------------------------------------
39  */
40
41
42 gboolean format_fuji_raw(guchar *data, const guint len,
43                          guint *image_offset, guint *exif_offset)
44 {
45         guint io;
46         guint eo;
47
48         if (len < 128 ||
49             memcmp(data, "FUJIFILM", 8) != 0)
50                 {
51                 return FALSE;
52                 }
53
54         /* offset to jpeg is embedded at bytes 84-87 */
55         io = exif_byte_get_int32(data + 84, EXIF_BYTE_ORDER_MOTOROLA);
56         if (io + 4 > len) return FALSE;
57
58         /* verify jpeg marker */
59         if (memcmp(data + io, "\xff\xd8\xff\xe1", 4) != 0)
60                 {
61                 return FALSE;
62                 }
63
64         /* Exif is stored in the jpeg, so use the same offset */
65         eo=io;
66
67         if (image_offset) *image_offset = io;
68         if (exif_offset) *exif_offset = eo;
69
70         return TRUE;
71 }
72
73
74 /*
75  *-----------------------------------------------------------------------------
76  * EXIF Makernote for Fujifilm
77  *-----------------------------------------------------------------------------
78  */
79
80 static ExifTextList FujiTagSharpness[] = {
81         { 1,    "soft" },
82         { 2,    "soft" },
83         { 3,    "normal" },
84         { 4,    "hard" },
85         { 5,    "hard" },
86         EXIF_TEXT_LIST_END
87 };
88
89 static ExifTextList FujiTagWhiteBalance[]= {
90         { 0,    "auto" },
91         { 256,  "daylight" },
92         { 512,  "cloudy" },
93         { 768,  "daylight color-fluorescence" },
94         { 769,  "daywhite color-fluorescence" },
95         { 770,  "white-fluorescence" },
96         { 1024, "incandescent" },
97         { 3840, "custom" },
98         EXIF_TEXT_LIST_END
99 };
100
101 static ExifTextList FujiTagColorTone[]= {
102         { 0,    "normal" },
103         { 256,  "high" },
104         { 512,  "low" },
105         EXIF_TEXT_LIST_END
106 };
107
108 static ExifTextList FujiTagFlashMode[]= {
109         { 0,    "auto" },
110         { 1,    "on" },
111         { 2,    "off" },
112         { 3,    "red-eye reduction" },
113         EXIF_TEXT_LIST_END
114 };
115
116 static ExifTextList FujiTagOffOn[]= {
117         { 0,    "off" },
118         { 1,    "on" },
119         EXIF_TEXT_LIST_END
120 };
121
122 static ExifTextList FujiTagFocusMode[]= {
123         { 0,    "auto" },
124         { 1,    "manual" },
125         EXIF_TEXT_LIST_END
126 };
127
128 static ExifTextList FujiTagPictureMode[]= {
129         { 0,    "auto" },
130         { 1,    "portrait" },
131         { 2,    "landscape" },
132         { 4,    "sports" },
133         { 5,    "night" },
134         { 6,    "program AE" },
135         { 256,  "aperture priority AE" },
136         { 512,  "shutter priority AE" },
137         { 768,  "manual" },
138         EXIF_TEXT_LIST_END
139 };
140
141 static ExifTextList FujiTagNoYes[]= {
142         { 0,    "no" },
143         { 1,    "yes" },
144         EXIF_TEXT_LIST_END
145 };
146
147 #if 0
148 static ExifTextList FujiTag[]= {
149         { ,     "" },
150         { ,     "" },
151         EXIF_TEXT_LIST_END
152 };
153 #endif
154
155
156 static ExifMarker FujiExifMarkersList[] = {
157 { 0x1000,       EXIF_FORMAT_STRING, 8,          "Fuji.Quality",         "Quality",      NULL },
158 { 0x1001,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.Sharpness",       "Sharpness",    FujiTagSharpness },
159 { 0x1002,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.WhiteBalance",    "White balance",FujiTagWhiteBalance },
160 { 0x1003,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.Color",           "Color",        FujiTagColorTone },
161 { 0x1004,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.Tone",            "Tone",         FujiTagColorTone },
162 { 0x1010,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.FlashMode",       "Flash mode",   FujiTagFlashMode },
163 { 0x1011,       EXIF_FORMAT_RATIONAL, 1,        "Fuji.FlashStrength",   "Flash strength", NULL },
164 { 0x1020,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.Macro",           "Macro",        FujiTagOffOn },
165 { 0x1021,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.FocusMode",       "Focus mode",   FujiTagFocusMode },
166 { 0x1030,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.SlowSync",        "Slow synchro", FujiTagOffOn },
167 { 0x1031,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.PictureMode",     "Picture mode", FujiTagPictureMode },
168 { 0x1100,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.ContTake/Bracket",
169                                                         "Continuous / Auto bracket",    FujiTagOffOn },
170 { 0x1300,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.BlurWarning",     "Blue warning", FujiTagNoYes },
171 { 0x1301,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.FocusWarning",    "Focus warning",FujiTagNoYes },
172 { 0x1302,       EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.AEWarning",       "AE warning",   FujiTagNoYes },
173 EXIF_MARKER_LIST_END
174 };
175
176
177
178 gboolean format_fuji_makernote(ExifData *exif, guchar *tiff, guint offset,
179                                guint size, ExifByteOrder bo)
180 {
181         guchar *data;
182         guint ifdstart;
183
184         if (offset + 8 + 4 >= size) return FALSE;
185
186         data = tiff + offset;
187
188         /* Fuji tag format starts with "FUJIFILM",
189          * followed by 4 bytes indicating offset to IFD directory using Fuji tags,
190          * byte order is always little endian (II).
191          */
192         if (memcmp(data, "FUJIFILM", 8) != 0) return FALSE;
193
194         ifdstart = exif_byte_get_int32(data + 8, EXIF_BYTE_ORDER_INTEL);
195         if (offset + ifdstart >= size) return FALSE;
196
197         if (exif_parse_IFD_table(exif, tiff + offset, ifdstart, size - offset,
198                                  EXIF_BYTE_ORDER_INTEL, 0, FujiExifMarkersList) != 0)
199                 {
200                 return FALSE;
201                 }
202
203         return TRUE;
204 }
205
206 #endif
207 /* not HAVE_EXIV2 */
208 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */