1 /* -*- C++ -*-
2 * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
3 *
4 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
5 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
6 LibRaw do not use RESTRICTED code from dcraw.c
7
8 LibRaw is free software; you can redistribute it and/or modify
9 it under the terms of the one of two licenses as you choose:
10
11 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12 (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13
14 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15 (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16
17 */
18
19 #include "../../internal/dcraw_defs.h"
20 #include "../../internal/libraw_cameraids.h"
21
parse_exif_interop(int base)22 void LibRaw::parse_exif_interop(int base)
23 {
24 unsigned entries, tag, type, len, save;
25 char value[4] = { 0,0,0,0 };
26 entries = get2();
27 INT64 fsize = ifp->size();
28 while (entries--)
29 {
30 tiff_get(base, &tag, &type, &len, &save);
31
32 INT64 savepos = ftell(ifp);
33 if (len > 8 && savepos + len > fsize * 2)
34 {
35 fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
36 continue;
37 }
38 if (callbacks.exif_cb)
39 {
40 callbacks.exif_cb(callbacks.exifparser_data, tag | 0x40000, type, len, order, ifp, base);
41 fseek(ifp, savepos, SEEK_SET);
42 }
43
44 switch (tag)
45 {
46 case 0x0001: // InteropIndex
47 fread(value, 1, MIN(4, len), ifp);
48 if (strncmp(value, "R98", 3) == 0 &&
49 // Canon bug, when [Canon].ColorSpace = AdobeRGB,
50 // but [ExifIFD].ColorSpace = Uncalibrated and
51 // [InteropIFD].InteropIndex = "R98"
52 imgdata.color.ExifColorSpace == LIBRAW_COLORSPACE_Unknown)
53 imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_sRGB;
54 else if (strncmp(value, "R03", 3) == 0)
55 imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
56 break;
57 }
58 fseek(ifp, save, SEEK_SET);
59 }
60 }
61
parse_exif(int base)62 void LibRaw::parse_exif(int base)
63 {
64 unsigned entries, tag, type, len, save, c;
65 double expo, ape;
66
67 unsigned kodak = !strncmp(make, "EASTMAN", 7) && tiff_nifds < 3;
68
69 if (!libraw_internal_data.unpacker_data.exif_offset)
70 libraw_internal_data.unpacker_data.exif_offset = base;
71
72 entries = get2();
73 if (!strncmp(make, "Hasselblad", 10) && (tiff_nifds > 3) && (entries > 512))
74 return;
75 INT64 fsize = ifp->size();
76 while (entries--)
77 {
78 tiff_get(base, &tag, &type, &len, &save);
79
80 INT64 savepos = ftell(ifp);
81 if (len > 8 && savepos + len > fsize * 2)
82 {
83 fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
84 continue;
85 }
86 if (callbacks.exif_cb)
87 {
88 callbacks.exif_cb(callbacks.exifparser_data, tag, type, len, order, ifp,
89 base);
90 fseek(ifp, savepos, SEEK_SET);
91 }
92
93 switch (tag)
94 {
95 case 0xA005: // Interoperability IFD
96 fseek(ifp, get4() + base, SEEK_SET);
97 parse_exif_interop(base);
98 break;
99 case 0xA001: // ExifIFD.ColorSpace
100 c = get2();
101 if (c == 1 && imgdata.color.ExifColorSpace == LIBRAW_COLORSPACE_Unknown)
102 imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_sRGB;
103 else if (c == 2)
104 imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
105 break;
106 case 0x9400:
107 imCommon.exifAmbientTemperature = getreal(type);
108 if ((imCommon.CameraTemperature > -273.15f) &&
109 ((OlyID == OlyID_TG_5) ||
110 (OlyID == OlyID_TG_6))
111 )
112 imCommon.CameraTemperature += imCommon.exifAmbientTemperature;
113 break;
114 case 0x9401:
115 imCommon.exifHumidity = getreal(type);
116 break;
117 case 0x9402:
118 imCommon.exifPressure = getreal(type);
119 break;
120 case 0x9403:
121 imCommon.exifWaterDepth = getreal(type);
122 break;
123 case 0x9404:
124 imCommon.exifAcceleration = getreal(type);
125 break;
126 case 0x9405:
127 imCommon.exifCameraElevationAngle = getreal(type);
128 break;
129
130 case 0xa405: // FocalLengthIn35mmFormat
131 imgdata.lens.FocalLengthIn35mmFormat = get2();
132 break;
133 case 0xa431: // BodySerialNumber
134 stmread(imgdata.shootinginfo.BodySerial, len, ifp);
135 break;
136 case 0xa432: // LensInfo, 42034dec, Lens Specification per EXIF standard
137 imgdata.lens.MinFocal = getreal(type);
138 imgdata.lens.MaxFocal = getreal(type);
139 imgdata.lens.MaxAp4MinFocal = getreal(type);
140 imgdata.lens.MaxAp4MaxFocal = getreal(type);
141 break;
142 case 0xa435: // LensSerialNumber
143 stmread(imgdata.lens.LensSerial, len, ifp);
144 if (!strncmp(imgdata.lens.LensSerial, "----", 4))
145 imgdata.lens.LensSerial[0] = '\0';
146 break;
147 case 0xa420: /* 42016, ImageUniqueID */
148 stmread(imgdata.color.ImageUniqueID, len, ifp);
149 break;
150 case 0xc65d: /* 50781, RawDataUniqueID */
151 imgdata.color.RawDataUniqueID[16] = 0;
152 fread(imgdata.color.RawDataUniqueID, 1, 16, ifp);
153 break;
154 case 0xc630: // DNG LensInfo, Lens Specification per EXIF standard
155 imgdata.lens.dng.MinFocal = getreal(type);
156 imgdata.lens.dng.MaxFocal = getreal(type);
157 imgdata.lens.dng.MaxAp4MinFocal = getreal(type);
158 imgdata.lens.dng.MaxAp4MaxFocal = getreal(type);
159 break;
160 case 0xc68b: /* 50827, OriginalRawFileName */
161 stmread(imgdata.color.OriginalRawFileName, len, ifp);
162 break;
163 case 0xa433: // LensMake
164 stmread(imgdata.lens.LensMake, len, ifp);
165 break;
166 case 0xa434: // LensModel
167 stmread(imgdata.lens.Lens, len, ifp);
168 if (!strncmp(imgdata.lens.Lens, "----", 4))
169 imgdata.lens.Lens[0] = '\0';
170 break;
171 case 0x9205:
172 imgdata.lens.EXIF_MaxAp = libraw_powf64l(2.0f, (getreal(type) / 2.0f));
173 break;
174 case 0x829a: // 33434
175 shutter = getreal(type);
176 if (tiff_nifds > 0 && tiff_nifds <= LIBRAW_IFD_MAXCOUNT)
177 tiff_ifd[tiff_nifds - 1].t_shutter = shutter;
178 break;
179 case 0x829d: // 33437, FNumber
180 aperture = getreal(type);
181 break;
182 case 0x8827: // 34855
183 iso_speed = get2();
184 break;
185 case 0x8831: // 34865
186 if (iso_speed == 0xffff && !strncasecmp(make, "FUJI", 4))
187 iso_speed = getreal(type);
188 break;
189 case 0x8832: // 34866
190 if (iso_speed == 0xffff &&
191 (!strncasecmp(make, "SONY", 4) || !strncasecmp(make, "CANON", 5)))
192 iso_speed = getreal(type);
193 break;
194 case 0x9003: // 36867
195 case 0x9004: // 36868
196 get_timestamp(0);
197 break;
198 case 0x9201: // 37377
199 if ((expo = -getreal(type)) < 128 && shutter == 0.)
200 {
201 shutter = libraw_powf64l(2.0, expo);
202 if (tiff_nifds > 0 && tiff_nifds <= LIBRAW_IFD_MAXCOUNT)
203 tiff_ifd[tiff_nifds - 1].t_shutter = shutter;
204 }
205 break;
206 case 0x9202: // 37378 ApertureValue
207 if ((fabs(ape = getreal(type)) < 256.0) && (!aperture))
208 aperture = libraw_powf64l(2.0, ape / 2);
209 break;
210 case 0x9209: // 37385
211 flash_used = getreal(type);
212 break;
213 case 0x920a: // 37386
214 focal_len = getreal(type);
215 break;
216 case 0x927c: // 37500
217 #ifndef USE_6BY9RPI
218 if (((make[0] == '\0') && !strncmp(model, "ov5647", 6)) ||
219 (!strncmp(make, "RaspberryPi", 11) &&
220 (!strncmp(model, "RP_OV5647", 9) ||
221 !strncmp(model, "RP_imx219", 9))))
222 #else
223 if (((make[0] == '\0') && !strncmp(model, "ov5647", 6)) ||
224 (!strncmp(make, "RaspberryPi", 11) &&
225 (!strncmp(model, "RP_", 3) || !strncmp(model,"imx477",6))))
226 #endif
227 {
228 char mn_text[512];
229 char *pos;
230 char ccms[512];
231 ushort l;
232 float num;
233
234 fgets(mn_text, MIN(len, 511), ifp);
235 mn_text[511] = 0;
236
237 pos = strstr(mn_text, "ev=");
238 if (pos)
239 imCommon.ExposureCalibrationShift = atof(pos + 3);
240
241 pos = strstr(mn_text, "gain_r=");
242 if (pos)
243 cam_mul[0] = atof(pos + 7);
244 pos = strstr(mn_text, "gain_b=");
245 if (pos)
246 cam_mul[2] = atof(pos + 7);
247 if ((cam_mul[0] > 0.001f) && (cam_mul[2] > 0.001f))
248 cam_mul[1] = cam_mul[3] = 1.0f;
249 else
250 cam_mul[0] = cam_mul[2] = 0.0f;
251
252 pos = strstr(mn_text, "ccm=");
253 if (pos)
254 {
255 pos += 4;
256 char *pos2 = strstr(pos, " ");
257 if (pos2)
258 {
259 l = pos2 - pos;
260 memcpy(ccms, pos, l);
261 ccms[l] = '\0';
262 #ifdef LIBRAW_WIN32_CALLS
263 // Win32 strtok is already thread-safe
264 pos = strtok(ccms, ",");
265 #else
266 char *last = 0;
267 pos = strtok_r(ccms, ",", &last);
268 #endif
269 if (pos)
270 {
271 for (l = 0; l < 3; l++) // skip last row
272 {
273 num = 0.0;
274 for (c = 0; c < 3; c++)
275 {
276 cmatrix[l][c] = (float)atoi(pos);
277 num += cmatrix[c][l];
278 #ifdef LIBRAW_WIN32_CALLS
279 pos = strtok(NULL, ",");
280 #else
281 pos = strtok_r(NULL, ",", &last);
282 #endif
283 if (!pos)
284 goto end; // broken
285 }
286 if (num > 0.01)
287 FORC3 cmatrix[l][c] = cmatrix[l][c] / num;
288 }
289 }
290 }
291 }
292 end:;
293 }
294 else if (!strncmp(make, "SONY", 4) &&
295 (!strncmp(model, "DSC-V3", 6) || !strncmp(model, "DSC-F828", 8)))
296 {
297 parseSonySRF(len);
298 break;
299 }
300 else if ((len == 1) && !strncmp(make, "NIKON", 5))
301 {
302 c = get4();
303 if (c)
304 fseek(ifp, c, SEEK_SET);
305 is_NikonTransfer = 1;
306 }
307 parse_makernote(base, 0);
308 break;
309 case 0xa002: // 40962
310 if (kodak)
311 raw_width = get4();
312 break;
313 case 0xa003: // 40963
314 if (kodak)
315 raw_height = get4();
316 break;
317 case 0xa302: // 41730
318 if (get4() == 0x20002)
319 for (exif_cfa = c = 0; c < 8; c += 2)
320 exif_cfa |= fgetc(ifp) * 0x01010101U << c;
321 }
322 fseek(ifp, save, SEEK_SET);
323 }
324 }
325
parse_gps_libraw(int base)326 void LibRaw::parse_gps_libraw(int base)
327 {
328 unsigned entries, tag, type, len, save, c;
329
330 entries = get2();
331 if (entries > 40)
332 return;
333 if (entries > 0)
334 imgdata.other.parsed_gps.gpsparsed = 1;
335 INT64 fsize = ifp->size();
336 while (entries--)
337 {
338 tiff_get(base, &tag, &type, &len, &save);
339 if (len > 1024)
340 {
341 fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
342 continue; // no GPS tags are 1k or larger
343 }
344 INT64 savepos = ftell(ifp);
345 if (len > 8 && savepos + len > fsize * 2)
346 {
347 fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
348 continue;
349 }
350
351 if (callbacks.exif_cb)
352 {
353 callbacks.exif_cb(callbacks.exifparser_data, tag | 0x50000, type, len, order, ifp, base);
354 fseek(ifp, savepos, SEEK_SET);
355 }
356
357 switch (tag)
358 {
359 case 0x0001:
360 imgdata.other.parsed_gps.latref = getc(ifp);
361 break;
362 case 0x0003:
363 imgdata.other.parsed_gps.longref = getc(ifp);
364 break;
365 case 0x0005:
366 imgdata.other.parsed_gps.altref = getc(ifp);
367 break;
368 case 0x0002:
369 if (len == 3)
370 FORC(3) imgdata.other.parsed_gps.latitude[c] = getreal(type);
371 break;
372 case 0x0004:
373 if (len == 3)
374 FORC(3) imgdata.other.parsed_gps.longitude[c] = getreal(type);
375 break;
376 case 0x0007:
377 if (len == 3)
378 FORC(3) imgdata.other.parsed_gps.gpstimestamp[c] = getreal(type);
379 break;
380 case 0x0006:
381 imgdata.other.parsed_gps.altitude = getreal(type);
382 break;
383 case 0x0009:
384 imgdata.other.parsed_gps.gpsstatus = getc(ifp);
385 break;
386 }
387 fseek(ifp, save, SEEK_SET);
388 }
389 }
390
parse_gps(int base)391 void LibRaw::parse_gps(int base)
392 {
393 unsigned entries, tag, type, len, save, c;
394
395 entries = get2();
396 if (entries > 40)
397 return;
398 while (entries--)
399 {
400 tiff_get(base, &tag, &type, &len, &save);
401 if (len > 1024)
402 {
403 fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
404 continue; // no GPS tags are 1k or larger
405 }
406 switch (tag)
407 {
408 case 0x0001:
409 case 0x0003:
410 case 0x0005:
411 gpsdata[29 + tag / 2] = getc(ifp);
412 break;
413 case 0x0002:
414 case 0x0004:
415 case 0x0007:
416 FORC(6) gpsdata[tag / 3 * 6 + c] = get4();
417 break;
418 case 0x0006:
419 FORC(2) gpsdata[18 + c] = get4();
420 break;
421 case 0x0012: // 18
422 case 0x001d: // 29
423 fgets((char *)(gpsdata + 14 + tag / 3), MIN(len, 12), ifp);
424 }
425 fseek(ifp, save, SEEK_SET);
426 }
427 }
428