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