Mercurial > geeqie
annotate src/exif.c @ 694:a3218946bd2d
Sort out log_printf() vs printf_term() mix up.
author | zas_ |
---|---|
date | Tue, 20 May 2008 08:14:35 +0000 |
parents | fbebf5cf4a55 |
children | f606e8962329 |
rev | line source |
---|---|
9 | 1 /* |
541 | 2 * Geeqie |
3 * (C) 2006 John Ellis | |
475 | 4 * Copyright (C) 2008 The Geeqie Team |
9 | 5 * |
6 * Authors: | |
442 | 7 * Support for Exif file format, originally written by Eric Swalens. |
9 | 8 * Modified by Quy Tonthat |
9 * | |
10 * Reimplemented with generic data storage by John Ellis (Nov 2003) | |
11 * | |
12 * The tags were added with information from the FREE document: | |
13 * http://www.ba.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html | |
14 * | |
15 * For the official Exif Format, please refer to: | |
16 * http://www.exif.org | |
17 * http://www.exif.org/specifications.html (PDF spec sheets) | |
18 * | |
19 * Notes: | |
20 * Additional tag formats should be added to the proper | |
21 * location in ExifKnownMarkersList[]. | |
22 * | |
23 * Human readable ouput (that needs additional processing of data to | |
24 * be useable) can be defined by adding a key to ExifFormattedList[], | |
25 * then handling that tag in the function exif_get_formatted_by_key(). | |
26 * The human readable formatted keys must begin with the character 'f'. | |
27 * | |
28 * Unsupported at this time: | |
29 * IFD1 (thumbnail) | |
30 * MakerNote | |
31 * GPSInfo | |
32 * | |
33 * TODO: | |
34 * Convert data to useable form in the ??_as_text function for: | |
35 * ComponentsConfiguration | |
36 * UserComment (convert this to UTF-8?) | |
37 * | |
38 | |
39 This program is free software; you can redistribute it and/or modify | |
40 it under the terms of the GNU General Public License as published by | |
41 the Free Software Foundation; either version 2 of the License, or | |
42 (at your option) any later version. | |
43 | |
44 This program is distributed in the hope that it will be useful, | |
45 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
46 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
47 GNU General Public License for more details. | |
48 | |
49 You should have received a copy of the GNU General Public License | |
50 along with this program; if not, write to the Free Software | |
51 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
52 */ | |
53 | |
54 #ifdef HAVE_CONFIG_H | |
55 # include "config.h" | |
56 #endif | |
57 | |
177 | 58 #ifndef HAVE_EXIV2 |
59 | |
9 | 60 #include <stdio.h> |
61 #include <string.h> | |
62 #include <fcntl.h> | |
63 #include <unistd.h> | |
64 #include <sys/types.h> | |
65 #include <sys/stat.h> | |
66 #include <sys/mman.h> | |
67 #include <math.h> | |
442 | 68 |
9 | 69 #include <glib.h> |
70 | |
71 #include "intl.h" | |
72 | |
281 | 73 #include "main.h" |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
74 #include "exif-int.h" |
9 | 75 |
43
ee03f36e9e4b
Sun May 15 21:40:26 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
76 #include "format_raw.h" |
9 | 77 #include "ui_fileops.h" |
78 | |
79 | |
80 /* | |
81 *----------------------------------------------------------------------------- | |
82 * Tag formats | |
83 *----------------------------------------------------------------------------- | |
84 */ | |
85 | |
86 ExifFormatAttrib ExifFormatList[] = { | |
87 { EXIF_FORMAT_UNKNOWN, 1, "unknown", "unknown" }, | |
88 { EXIF_FORMAT_BYTE_UNSIGNED, 1, "ubyte", "unsigned byte" }, | |
89 { EXIF_FORMAT_STRING, 1, "string", "string" }, | |
90 { EXIF_FORMAT_SHORT_UNSIGNED, 2, "ushort", "unsigned short" }, | |
91 { EXIF_FORMAT_LONG_UNSIGNED, 4, "ulong", "unsigned long" }, | |
92 { EXIF_FORMAT_RATIONAL_UNSIGNED,8, "urational", "unsigned rational" }, | |
93 { EXIF_FORMAT_BYTE, 1, "byte", "byte" }, | |
94 { EXIF_FORMAT_UNDEFINED, 1, "undefined", "undefined" }, | |
95 { EXIF_FORMAT_SHORT, 2, "sshort", "signed short" }, | |
96 { EXIF_FORMAT_LONG, 4, "slong", "signed long" }, | |
97 { EXIF_FORMAT_RATIONAL, 8, "srational", "signed rational" }, | |
98 { EXIF_FORMAT_FLOAT, 4, "float", "float" }, | |
99 { EXIF_FORMAT_DOUBLE, 8, "double", "double" }, | |
100 { -1, 0, NULL } | |
101 }; | |
102 | |
103 /* tags that are special, or need special treatment */ | |
104 #define TAG_EXIFOFFSET 0x8769 | |
47
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
105 #define TAG_EXIFMAKERNOTE 0x927c |
9 | 106 |
107 | |
108 /* | |
109 *----------------------------------------------------------------------------- | |
110 * Data | |
111 *----------------------------------------------------------------------------- | |
112 */ | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
113 static ExifTextList ExifCompressionList[] = { |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
114 { 1, "Uncompressed" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
115 { 2, "CCITT 1D" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
116 { 3, "T4/Group 3 Fax" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
117 { 4, "T6/Group 4 Fax" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
118 { 5, "LZW" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
119 { 6, "JPEG (old style)" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
120 { 7, "JPEG" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
121 { 8, "Adobe Deflate" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
122 { 9, "JBIG B&W" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
123 { 10, "JBIG Color" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
124 { 32766, "Next" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
125 { 32771, "CCIRLEW" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
126 { 32773, "PackBits" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
127 { 32809, "ThunderScan" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
128 { 32895, "IT8CTPAD" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
129 { 32896, "IT8LW" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
130 { 32897, "IT8MP" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
131 { 32898, "IT8BL" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
132 { 32908, "PixasFilm" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
133 { 32909, "PixasLog" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
134 { 32946, "Deflate" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
135 { 32947, "DCS" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
136 { 34661, "JBIG" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
137 { 34676, "SGILog" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
138 { 34677, "SGILog24" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
139 { 34712, "JPEF 2000" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
140 { 34713, "Nikon NEF Compressed" }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
141 EXIF_TEXT_LIST_END |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
142 }; |
9 | 143 |
144 static ExifTextList ExifOrientationList[] = { | |
145 { EXIF_ORIENTATION_UNKNOWN, N_("unknown") }, | |
146 { EXIF_ORIENTATION_TOP_LEFT, N_("top left") }, | |
147 { EXIF_ORIENTATION_TOP_RIGHT, N_("top right") }, | |
148 { EXIF_ORIENTATION_BOTTOM_RIGHT,N_("bottom right") }, | |
149 { EXIF_ORIENTATION_BOTTOM_LEFT, N_("bottom left") }, | |
150 { EXIF_ORIENTATION_LEFT_TOP, N_("left top") }, | |
151 { EXIF_ORIENTATION_RIGHT_TOP, N_("right top") }, | |
152 { EXIF_ORIENTATION_RIGHT_BOTTOM,N_("right bottom") }, | |
153 { EXIF_ORIENTATION_LEFT_BOTTOM, N_("left bottom") }, | |
154 EXIF_TEXT_LIST_END | |
155 }; | |
156 | |
157 static ExifTextList ExifUnitList[] = { | |
158 { EXIF_UNIT_UNKNOWN, N_("unknown") }, | |
159 { EXIF_UNIT_NOUNIT, "" }, | |
160 { EXIF_UNIT_INCH, N_("inch") }, | |
161 { EXIF_UNIT_CENTIMETER, N_("centimeter") }, | |
162 EXIF_TEXT_LIST_END | |
163 }; | |
164 | |
165 static ExifTextList ExifYCbCrPosList[] = { | |
166 { 1, "center" }, | |
167 { 2, "datum" }, | |
168 EXIF_TEXT_LIST_END | |
169 }; | |
170 | |
171 static ExifTextList ExifMeteringModeList[] = { | |
172 { 0, N_("unknown") }, | |
173 { 1, N_("average") }, | |
174 { 2, N_("center weighted") }, | |
175 { 3, N_("spot") }, | |
176 { 4, N_("multi-spot") }, | |
177 { 5, N_("multi-segment") }, | |
178 { 6, N_("partial") }, | |
179 { 255, N_("other") }, | |
180 EXIF_TEXT_LIST_END | |
181 }; | |
182 | |
183 static ExifTextList ExifExposureProgramList[] = { | |
184 { 0, N_("not defined") }, | |
185 { 1, N_("manual") }, | |
186 { 2, N_("normal") }, | |
187 { 3, N_("aperture") }, | |
188 { 4, N_("shutter") }, | |
189 { 5, N_("creative") }, | |
190 { 6, N_("action") }, | |
191 { 7, N_("portrait") }, | |
192 { 8, N_("landscape") }, | |
193 EXIF_TEXT_LIST_END | |
194 }; | |
195 | |
196 static ExifTextList ExifLightSourceList[] = { | |
197 { 0, N_("unknown") }, | |
198 { 1, N_("daylight") }, | |
199 { 2, N_("fluorescent") }, | |
200 { 3, N_("tungsten (incandescent)") }, | |
201 { 4, N_("flash") }, | |
262 | 202 { 9, N_("fine weather") }, |
203 { 10, N_("cloudy weather") }, | |
204 { 11, N_("shade") }, | |
205 { 12, N_("daylight fluorescent") }, | |
206 { 13, N_("day white fluorescent") }, | |
207 { 14, N_("cool white fluorescent") }, | |
293
faeda3c7c8f8
Fix a typo: "while fluorescent" -> "white fluorescent"
zas_
parents:
281
diff
changeset
|
208 { 15, N_("white fluorescent") }, |
262 | 209 { 17, N_("standard light A") }, |
210 { 18, N_("standard light B") }, | |
211 { 19, N_("standard light C") }, | |
212 { 20, N_("D55") }, | |
213 { 21, N_("D65") }, | |
214 { 22, N_("D75") }, | |
215 { 23, N_("D50") }, | |
216 { 24, N_("ISO studio tungsten") }, | |
9 | 217 { 255, N_("other") }, |
218 EXIF_TEXT_LIST_END | |
219 }; | |
220 | |
221 static ExifTextList ExifFlashList[] = { | |
222 { 0, N_("no") }, | |
223 { 1, N_("yes") }, | |
224 { 5, N_("yes, not detected by strobe") }, | |
225 { 7, N_("yes, detected by strobe") }, | |
226 EXIF_TEXT_LIST_END | |
227 }; | |
228 | |
229 static ExifTextList ExifColorSpaceList[] = { | |
262 | 230 { 1, N_("sRGB") }, |
231 { 65535,N_("uncalibrated") }, | |
9 | 232 EXIF_TEXT_LIST_END |
233 }; | |
234 | |
235 static ExifTextList ExifSensorList[] = { | |
262 | 236 { 1, N_("not defined") }, |
237 { 2, N_("1 chip color area") }, | |
238 { 2, N_("2 chip color area") }, | |
239 { 4, N_("3 chip color area") }, | |
240 { 5, N_("color sequential area") }, | |
241 { 7, N_("trilinear") }, | |
242 { 8, N_("color sequential linear") }, | |
9 | 243 EXIF_TEXT_LIST_END |
244 }; | |
245 | |
246 static ExifTextList ExifSourceList[] = { | |
262 | 247 { 3, N_("digital still camera") }, |
9 | 248 EXIF_TEXT_LIST_END |
249 }; | |
250 | |
251 static ExifTextList ExifSceneList[] = { | |
262 | 252 { 1, N_("direct photo") }, |
9 | 253 EXIF_TEXT_LIST_END |
254 }; | |
255 | |
256 static ExifTextList ExifCustRenderList[] = { | |
262 | 257 { 0, N_("normal") }, |
258 { 1, N_("custom") }, | |
9 | 259 EXIF_TEXT_LIST_END |
260 }; | |
261 | |
262 static ExifTextList ExifExposureModeList[] = { | |
262 | 263 { 0, N_("auto") }, |
264 { 1, N_("manual") }, | |
265 { 2, N_("auto bracket") }, | |
9 | 266 EXIF_TEXT_LIST_END |
267 }; | |
268 | |
269 static ExifTextList ExifWhiteBalanceList[] = { | |
262 | 270 { 0, N_("auto") }, |
271 { 1, N_("manual") }, | |
9 | 272 EXIF_TEXT_LIST_END |
273 }; | |
274 | |
275 static ExifTextList ExifSceneCaptureList[] = { | |
262 | 276 { 0, N_("standard") }, |
277 { 1, N_("landscape") }, | |
278 { 2, N_("portrait") }, | |
279 { 3, N_("night scene") }, | |
9 | 280 EXIF_TEXT_LIST_END |
281 }; | |
282 | |
283 static ExifTextList ExifGainControlList[] = { | |
262 | 284 { 0, N_("none") }, |
285 { 1, N_("low gain up") }, | |
286 { 2, N_("high gain up") }, | |
287 { 3, N_("low gain down") }, | |
288 { 4, N_("high gain down") }, | |
9 | 289 EXIF_TEXT_LIST_END |
290 }; | |
291 | |
292 static ExifTextList ExifContrastList[] = { | |
262 | 293 { 0, N_("normal") }, |
294 { 1, N_("soft") }, | |
295 { 2, N_("hard") }, | |
9 | 296 EXIF_TEXT_LIST_END |
297 }; | |
298 | |
299 static ExifTextList ExifSaturationList[] = { | |
262 | 300 { 0, N_("normal") }, |
301 { 1, N_("low") }, | |
302 { 2, N_("high") }, | |
9 | 303 EXIF_TEXT_LIST_END |
304 }; | |
305 | |
306 static ExifTextList ExifSharpnessList[] = { | |
262 | 307 { 0, N_("normal") }, |
308 { 1, N_("soft") }, | |
309 { 2, N_("hard") }, | |
9 | 310 EXIF_TEXT_LIST_END |
311 }; | |
312 | |
313 static ExifTextList ExifSubjectRangeList[] = { | |
262 | 314 { 0, N_("unknown") }, |
315 { 1, N_("macro") }, | |
316 { 2, N_("close") }, | |
317 { 3, N_("distant") }, | |
9 | 318 EXIF_TEXT_LIST_END |
319 }; | |
320 | |
442 | 321 /* |
322 Tag names should match to exiv2 keys, http://www.exiv2.org/metadata.html | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
323 Tags that don't match are not supported by exiv2 and should not be used anywhere in the code |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
324 */ |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
325 |
9 | 326 ExifMarker ExifKnownMarkersList[] = { |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
327 { 0x0100, EXIF_FORMAT_LONG_UNSIGNED, 1, "Exif.Image.ImageWidth", N_("Image Width"), NULL }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
328 { 0x0101, EXIF_FORMAT_LONG_UNSIGNED, 1, "Exif.Image.ImageLength", N_("Image Height"), NULL }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
329 { 0x0102, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Image.BitsPerSample", N_("Bits per Sample/Pixel"), NULL }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
330 { 0x0103, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Image.Compression", N_("Compression"), ExifCompressionList }, |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
331 { 0x010e, EXIF_FORMAT_STRING, -1, "Exif.Image.ImageDescription", N_("Image description"), NULL }, |
262 | 332 { 0x010f, EXIF_FORMAT_STRING, -1, "Exif.Image.Make", N_("Camera make"), NULL }, |
333 { 0x0110, EXIF_FORMAT_STRING, -1, "Exif.Image.Model", N_("Camera model"), NULL }, | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
334 { 0x0112, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Image.Orientation", N_("Orientation"), ExifOrientationList }, |
262 | 335 { 0x011a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Image.XResolution", N_("X resolution"), NULL }, |
336 { 0x011b, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Image.YResolution", N_("Y Resolution"), NULL }, | |
337 { 0x0128, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Image.ResolutionUnit", N_("Resolution units"), ExifUnitList }, | |
338 { 0x0131, EXIF_FORMAT_STRING, -1, "Exif.Image.Software", N_("Firmware"), NULL }, | |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
339 { 0x0132, EXIF_FORMAT_STRING, 20, "Exif.Image.DateTime", N_("Date"), NULL }, |
262 | 340 { 0x013e, EXIF_FORMAT_RATIONAL_UNSIGNED, 2, "Exif.Image.WhitePoint", N_("White point"), NULL }, |
341 { 0x013f, EXIF_FORMAT_RATIONAL_UNSIGNED, 6, "Exif.Image.PrimaryChromaticities",N_("Primary chromaticities"), NULL }, | |
342 { 0x0211, EXIF_FORMAT_RATIONAL_UNSIGNED, 3, "Exif.Image.YCbCrCoefficients", N_("YCbCy coefficients"), NULL }, | |
343 { 0x0213, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Image.YCbCrPositioning", N_("YCbCr positioning"), ExifYCbCrPosList }, | |
344 { 0x0214, EXIF_FORMAT_RATIONAL_UNSIGNED, 6, "Exif.Image.ReferenceBlackWhite",N_("Black white reference"), NULL }, | |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
345 { 0x8298, EXIF_FORMAT_STRING, -1, "Exif.Image.Copyright", N_("Copyright"), NULL }, |
262 | 346 { 0x8769, EXIF_FORMAT_LONG_UNSIGNED, 1, "Exif.Image.ExifTag", N_("SubIFD Exif offset"), NULL }, |
9 | 347 /* subIFD follows */ |
262 | 348 { 0x829a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.ExposureTime", N_("Exposure time (seconds)"), NULL }, |
349 { 0x829d, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.FNumber", N_("FNumber"), NULL }, | |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
350 { 0x8822, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.ExposureProgram", N_("Exposure program"), ExifExposureProgramList }, |
262 | 351 { 0x8824, EXIF_FORMAT_STRING, -1, "Exif.Photo.SpectralSensitivity",N_("Spectral Sensitivity"), NULL }, |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
352 { 0x8827, EXIF_FORMAT_SHORT_UNSIGNED, -1, "Exif.Photo.ISOSpeedRatings", N_("ISO sensitivity"), NULL }, |
262 | 353 { 0x8828, EXIF_FORMAT_UNDEFINED, -1, "Exif.Photo.OECF", N_("Optoelectric conversion factor"), NULL }, |
354 { 0x9000, EXIF_FORMAT_UNDEFINED, 4, "Exif.Photo.ExifVersion", N_("Exif version"), NULL }, | |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
355 { 0x9003, EXIF_FORMAT_STRING, 20, "Exif.Photo.DateTimeOriginal", N_("Date original"), NULL }, |
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
356 { 0x9004, EXIF_FORMAT_STRING, 20, "Exif.Photo.DateTimeDigitized", N_("Date digitized"), NULL }, |
262 | 357 { 0x9101, EXIF_FORMAT_UNDEFINED, -1, "Exif.Photo.ComponentsConfiguration",N_("Pixel format"), NULL }, |
358 { 0x9102, EXIF_FORMAT_RATIONAL_UNSIGNED,1, "Exif.Photo.CompressedBitsPerPixel",N_("Compression ratio"), NULL }, | |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
359 { 0x9201, EXIF_FORMAT_RATIONAL, 1, "Exif.Photo.ShutterSpeedValue", N_("Shutter speed"), NULL }, |
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
360 { 0x9202, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.ApertureValue", N_("Aperture"), NULL }, |
262 | 361 { 0x9203, EXIF_FORMAT_RATIONAL, 1, "Exif.Photo.BrightnessValue", N_("Brightness"), NULL }, |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
362 { 0x9204, EXIF_FORMAT_RATIONAL, 1, "Exif.Photo.ExposureBiasValue", N_("Exposure bias"), NULL }, |
262 | 363 { 0x9205, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.MaxApertureValue", N_("Maximum aperture"), NULL }, |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
364 { 0x9206, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.SubjectDistance", N_("Subject distance"), NULL }, |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
365 { 0x9207, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.MeteringMode", N_("Metering mode"), ExifMeteringModeList }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
366 { 0x9208, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.LightSource", N_("Light source"), ExifLightSourceList }, |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
367 { 0x9209, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.Flash", N_("Flash"), ExifFlashList }, |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
368 { 0x920a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.FocalLength", N_("Focal length"), NULL }, |
262 | 369 { 0x9214, EXIF_FORMAT_SHORT_UNSIGNED, -1, "Exif.Photo.SubjectArea", N_("Subject area"), NULL }, |
370 { 0x927c, EXIF_FORMAT_UNDEFINED, -1, "Exif.Photo.MakerNote", N_("MakerNote"), NULL }, | |
371 { 0x9286, EXIF_FORMAT_UNDEFINED, -1, "Exif.Photo.UserComment", N_("UserComment"), NULL }, | |
372 { 0x9290, EXIF_FORMAT_STRING, -1, "Exif.Photo.SubSecTime", N_("Subsecond time"), NULL }, | |
373 { 0x9291, EXIF_FORMAT_STRING, -1, "Exif.Photo.SubSecTimeOriginal",N_("Subsecond time original"), NULL }, | |
374 { 0x9292, EXIF_FORMAT_STRING, -1, "Exif.Photo.SubSecTimeDigitized",N_("Subsecond time digitized"), NULL }, | |
375 { 0xa000, EXIF_FORMAT_UNDEFINED, 4, "Exif.Photo.FlashpixVersion", N_("FlashPix version"), NULL }, | |
376 { 0xa001, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.ColorSpace", N_("Colorspace"), ExifColorSpaceList }, | |
9 | 377 /* ExifImageWidth, ExifImageHeight can also be unsigned short */ |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
378 { 0xa002, EXIF_FORMAT_LONG_UNSIGNED, 1, "Exif.Photo.PixelXDimension", N_("Width"), NULL }, |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
379 { 0xa003, EXIF_FORMAT_LONG_UNSIGNED, 1, "Exif.Photo.PixelYDimension", N_("Height"), NULL }, |
262 | 380 { 0xa004, EXIF_FORMAT_STRING, -1, "Exif.Photo.RelatedSoundFile", N_("Audio data"), NULL }, |
381 { 0xa005, EXIF_FORMAT_LONG_UNSIGNED, 1, "ExifInteroperabilityOffset", N_("ExifR98 extension"), NULL }, | |
382 { 0xa20b, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.FlashEnergy", N_("Flash strength"), NULL }, | |
383 { 0xa20c, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.SpatialFrequencyResponse",N_("Spatial frequency response"), NULL }, | |
384 { 0xa20e, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.FocalPlaneXResolution", N_("X Pixel density"), NULL }, | |
385 { 0xa20f, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.FocalPlaneYResolution", N_("Y Pixel density"), NULL }, | |
386 { 0xa210, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.FocalPlaneResolutionUnit", N_("Pixel density units"), ExifUnitList }, | |
387 { 0x0214, EXIF_FORMAT_SHORT_UNSIGNED, 2, "Exif.Photo.SubjectLocation", N_("Subject location"), NULL }, | |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
388 { 0xa215, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.ExposureIndex", N_("ISO sensitivity"), NULL }, |
262 | 389 { 0xa217, EXIF_FORMAT_SHORT_UNSIGNED, -1, "Exif.Photo.SensingMethod", N_("Sensor type"), ExifSensorList }, |
390 { 0xa300, EXIF_FORMAT_UNDEFINED, 1, "Exif.Photo.FileSource", N_("Source type"), ExifSourceList }, | |
391 { 0xa301, EXIF_FORMAT_UNDEFINED, 1, "Exif.Photo.SceneType", N_("Scene type"), ExifSceneList }, | |
392 { 0xa302, EXIF_FORMAT_UNDEFINED, -1, "Exif.Image.CFAPattern", N_("Color filter array pattern"), NULL }, | |
9 | 393 /* tags a4xx were added for Exif 2.2 (not just these - some above, as well) */ |
262 | 394 { 0xa401, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.CustomRendered", N_("Render process"), ExifCustRenderList }, |
395 { 0xa402, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.ExposureMode", N_("Exposure mode"), ExifExposureModeList }, | |
396 { 0xa403, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.WhiteBalance", N_("White balance"), ExifWhiteBalanceList }, | |
397 { 0xa404, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.DigitalZoomRatio", N_("Digital zoom ratio"), NULL }, | |
398 { 0xa405, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.FocalLengthIn35mmFilm",N_("Focal length (35mm)"), NULL }, | |
399 { 0xa406, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.SceneCaptureType", N_("Scene capture type"), ExifSceneCaptureList }, | |
400 { 0xa407, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.GainControl", N_("Gain control"), ExifGainControlList }, | |
401 { 0xa408, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.Contrast", N_("Contrast"), ExifContrastList }, | |
402 { 0xa409, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.Saturation", N_("Saturation"), ExifSaturationList }, | |
403 { 0xa40a, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.Sharpness", N_("Sharpness"), ExifSharpnessList }, | |
404 { 0xa40b, EXIF_FORMAT_UNDEFINED, -1, "Exif.Photo.DeviceSettingDescription",N_("Device setting"), NULL }, | |
405 { 0xa40c, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Exif.Photo.SubjectDistanceRange",N_("Subject range"), ExifSubjectRangeList }, | |
406 { 0xa420, EXIF_FORMAT_STRING, -1, "Exif.Photo.ImageUniqueID", N_("Image serial number"), NULL }, | |
9 | 407 /* place known, but undocumented or lesser used tags here */ |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
408 { 0x00fe, EXIF_FORMAT_LONG_UNSIGNED, 1, "Exif.Image.NewSubfileType", NULL, NULL }, |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
409 { 0x00ff, EXIF_FORMAT_SHORT_UNSIGNED, 1, "SubfileType", NULL, NULL }, |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
410 { 0x012d, EXIF_FORMAT_SHORT_UNSIGNED, 3, "Exif.Image.TransferFunction", NULL, NULL }, |
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
411 { 0x013b, EXIF_FORMAT_STRING, -1, "Exif.Image.Artist", "Artist", NULL }, |
9 | 412 { 0x013d, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Predictor", NULL, NULL }, |
413 { 0x0142, EXIF_FORMAT_SHORT_UNSIGNED, 1, "TileWidth", NULL, NULL }, | |
414 { 0x0143, EXIF_FORMAT_SHORT_UNSIGNED, 1, "TileLength", NULL, NULL }, | |
415 { 0x0144, EXIF_FORMAT_LONG_UNSIGNED, -1, "TileOffsets", NULL, NULL }, | |
416 { 0x0145, EXIF_FORMAT_SHORT_UNSIGNED, -1, "TileByteCounts", NULL, NULL }, | |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
417 { 0x014a, EXIF_FORMAT_LONG_UNSIGNED, -1, "Exif.Image.SubIFDs", NULL, NULL }, |
9 | 418 { 0x015b, EXIF_FORMAT_UNDEFINED, -1, "JPEGTables", NULL, NULL }, |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
419 { 0x828d, EXIF_FORMAT_SHORT_UNSIGNED, 2, "Exif.Image.CFARepeatPatternDim", NULL, NULL }, |
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
420 { 0x828e, EXIF_FORMAT_BYTE_UNSIGNED, -1, "Exif.Image.CFAPattern", NULL, NULL }, |
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
421 { 0x828f, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Image.BatteryLevel", NULL, NULL }, |
9 | 422 { 0x83bb, EXIF_FORMAT_LONG_UNSIGNED, -1, "IPTC/NAA", NULL, NULL }, |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
423 { 0x8773, EXIF_FORMAT_UNDEFINED, -1, "Exif.Image.InterColorProfile", NULL, NULL }, |
9 | 424 { 0x8825, EXIF_FORMAT_LONG_UNSIGNED, 1, "GPSInfo", "SubIFD GPS offset", NULL }, |
425 { 0x8829, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Interlace", NULL, NULL }, | |
426 { 0x882a, EXIF_FORMAT_SHORT, 1, "TimeZoneOffset", NULL, NULL }, | |
427 { 0x882b, EXIF_FORMAT_SHORT_UNSIGNED, 1, "SelfTimerMode", NULL, NULL }, | |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
428 { 0x920b, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.FlashEnergy", NULL, NULL }, |
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
429 { 0x920c, EXIF_FORMAT_UNDEFINED, -1, "Exif.Photo.SpatialFrequencyResponse", NULL, NULL }, |
9 | 430 { 0x920d, EXIF_FORMAT_UNDEFINED, -1, "Noise", NULL, NULL }, |
431 { 0x9211, EXIF_FORMAT_LONG_UNSIGNED, 1, "ImageNumber", NULL, NULL }, | |
432 { 0x9212, EXIF_FORMAT_STRING, 1, "SecurityClassification", NULL, NULL }, | |
433 { 0x9213, EXIF_FORMAT_STRING, -1, "ImageHistory", NULL, NULL }, | |
181
c01dd7c9c7dc
unified tag names between exiv2 and internal rxif parser
nadvornik
parents:
177
diff
changeset
|
434 { 0x9215, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Exif.Photo.ExposureIndex", NULL, NULL }, |
9 | 435 { 0x9216, EXIF_FORMAT_BYTE_UNSIGNED, 4, "TIFF/EPStandardID", NULL, NULL }, |
436 | |
47
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
437 EXIF_MARKER_LIST_END |
9 | 438 }; |
439 | |
440 ExifMarker ExifUnknownMarkersList[] = { | |
441 { 0x0000, EXIF_FORMAT_UNKNOWN, 0, "unknown", NULL, NULL }, | |
442 { 0x0000, EXIF_FORMAT_BYTE_UNSIGNED, -1, "unknown", NULL, NULL }, | |
443 { 0x0000, EXIF_FORMAT_STRING, -1, "unknown", NULL, NULL }, | |
444 { 0x0000, EXIF_FORMAT_SHORT_UNSIGNED, -1, "unknown", NULL, NULL }, | |
445 { 0x0000, EXIF_FORMAT_LONG_UNSIGNED, -1, "unknown", NULL, NULL }, | |
446 { 0x0000, EXIF_FORMAT_RATIONAL_UNSIGNED, -1, "unknown", NULL, NULL }, | |
447 { 0x0000, EXIF_FORMAT_BYTE, -1, "unknown", NULL, NULL }, | |
448 { 0x0000, EXIF_FORMAT_UNDEFINED, -1, "unknown", NULL, NULL }, | |
449 { 0x0000, EXIF_FORMAT_SHORT, -1, "unknown", NULL, NULL }, | |
450 { 0x0000, EXIF_FORMAT_LONG, -1, "unknown", NULL, NULL }, | |
451 { 0x0000, EXIF_FORMAT_RATIONAL, -1, "unknown", NULL, NULL }, | |
452 { 0x0000, EXIF_FORMAT_FLOAT, -1, "unknown", NULL, NULL }, | |
453 { 0x0000, EXIF_FORMAT_DOUBLE, -1, "unknown", NULL, NULL }, | |
454 }; | |
455 | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
456 static const ExifMarker *exif_marker_from_tag(guint16 tag, const ExifMarker *list); |
9 | 457 |
458 /* | |
459 *----------------------------------------------------------------------------- | |
460 * ExifItem | |
461 *----------------------------------------------------------------------------- | |
462 */ | |
463 | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
464 ExifItem *exif_item_new(ExifFormatType format, guint tag, |
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
465 guint elements, const ExifMarker *marker) |
9 | 466 { |
467 ExifItem *item; | |
468 | |
469 item = g_new0(ExifItem, 1); | |
470 item->format = format; | |
471 item->tag = tag; | |
472 item->marker = marker; | |
473 item->elements = elements; | |
474 item->data = NULL; | |
475 item->data_len = 0; | |
476 | |
477 switch (format) | |
478 { | |
479 case EXIF_FORMAT_UNKNOWN: | |
480 /* unknown, data is NULL */ | |
481 return item; | |
482 break; | |
483 case EXIF_FORMAT_BYTE_UNSIGNED: | |
484 item->data_len = sizeof(char) * elements; | |
485 break; | |
486 case EXIF_FORMAT_STRING: | |
487 item->data_len = sizeof(char) * elements; | |
488 break; | |
489 case EXIF_FORMAT_SHORT_UNSIGNED: | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
490 item->data_len = sizeof(guint16) * elements; |
9 | 491 break; |
492 case EXIF_FORMAT_LONG_UNSIGNED: | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
493 item->data_len = sizeof(guint32) * elements; |
9 | 494 break; |
495 case EXIF_FORMAT_RATIONAL_UNSIGNED: | |
496 item->data_len = sizeof(ExifRational) * elements; | |
497 break; | |
498 case EXIF_FORMAT_BYTE: | |
499 item->data_len = sizeof(char) * elements; | |
500 break; | |
501 case EXIF_FORMAT_UNDEFINED: | |
502 item->data_len = sizeof(char) * elements; | |
503 break; | |
504 case EXIF_FORMAT_SHORT: | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
505 item->data_len = sizeof(gint16) * elements; |
9 | 506 break; |
507 case EXIF_FORMAT_LONG: | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
508 item->data_len = sizeof(gint32) * elements; |
9 | 509 break; |
510 case EXIF_FORMAT_RATIONAL: | |
511 item->data_len = sizeof(ExifRational) * elements; | |
512 break; | |
513 case EXIF_FORMAT_FLOAT: | |
514 item->data_len = sizeof(float) * elements; | |
515 break; | |
516 case EXIF_FORMAT_DOUBLE: | |
517 item->data_len = sizeof(double) * elements; | |
518 break; | |
519 } | |
520 | |
521 item->data = g_malloc0(item->data_len); | |
522 | |
523 return item; | |
524 } | |
525 | |
526 static void exif_item_free(ExifItem *item) | |
527 { | |
528 if (!item) return; | |
529 | |
530 g_free(item->data); | |
531 g_free(item); | |
532 } | |
533 | |
192 | 534 char *exif_item_get_tag_name(ExifItem *item) |
9 | 535 { |
536 if (!item || !item->marker) return NULL; | |
185 | 537 return g_strdup(item->marker->key); |
9 | 538 } |
539 | |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
540 guint exif_item_get_tag_id(ExifItem *item) |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
541 { |
242
59eac2063093
Fix a segfault occuring when using --without-exiv2 and
zas_
parents:
222
diff
changeset
|
542 if (!item) return 0; |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
543 return item->tag; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
544 } |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
545 |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
546 guint exif_item_get_elements(ExifItem *item) |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
547 { |
242
59eac2063093
Fix a segfault occuring when using --without-exiv2 and
zas_
parents:
222
diff
changeset
|
548 if (!item) return 0; |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
549 return item->elements; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
550 } |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
551 |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
552 char *exif_item_get_data(ExifItem *item, guint *data_len) |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
553 { |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
554 if (data_len) |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
555 *data_len = item->data_len; |
414
49c1cbe058ae
partially fixed reading embedded color profiles with exiv2
nadvornik
parents:
293
diff
changeset
|
556 return g_memdup(item->data, item->data_len); |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
557 } |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
558 |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
559 guint exif_item_get_format_id(ExifItem *item) |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
560 { |
242
59eac2063093
Fix a segfault occuring when using --without-exiv2 and
zas_
parents:
222
diff
changeset
|
561 if (!item) return EXIF_FORMAT_UNKNOWN; |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
562 return item->format; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
563 } |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
564 |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
565 |
182 | 566 char *exif_item_get_description(ExifItem *item) |
9 | 567 { |
568 if (!item || !item->marker) return NULL; | |
182 | 569 return g_strdup(_(item->marker->description)); |
9 | 570 } |
571 | |
572 const char *exif_item_get_format_name(ExifItem *item, gint brief) | |
573 { | |
442 | 574 if (!item || !item->marker) return NULL; |
9 | 575 return (brief) ? ExifFormatList[item->format].short_name : ExifFormatList[item->format].description; |
576 } | |
577 | |
578 static GString *string_append_raw_bytes(GString *string, gpointer data, gint ne) | |
579 { | |
580 gint i; | |
581 | |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
582 for (i = 0 ; i < ne; i++) |
9 | 583 { |
584 unsigned char c = ((char *)data)[i]; | |
585 if (c < 32 || c > 127) c = '.'; | |
586 g_string_append_printf(string, "%c", c); | |
587 } | |
588 string = g_string_append(string, " : "); | |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
589 for (i = 0 ; i < ne; i++) |
9 | 590 { |
591 const gchar *spacer; | |
592 if (i > 0) | |
593 { | |
594 if (i%8 == 0) | |
595 { | |
596 spacer = " - "; | |
597 } | |
598 else | |
599 { | |
600 spacer = " "; | |
601 } | |
602 } | |
603 else | |
604 { | |
605 spacer = ""; | |
606 } | |
607 g_string_append_printf(string, "%s%02x", spacer, ((char *)data)[i]); | |
608 } | |
609 | |
610 return string; | |
611 } | |
612 | |
182 | 613 |
57
a8c9992320f4
Fri Jun 10 20:57:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
55
diff
changeset
|
614 gchar *exif_text_list_find_value(ExifTextList *list, guint value) |
9 | 615 { |
616 gchar *result = NULL; | |
617 gint i; | |
618 | |
619 i = 0; | |
620 while (!result && list[i].value >= 0) | |
621 { | |
622 if (value == list[i].value) result = g_strdup(_(list[i].description)); | |
623 i++; | |
624 } | |
625 if (!result) result = g_strdup_printf("%d (%s)", value, _("unknown")); | |
626 | |
627 return result; | |
628 } | |
629 | |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
630 |
9 | 631 /* |
632 *------------------------------------------------------------------- | |
107 | 633 * byte order utils |
9 | 634 *------------------------------------------------------------------- |
635 */ | |
636 | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
637 /* note: the align_buf is used to avoid alignment issues (on sparc) */ |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
638 |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
639 guint16 exif_byte_get_int16(unsigned char *f, ExifByteOrder bo) |
9 | 640 { |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
641 guint16 align_buf; |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
642 |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
643 memcpy(&align_buf, f, sizeof(guint16)); |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
644 |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
645 if (bo == EXIF_BYTE_ORDER_INTEL) |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
646 return GUINT16_FROM_LE(align_buf); |
9 | 647 else |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
648 return GUINT16_FROM_BE(align_buf); |
9 | 649 } |
650 | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
651 guint32 exif_byte_get_int32(unsigned char *f, ExifByteOrder bo) |
9 | 652 { |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
653 guint32 align_buf; |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
654 |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
655 memcpy(&align_buf, f, sizeof(guint32)); |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
656 |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
657 if (bo == EXIF_BYTE_ORDER_INTEL) |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
658 return GUINT32_FROM_LE(align_buf); |
9 | 659 else |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
660 return GUINT32_FROM_BE(align_buf); |
9 | 661 } |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
662 |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
663 void exif_byte_put_int16(unsigned char *f, guint16 n, ExifByteOrder bo) |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
664 { |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
665 guint16 align_buf; |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
666 |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
667 if (bo == EXIF_BYTE_ORDER_INTEL) |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
668 { |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
669 align_buf = GUINT16_TO_LE(n); |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
670 } |
9 | 671 else |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
672 { |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
673 align_buf = GUINT16_TO_BE(n); |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
674 } |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
675 |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
676 memcpy(f, &align_buf, sizeof(guint16)); |
9 | 677 } |
678 | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
679 void exif_byte_put_int32(unsigned char *f, guint32 n, ExifByteOrder bo) |
9 | 680 { |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
681 guint32 align_buf; |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
682 |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
683 if (bo == EXIF_BYTE_ORDER_INTEL) |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
684 { |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
685 align_buf = GUINT32_TO_LE(n); |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
686 } |
9 | 687 else |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
688 { |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
689 align_buf = GUINT32_TO_BE(n); |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
690 } |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
691 |
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
692 memcpy(f, &align_buf, sizeof(guint32)); |
9 | 693 } |
694 | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
695 |
9 | 696 /* |
697 *------------------------------------------------------------------- | |
698 * IFD utils | |
699 *------------------------------------------------------------------- | |
700 */ | |
701 | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
702 static const ExifMarker *exif_marker_from_tag(guint16 tag, const ExifMarker *list) |
9 | 703 { |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
704 gint i = 0; |
9 | 705 |
47
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
706 if (!list) return NULL; |
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
707 |
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
708 while (list[i].tag != 0 && list[i].tag != tag) |
9 | 709 { |
710 i++; | |
711 } | |
712 | |
47
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
713 return (list[i].tag == 0 ? NULL : &list[i]); |
9 | 714 } |
715 | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
716 static void rational_from_data(ExifRational *r, void *src, ExifByteOrder bo) |
9 | 717 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
718 r->num = exif_byte_get_int32(src, bo); |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
719 r->den = exif_byte_get_int32(src + sizeof(guint32), bo); |
9 | 720 } |
721 | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
722 /* src_format and item->format must be compatible |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
723 * and not overrun src or item->data. |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
724 */ |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
725 void exif_item_copy_data(ExifItem *item, void *src, guint len, |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
726 ExifFormatType src_format, ExifByteOrder bo) |
9 | 727 { |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
728 gint bs; |
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
729 gint ne; |
9 | 730 gpointer dest; |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
731 gint i; |
9 | 732 |
733 bs = ExifFormatList[item->format].size; | |
734 ne = item->elements; | |
735 dest = item->data; | |
736 | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
737 if (!dest || |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
738 ExifFormatList[src_format].size * ne > len) |
9 | 739 { |
185 | 740 gchar *tag = exif_item_get_tag_name(item); |
673
fbebf5cf4a55
Do not use printf() directly but use new wrapper function log_printf() instead.
zas_
parents:
541
diff
changeset
|
741 log_printf("exif tag %s data size mismatch\n", tag); |
185 | 742 g_free(tag); |
9 | 743 return; |
744 } | |
745 | |
746 switch (item->format) | |
747 { | |
748 case EXIF_FORMAT_UNKNOWN: | |
749 break; | |
750 case EXIF_FORMAT_BYTE_UNSIGNED: | |
751 case EXIF_FORMAT_BYTE: | |
752 case EXIF_FORMAT_UNDEFINED: | |
753 memcpy(dest, src, len); | |
754 break; | |
755 case EXIF_FORMAT_STRING: | |
756 memcpy(dest, src, len); | |
757 /* string is NULL terminated, make sure this is true */ | |
758 if (((char *)dest)[len - 1] != '\0') ((char *)dest)[len - 1] = '\0'; | |
759 break; | |
760 case EXIF_FORMAT_SHORT_UNSIGNED: | |
761 case EXIF_FORMAT_SHORT: | |
762 for (i = 0; i < ne; i++) | |
763 { | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
764 ((guint16 *)dest)[i] = exif_byte_get_int16(src + i * bs, bo); |
9 | 765 } |
766 break; | |
767 case EXIF_FORMAT_LONG_UNSIGNED: | |
768 case EXIF_FORMAT_LONG: | |
769 if (src_format == EXIF_FORMAT_SHORT_UNSIGNED || | |
770 src_format == EXIF_FORMAT_SHORT) | |
771 { | |
772 /* a short fits into a long, so allow it */ | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
773 gint ss; |
9 | 774 |
775 ss = ExifFormatList[src_format].size; | |
776 for (i = 0; i < ne; i++) | |
777 { | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
778 ((gint32 *)dest)[i] = |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
779 (gint32)exif_byte_get_int16(src + i * ss, bo); |
9 | 780 } |
781 } | |
782 else | |
783 { | |
784 for (i = 0; i < ne; i++) | |
785 { | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
786 ((gint32 *)dest)[i] = |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
787 exif_byte_get_int32(src + i * bs, bo); |
9 | 788 } |
789 } | |
790 break; | |
791 case EXIF_FORMAT_RATIONAL_UNSIGNED: | |
792 case EXIF_FORMAT_RATIONAL: | |
793 for (i = 0; i < ne; i++) | |
794 { | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
795 rational_from_data(&((ExifRational *)dest)[i], src + i * bs, bo); |
9 | 796 } |
797 break; | |
798 case EXIF_FORMAT_FLOAT: | |
799 for (i = 0; i < ne; i++) | |
800 { | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
801 ((float *)dest)[i] = exif_byte_get_int32(src + i * bs, bo); |
9 | 802 } |
803 break; | |
804 case EXIF_FORMAT_DOUBLE: | |
805 for (i = 0; i < ne; i++) | |
806 { | |
807 ExifRational r; | |
808 | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
809 rational_from_data(&r, src + i * bs, bo); |
9 | 810 if (r.den) ((double *)dest)[i] = (double)r.num / r.den; |
811 } | |
812 break; | |
813 } | |
814 } | |
815 | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
816 static gint exif_parse_IFD_entry(ExifData *exif, unsigned char *tiff, guint offset, |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
817 guint size, ExifByteOrder bo, |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
818 gint level, |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
819 const ExifMarker *list) |
9 | 820 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
821 guint tag; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
822 guint format; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
823 guint count; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
824 guint data_val; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
825 guint data_offset; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
826 guint data_length; |
47
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
827 const ExifMarker *marker; |
9 | 828 ExifItem *item; |
829 | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
830 tag = exif_byte_get_int16(tiff + offset + EXIF_TIFD_OFFSET_TAG, bo); |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
831 format = exif_byte_get_int16(tiff + offset + EXIF_TIFD_OFFSET_FORMAT, bo); |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
832 count = exif_byte_get_int32(tiff + offset + EXIF_TIFD_OFFSET_COUNT, bo); |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
833 data_val = exif_byte_get_int32(tiff + offset + EXIF_TIFD_OFFSET_DATA, bo); |
9 | 834 |
835 /* Check tag type. If it does not match, either the format is wrong, | |
836 * either it is a unknown tag; so it is not really an error. | |
837 */ | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
838 marker = exif_marker_from_tag(tag, list); |
9 | 839 if (!marker) |
840 { | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
841 if (format >= EXIF_FORMAT_COUNT) |
9 | 842 { |
673
fbebf5cf4a55
Do not use printf() directly but use new wrapper function log_printf() instead.
zas_
parents:
541
diff
changeset
|
843 log_printf("warning: exif tag 0x%4x has invalid format %d\n", tag, format); |
9 | 844 return 0; |
845 } | |
846 /* allow non recognized tags to be displayed */ | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
847 marker = &ExifUnknownMarkersList[format]; |
9 | 848 } |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
849 if (marker->format != format) |
9 | 850 { |
851 /* Some cameras got mixed up signed/unsigned_rational | |
852 * eg KODAK DC4800 on object_distance tag | |
853 * | |
854 * FIXME: what exactly is this test trying to do? | |
855 * ok, so this test is to allow the case of swapped signed/unsigned mismatch to leak through? | |
856 */ | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
857 if (!(marker->format == EXIF_FORMAT_RATIONAL_UNSIGNED && format == EXIF_FORMAT_RATIONAL) && |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
858 !(marker->format == EXIF_FORMAT_RATIONAL && format == EXIF_FORMAT_RATIONAL_UNSIGNED) && |
9 | 859 /* short fits into a long so allow this mismatch |
860 * as well (some tags allowed to be unsigned short _or_ unsigned long) | |
861 */ | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
862 !(marker->format == EXIF_FORMAT_LONG_UNSIGNED && format == EXIF_FORMAT_SHORT_UNSIGNED) ) |
9 | 863 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
864 if (format < EXIF_FORMAT_COUNT) |
9 | 865 { |
673
fbebf5cf4a55
Do not use printf() directly but use new wrapper function log_printf() instead.
zas_
parents:
541
diff
changeset
|
866 log_printf("warning: exif tag %s format mismatch, found %s exif spec requests %s\n", |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
867 marker->key, ExifFormatList[format].short_name, |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
868 ExifFormatList[marker->format].short_name); |
9 | 869 } |
870 else | |
871 { | |
673
fbebf5cf4a55
Do not use printf() directly but use new wrapper function log_printf() instead.
zas_
parents:
541
diff
changeset
|
872 log_printf("warning: exif tag %s format mismatch, found unknown id %d exif spec requests %d (%s)\n", |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
873 marker->key, format, marker->format, |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
874 ExifFormatList[marker->format].short_name); |
9 | 875 } |
876 return 0; | |
877 } | |
878 } | |
879 | |
880 /* Where is the data, is it available? | |
881 */ | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
882 if (marker->components > 0 && marker->components != count) |
9 | 883 { |
673
fbebf5cf4a55
Do not use printf() directly but use new wrapper function log_printf() instead.
zas_
parents:
541
diff
changeset
|
884 log_printf("warning: exif tag %s has %d elements, exif spec requests %d\n", |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
885 marker->key, count, marker->components); |
9 | 886 } |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
887 |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
888 data_length = ExifFormatList[marker->format].size * count; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
889 if (data_length > 4) |
9 | 890 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
891 data_offset = data_val; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
892 if (size < data_offset + data_length) |
9 | 893 { |
673
fbebf5cf4a55
Do not use printf() directly but use new wrapper function log_printf() instead.
zas_
parents:
541
diff
changeset
|
894 log_printf("warning: exif tag %s data will overrun end of file, ignored.\n", marker->key); |
9 | 895 return -1; |
896 } | |
897 } | |
898 else | |
899 { | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
900 data_offset = offset + EXIF_TIFD_OFFSET_DATA; |
9 | 901 } |
902 | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
903 item = exif_item_new(marker->format, tag, count, marker); |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
904 exif_item_copy_data(item, tiff + data_offset, data_length, format, bo); |
9 | 905 exif->items = g_list_prepend(exif->items, item); |
906 | |
47
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
907 if (list == ExifKnownMarkersList) |
9 | 908 { |
47
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
909 switch (item->tag) |
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
910 { |
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
911 case TAG_EXIFOFFSET: |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
912 exif_parse_IFD_table(exif, tiff, data_val, size, bo, level + 1, list); |
47
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
913 break; |
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
914 case TAG_EXIFMAKERNOTE: |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
915 format_exif_makernote_parse(exif, tiff, data_val, size, bo); |
47
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
916 break; |
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
917 } |
9 | 918 } |
919 | |
920 return 0; | |
921 } | |
922 | |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
923 gint exif_parse_IFD_table(ExifData *exif, |
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
924 unsigned char *tiff, guint offset, |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
925 guint size, ExifByteOrder bo, |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
926 gint level, |
51
276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
47
diff
changeset
|
927 const ExifMarker *list) |
9 | 928 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
929 guint count; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
930 guint i; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
931 |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
932 /* limit damage from infinite loops */ |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
933 if (level > EXIF_TIFF_MAX_LEVELS) return -1; |
9 | 934 |
935 /* We should be able to read number of entries in IFD0) */ | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
936 if (size < offset + 2) return -1; |
9 | 937 |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
938 count = exif_byte_get_int16(tiff + offset, bo); |
57
a8c9992320f4
Fri Jun 10 20:57:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
55
diff
changeset
|
939 offset += 2; |
9 | 940 |
941 /* Entries and next IFD offset must be readable */ | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
942 if (size < offset + count * EXIF_TIFD_SIZE + 4) return -1; |
9 | 943 |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
944 for (i = 0; i < count; i++) |
9 | 945 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
946 exif_parse_IFD_entry(exif, tiff, offset + i * EXIF_TIFD_SIZE, size, bo, level, list); |
9 | 947 } |
948 | |
949 return 0; | |
950 } | |
951 | |
952 /* | |
953 *------------------------------------------------------------------- | |
954 * file formats | |
955 *------------------------------------------------------------------- | |
956 */ | |
957 | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
958 gint exif_tiff_directory_offset(unsigned char *data, const guint len, |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
959 guint *offset, ExifByteOrder *bo) |
9 | 960 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
961 if (len < 8) return FALSE; |
9 | 962 |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
963 if (memcmp(data, "II", 2) == 0) |
9 | 964 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
965 *bo = EXIF_BYTE_ORDER_INTEL; |
9 | 966 } |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
967 else if (memcmp(data, "MM", 2) == 0) |
9 | 968 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
969 *bo = EXIF_BYTE_ORDER_MOTOROLA; |
9 | 970 } |
971 else | |
972 { | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
973 return FALSE; |
9 | 974 } |
975 | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
976 if (exif_byte_get_int16(data + 2, *bo) != 0x002A) |
9 | 977 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
978 return FALSE; |
9 | 979 } |
980 | |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
981 *offset = exif_byte_get_int32(data + 4, *bo); |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
982 |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
983 return (*offset < len); |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
984 } |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
985 |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
986 gint exif_tiff_parse(ExifData *exif, unsigned char *tiff, guint size, ExifMarker *list) |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
987 { |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
988 ExifByteOrder bo; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
989 guint offset; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
990 |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
991 if (!exif_tiff_directory_offset(tiff, size, &offset, &bo)) return -1; |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
992 |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
993 return exif_parse_IFD_table(exif, tiff, offset, size, bo, 0, list); |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
994 } |
9 | 995 |
449 | 996 |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
997 /* |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
998 *------------------------------------------------------------------- |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
999 * jpeg marker utils |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1000 *------------------------------------------------------------------- |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1001 */ |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1002 |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1003 #define JPEG_MARKER 0xFF |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1004 #define JPEG_MARKER_SOI 0xD8 |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1005 #define JPEG_MARKER_EOI 0xD9 |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1006 #define JPEG_MARKER_APP1 0xE1 |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1007 #define JPEG_MARKER_APP2 0xE2 |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1008 |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1009 /* jpeg container format: |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1010 all data markers start with 0XFF |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1011 2 byte long file start and end markers: 0xFFD8(SOI) and 0XFFD9(EOI) |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1012 4 byte long data segment markers in format: 0xFFTTSSSSNNN... |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1013 FF: 1 byte standard marker identifier |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1014 TT: 1 byte data type |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1015 SSSS: 2 bytes in Motorola byte alignment for length of the data. |
442 | 1016 This value includes these 2 bytes in the count, making actual |
1017 length of NN... == SSSS - 2. | |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1018 NNN.: the data in this segment |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1019 */ |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
192
diff
changeset
|
1020 static ExifMarker jpeg_color_marker = { 0x8773, EXIF_FORMAT_UNDEFINED, -1, "Exif.Image.InterColorProfile", NULL, NULL }; |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1021 |
449 | 1022 void exif_add_jpeg_color_profile(ExifData *exif, unsigned char *cp_data, guint cp_length) |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1023 { |
449 | 1024 ExifItem *item = exif_item_new(jpeg_color_marker.format, jpeg_color_marker.tag, 1, |
1025 &jpeg_color_marker); | |
1026 g_free(item->data); | |
1027 item->data = cp_data; | |
1028 item->elements = cp_length; | |
1029 item->data_len = cp_length; | |
1030 exif->items = g_list_prepend(exif->items, item); | |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1031 |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1032 } |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1033 |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1034 static gint exif_jpeg_parse(ExifData *exif, |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1035 unsigned char *data, guint size, |
449 | 1036 ExifMarker *list) |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1037 { |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1038 guint seg_offset = 0; |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1039 guint seg_length = 0; |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1040 gint res = -1; |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1041 |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1042 if (size < 4 || |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1043 memcmp(data, "\xFF\xD8", 2) != 0) |
9 | 1044 { |
1045 return -2; | |
1046 } | |
1047 | |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1048 if (exif_jpeg_segment_find(data, size, JPEG_MARKER_APP1, |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1049 "Exif\x00\x00", 6, |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1050 &seg_offset, &seg_length)) |
9 | 1051 { |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1052 res = exif_tiff_parse(exif, data + seg_offset + 6, seg_length - 6, list); |
9 | 1053 } |
1054 | |
449 | 1055 if (exif_jpeg_parse_color(exif, data, size)) |
9 | 1056 { |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1057 res = 0; |
9 | 1058 } |
1059 | |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1060 return res; |
9 | 1061 } |
1062 | |
449 | 1063 unsigned char *exif_get_color_profile(ExifData *exif, guint *data_len) |
1064 { | |
1065 ExifItem *prof_item = exif_get_item(exif, "Exif.Image.InterColorProfile"); | |
1066 if (prof_item && exif_item_get_format_id(prof_item) == EXIF_FORMAT_UNDEFINED) | |
1067 return (unsigned char*) exif_item_get_data(prof_item, data_len); | |
1068 return NULL; | |
1069 } | |
1070 | |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1071 |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1072 /* |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1073 *------------------------------------------------------------------- |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1074 * misc |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1075 *------------------------------------------------------------------- |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1076 */ |
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1077 |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1078 |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1079 ExifItem *exif_get_first_item(ExifData *exif) |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1080 { |
442 | 1081 if (exif->items) |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1082 { |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1083 ExifItem *ret = (ExifItem *)exif->items->data; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1084 exif->current = exif->items->next; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1085 return ret; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1086 } |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1087 exif->current = NULL; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1088 return NULL; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1089 } |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1090 |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1091 ExifItem *exif_get_next_item(ExifData *exif) |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1092 { |
442 | 1093 if (exif->current) |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1094 { |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1095 ExifItem *ret = (ExifItem *)exif->current->data; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1096 exif->current = exif->current->next; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1097 return ret; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1098 } |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1099 return NULL; |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1100 } |
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1101 |
9 | 1102 static gint map_file(const gchar *path, void **mapping, int *size) |
1103 { | |
1104 int fd; | |
1105 struct stat fs; | |
1106 | |
1107 if ((fd = open(path, O_RDONLY)) == -1) | |
1108 { | |
1109 perror(path); | |
1110 return -1; | |
1111 } | |
1112 | |
1113 if (fstat(fd, &fs) == -1) | |
1114 { | |
1115 perror(path); | |
1116 close(fd); | |
1117 return -1; | |
1118 } | |
1119 | |
1120 *size = fs.st_size; | |
1121 | |
1122 if ((*mapping = mmap(0, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0)) == MAP_FAILED) | |
1123 { | |
1124 perror(path); | |
1125 close(fd); | |
1126 return -1; | |
1127 } | |
1128 | |
1129 close(fd); | |
1130 return 0; | |
1131 } | |
1132 | |
1133 static gint unmap_file(void *mapping, int size) | |
1134 { | |
1135 if (munmap(mapping, size) == -1) | |
1136 { | |
1137 perror("munmap"); | |
1138 return -1; | |
1139 } | |
1140 | |
1141 return 0; | |
1142 } | |
1143 | |
1144 void exif_free(ExifData *exif) | |
1145 { | |
1146 GList *work; | |
1147 | |
1148 if (!exif) return; | |
1149 | |
1150 work = exif->items; | |
1151 while (work) | |
1152 { | |
1153 ExifItem *item = work->data; | |
1154 work = work->next; | |
1155 exif_item_free(item); | |
1156 } | |
1157 | |
1158 g_list_free(exif->items); | |
1159 g_free(exif); | |
1160 } | |
1161 | |
449 | 1162 ExifData *exif_read(gchar *path, gchar *sidecar_path) |
9 | 1163 { |
1164 ExifData *exif; | |
1165 void *f; | |
1166 int size, res; | |
1167 gchar *pathl; | |
1168 | |
182 | 1169 if (!path) return NULL; |
9 | 1170 |
177 | 1171 pathl = path_from_utf8(path); |
9 | 1172 if (map_file(pathl, &f, &size) == -1) |
1173 { | |
1174 g_free(pathl); | |
1175 return NULL; | |
1176 } | |
1177 g_free(pathl); | |
1178 | |
1179 exif = g_new0(ExifData, 1); | |
1180 exif->items = NULL; | |
176
695e1ad3b169
simplified exif.h, moved implementation-specific stuff to exif-int.h
nadvornik
parents:
138
diff
changeset
|
1181 exif->current = NULL; |
9 | 1182 |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1183 if ((res = exif_jpeg_parse(exif, (unsigned char *)f, size, |
449 | 1184 ExifKnownMarkersList)) == -2) |
9 | 1185 { |
54
b58cac75ad12
Thu Jun 9 22:23:18 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
1186 res = exif_tiff_parse(exif, (unsigned char *)f, size, ExifKnownMarkersList); |
9 | 1187 } |
1188 | |
1189 if (res != 0) | |
1190 { | |
101
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1191 FormatRawExifType exif_type; |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1192 FormatRawExifParseFunc exif_parse_func; |
43
ee03f36e9e4b
Sun May 15 21:40:26 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1193 guint32 offset = 0; |
101
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1194 |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1195 exif_type = format_raw_exif_offset(f, size, &offset, &exif_parse_func); |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1196 switch (exif_type) |
43
ee03f36e9e4b
Sun May 15 21:40:26 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1197 { |
101
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1198 case FORMAT_RAW_EXIF_NONE: |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1199 default: |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1200 break; |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1201 case FORMAT_RAW_EXIF_TIFF: |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1202 res = exif_tiff_parse(exif, (unsigned char*)f + offset, size - offset, |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1203 ExifKnownMarkersList); |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1204 break; |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1205 case FORMAT_RAW_EXIF_JPEG: |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1206 res = exif_jpeg_parse(exif, (unsigned char*)f + offset, size - offset, |
449 | 1207 ExifKnownMarkersList); |
101
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1208 break; |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1209 case FORMAT_RAW_EXIF_IFD_II: |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1210 case FORMAT_RAW_EXIF_IFD_MM: |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1211 res = exif_parse_IFD_table(exif, (unsigned char*)f, offset, size - offset, |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1212 (exif_type == FORMAT_RAW_EXIF_IFD_II) ? |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1213 EXIF_BYTE_ORDER_INTEL : EXIF_BYTE_ORDER_MOTOROLA, |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1214 0, ExifKnownMarkersList); |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1215 break; |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1216 case FORMAT_RAW_EXIF_PROPRIETARY: |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1217 if (exif_parse_func) |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1218 { |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1219 res = exif_parse_func((unsigned char*)f + offset, size - offset, exif); |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1220 } |
847e4bc6b54c
Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1221 break; |
43
ee03f36e9e4b
Sun May 15 21:40:26 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1222 } |
ee03f36e9e4b
Sun May 15 21:40:26 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1223 } |
ee03f36e9e4b
Sun May 15 21:40:26 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1224 |
ee03f36e9e4b
Sun May 15 21:40:26 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1225 if (res != 0) |
ee03f36e9e4b
Sun May 15 21:40:26 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1226 { |
9 | 1227 exif_free(exif); |
1228 exif = NULL; | |
1229 } | |
1230 | |
1231 unmap_file(f, size); | |
1232 | |
1233 if (exif) exif->items = g_list_reverse(exif->items); | |
1234 | |
1235 #if 0 | |
1236 exif_write_data_list(exif, stdout, TRUE); | |
1237 exif_write_data_list(exif, stdout, FALSE); | |
1238 #endif | |
1239 | |
1240 return exif; | |
1241 } | |
1242 | |
1243 ExifItem *exif_get_item(ExifData *exif, const gchar *key) | |
1244 { | |
1245 GList *work; | |
1246 | |
1247 if (!key) return NULL; | |
1248 | |
1249 work = exif->items; | |
1250 while (work) | |
1251 { | |
1252 ExifItem *item; | |
1253 | |
1254 item = work->data; | |
1255 work = work->next; | |
1256 if (item->marker->key && strcmp(key, item->marker->key) == 0) return item; | |
442 | 1257 } |
9 | 1258 return NULL; |
1259 } | |
1260 | |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1261 #define EXIF_DATA_AS_TEXT_MAX_COUNT 16 |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1262 |
192 | 1263 gchar *exif_item_get_string(ExifItem *item, int idx) |
1264 { | |
1265 return exif_item_get_data_as_text(item); | |
1266 } | |
1267 | |
1268 | |
9 | 1269 gchar *exif_item_get_data_as_text(ExifItem *item) |
1270 { | |
47
aa4c0e1b54b0
Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net>
gqview
parents:
45
diff
changeset
|
1271 const ExifMarker *marker; |
9 | 1272 gpointer data; |
1273 GString *string; | |
1274 gchar *text; | |
1275 gint ne; | |
1276 gint i; | |
1277 | |
1278 if (!item) return NULL; | |
1279 | |
1280 marker = item->marker; | |
1281 if (!marker) return NULL; | |
1282 | |
1283 data = item->data; | |
1284 ne = item->elements; | |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1285 if (ne > EXIF_DATA_AS_TEXT_MAX_COUNT) ne = EXIF_DATA_AS_TEXT_MAX_COUNT; |
9 | 1286 string = g_string_new(""); |
1287 switch (item->format) | |
1288 { | |
1289 case EXIF_FORMAT_UNKNOWN: | |
1290 break; | |
1291 case EXIF_FORMAT_BYTE_UNSIGNED: | |
1292 case EXIF_FORMAT_BYTE: | |
1293 case EXIF_FORMAT_UNDEFINED: | |
1294 if (ne == 1 && marker->list) | |
1295 { | |
1296 gchar *result; | |
1297 unsigned char val; | |
1298 | |
1299 if (item->format == EXIF_FORMAT_BYTE_UNSIGNED || | |
1300 item->format == EXIF_FORMAT_UNDEFINED) | |
1301 { | |
1302 val = ((unsigned char *)data)[0]; | |
1303 } | |
1304 else | |
1305 { | |
1306 val = (unsigned char)(((signed char *)data)[0]); | |
1307 } | |
1308 | |
57
a8c9992320f4
Fri Jun 10 20:57:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
55
diff
changeset
|
1309 result = exif_text_list_find_value(marker->list, (guint)val); |
9 | 1310 string = g_string_append(string, result); |
1311 g_free(result); | |
1312 } | |
1313 else | |
1314 { | |
1315 string = string_append_raw_bytes(string, data, ne); | |
1316 } | |
1317 break; | |
1318 case EXIF_FORMAT_STRING: | |
1319 string = g_string_append(string, (gchar *)(item->data)); | |
1320 break; | |
1321 case EXIF_FORMAT_SHORT_UNSIGNED: | |
1322 if (ne == 1 && marker->list) | |
1323 { | |
1324 gchar *result; | |
1325 | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
1326 result = exif_text_list_find_value(marker->list, ((guint16 *)data)[0]); |
9 | 1327 string = g_string_append(string, result); |
1328 g_free(result); | |
1329 } | |
1330 else for (i = 0; i < ne; i++) | |
1331 { | |
1332 g_string_append_printf(string, "%s%hd", (i > 0) ? ", " : "", | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
1333 ((guint16 *)data)[i]); |
9 | 1334 } |
1335 break; | |
1336 case EXIF_FORMAT_LONG_UNSIGNED: | |
1337 for (i = 0; i < ne; i++) | |
1338 { | |
1339 g_string_append_printf(string, "%s%ld", (i > 0) ? ", " : "", | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
1340 (unsigned long int)((guint32 *)data)[i]); |
9 | 1341 } |
1342 break; | |
1343 case EXIF_FORMAT_RATIONAL_UNSIGNED: | |
1344 for (i = 0; i < ne; i++) | |
1345 { | |
1346 ExifRational *r; | |
1347 | |
1348 r = &((ExifRational *)data)[i]; | |
1349 g_string_append_printf(string, "%s%ld/%ld", (i > 0) ? ", " : "", | |
1350 (unsigned long)r->num, (unsigned long)r->den); | |
1351 } | |
1352 break; | |
1353 case EXIF_FORMAT_SHORT: | |
1354 for (i = 0; i < ne; i++) | |
1355 { | |
1356 g_string_append_printf(string, "%s%hd", (i > 0) ? ", " : "", | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
1357 ((gint16 *)data)[i]); |
9 | 1358 } |
1359 break; | |
1360 case EXIF_FORMAT_LONG: | |
1361 for (i = 0; i < ne; i++) | |
1362 { | |
1363 g_string_append_printf(string, "%s%ld", (i > 0) ? ", " : "", | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
1364 (long int)((gint32 *)data)[i]); |
9 | 1365 } |
1366 break; | |
1367 case EXIF_FORMAT_RATIONAL: | |
1368 for (i = 0; i < ne; i++) | |
1369 { | |
1370 ExifRational *r; | |
1371 | |
1372 r = &((ExifRational *)data)[i]; | |
1373 g_string_append_printf(string, "%s%ld/%ld", (i > 0) ? ", " : "", | |
1374 (long)r->num, (long)r->den); | |
1375 } | |
1376 break; | |
1377 case EXIF_FORMAT_FLOAT: | |
1378 for (i = 0; i < ne; i++) | |
1379 { | |
1380 g_string_append_printf(string, "%s%f", (i > 0) ? ", " : "", | |
1381 ((float *)data)[i]); | |
1382 } | |
1383 break; | |
1384 case EXIF_FORMAT_DOUBLE: | |
1385 for (i = 0; i < ne; i++) | |
1386 { | |
1387 g_string_append_printf(string, "%s%f", (i > 0) ? ", " : "", | |
1388 ((double *)data)[i]); | |
1389 } | |
1390 break; | |
1391 } | |
1392 | |
114
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1393 if (item->elements > EXIF_DATA_AS_TEXT_MAX_COUNT && |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1394 item->format != EXIF_FORMAT_STRING) |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1395 { |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1396 g_string_append(string, " ..."); |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1397 } |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1398 |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1399 text = string->str; |
50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
gqview
parents:
110
diff
changeset
|
1400 g_string_free(string, FALSE); |
9 | 1401 |
1402 return text; | |
1403 } | |
1404 | |
1405 gint exif_item_get_integer(ExifItem *item, gint *value) | |
1406 { | |
1407 if (!item) return FALSE; | |
1408 | |
1409 switch (item->format) | |
1410 { | |
1411 case EXIF_FORMAT_SHORT: | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
1412 *value = (gint)(((gint16 *)(item->data))[0]); |
9 | 1413 return TRUE; |
1414 break; | |
1415 case EXIF_FORMAT_SHORT_UNSIGNED: | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
1416 *value = (gint)(((guint16 *)(item->data))[0]); |
9 | 1417 return TRUE; |
1418 break; | |
1419 case EXIF_FORMAT_LONG: | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
1420 *value = (gint)(((gint32 *)(item->data))[0]); |
9 | 1421 return TRUE; |
1422 break; | |
1423 case EXIF_FORMAT_LONG_UNSIGNED: | |
1424 /* FIXME: overflow possible */ | |
110
9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
gqview
parents:
107
diff
changeset
|
1425 *value = (gint)(((guint32 *)(item->data))[0]); |
9 | 1426 return TRUE; |
1427 default: | |
1428 /* all other type return FALSE */ | |
1429 break; | |
1430 } | |
1431 return FALSE; | |
1432 } | |
1433 | |
1434 | |
1435 ExifRational *exif_item_get_rational(ExifItem *item, gint *sign) | |
1436 { | |
1437 if (!item) return NULL; | |
1438 | |
1439 if (item->format == EXIF_FORMAT_RATIONAL || | |
1440 item->format == EXIF_FORMAT_RATIONAL_UNSIGNED) | |
1441 { | |
1442 if (sign) *sign = (item->format == EXIF_FORMAT_RATIONAL); | |
1443 return &((ExifRational *)(item->data))[0]; | |
1444 } | |
1445 | |
1446 return NULL; | |
1447 } | |
1448 | |
182 | 1449 const gchar *exif_get_tag_description_by_key(const gchar *key) |
9 | 1450 { |
1451 gint i; | |
1452 | |
1453 if (!key) return NULL; | |
1454 | |
1455 i = 0; | |
1456 while (ExifKnownMarkersList[i].tag > 0) | |
1457 { | |
1458 if (strcmp(key, ExifKnownMarkersList[i].key) == 0) return _(ExifKnownMarkersList[i].description); | |
1459 i++; | |
1460 } | |
1461 | |
1462 return NULL; | |
1463 } | |
1464 | |
1465 static void exif_write_item(FILE *f, ExifItem *item) | |
1466 { | |
1467 gchar *text; | |
1468 | |
1469 text = exif_item_get_data_as_text(item); | |
1470 if (text) | |
1471 { | |
185 | 1472 gchar *tag = exif_item_get_tag_name(item); |
9 | 1473 fprintf(f, "%4x %9s %30s %s\n", item->tag, ExifFormatList[item->format].short_name, |
185 | 1474 tag, text); |
1475 g_free(tag); | |
9 | 1476 } |
1477 g_free(text); | |
1478 } | |
1479 | |
1480 void exif_write_data_list(ExifData *exif, FILE *f, gint human_readable_list) | |
1481 { | |
1482 if (!f || !exif) return; | |
1483 | |
1484 fprintf(f, " tag format key value\n"); | |
1485 fprintf(f, "----------------------------------------------------\n"); | |
1486 | |
1487 if (human_readable_list) | |
1488 { | |
1489 gint i; | |
1490 | |
1491 i = 0; | |
1492 while (ExifFormattedList[i].key) | |
1493 { | |
1494 gchar *text; | |
1495 | |
1496 text = exif_get_formatted_by_key(exif, ExifFormattedList[i].key, NULL); | |
1497 if (text) | |
1498 { | |
1499 fprintf(f, " %9s %30s %s\n", "string", ExifFormattedList[i].key, text); | |
1500 } | |
1501 i++; | |
1502 } | |
1503 } | |
1504 else | |
1505 { | |
1506 GList *work; | |
1507 | |
1508 work = exif->items; | |
1509 while (work) | |
1510 { | |
1511 ExifItem *item; | |
1512 | |
1513 item = work->data; | |
1514 work = work->next; | |
1515 | |
1516 exif_write_item(f, item); | |
1517 } | |
1518 } | |
1519 fprintf(f, "----------------------------------------------------\n"); | |
1520 } | |
1521 | |
187
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1522 int exif_write(ExifData *exif) |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1523 { |
673
fbebf5cf4a55
Do not use printf() directly but use new wrapper function log_printf() instead.
zas_
parents:
541
diff
changeset
|
1524 log_printf("Not compiled with EXIF write support"); |
187
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1525 return 0; |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1526 } |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1527 |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1528 ExifItem *exif_add_item(ExifData *exif, const gchar *key) |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1529 { |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1530 return NULL; |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1531 } |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1532 |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1533 int exif_item_delete(ExifData *exif, ExifItem *item) |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1534 { |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1535 return 0; |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1536 } |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1537 |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1538 int exif_item_set_string(ExifItem *item, const char *str) |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1539 { |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1540 return 0; |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1541 } |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1542 |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1543 |
9eafc4957f1a
write support in Exiv2 wrapper; for now only string values
nadvornik
parents:
185
diff
changeset
|
1544 |
442 | 1545 #endif |
177 | 1546 /* not HAVE_EXIV2 */ |