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