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