1 /* -*- C++ -*-
2  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
3  *
4  LibRaw is free software; you can redistribute it and/or modify
5  it under the terms of the one of two licenses as you choose:
6 
7 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
8    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
9 
10 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
11    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
12 
13  */
14 
15 #include "../../internal/dcraw_defs.h"
16 
Kodak_KDC_WBtags(int wb,int wbi)17 void LibRaw::Kodak_KDC_WBtags(int wb, int wbi)
18 {
19   int c;
20   FORC3 icWBC[wb][c] = get4();
21   icWBC[wb][3] = icWBC[wb][1];
22   if (wbi == wb)
23     FORC4 cam_mul[c] = icWBC[wb][c];
24   return;
25 }
26 
Kodak_DCR_WBtags(int wb,unsigned type,int wbi)27 void LibRaw::Kodak_DCR_WBtags(int wb, unsigned type, int wbi)
28 {
29   float mul[3] = {1.0f, 1.0f, 1.0f}, num, mul2;
30   int c;
31   FORC3 mul[c] = (num = getreal(type)) <= 0.001f ? 1.0f : num;
32   icWBC[wb][1] = icWBC[wb][3] = mul[1];
33   mul2 = mul[1] * mul[1];
34   icWBC[wb][0] = mul2 / mul[0];
35   icWBC[wb][2] = mul2 / mul[2];
36   if (wbi == wb)
37     FORC4 cam_mul[c] = icWBC[wb][c];
38   return;
39 }
40 
KodakIllumMatrix(unsigned type,float * romm_camIllum)41 short LibRaw::KodakIllumMatrix(unsigned type, float *romm_camIllum)
42 {
43   int c, j, romm_camTemp[9], romm_camScale[3];
44   if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL))
45   {
46     for (j = 0; j < 9; j++)
47       ((float *)romm_camIllum)[j] = getreal(type);
48     return 1;
49   }
50   else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG))
51   {
52     FORC3
53     {
54       romm_camScale[c] = 0;
55       for (j = 0; j < 3; j++)
56       {
57         romm_camTemp[c * 3 + j] = get4();
58         romm_camScale[c] += romm_camTemp[c * 3 + j];
59       }
60     }
61     if ((romm_camScale[0] > 0x1fff) && (romm_camScale[1] > 0x1fff) &&
62         (romm_camScale[2] > 0x1fff))
63     {
64       FORC3 for (j = 0; j < 3; j++)((float *)romm_camIllum)[c * 3 + j] =
65           ((float)romm_camTemp[c * 3 + j]) / ((float)romm_camScale[c]);
66       return 1;
67     }
68   }
69   return 0;
70 }
71 
72 /* Thanks to Alexey Danilchenko for wb as-shot parsing code */
parse_kodak_ifd(int base)73 void LibRaw::parse_kodak_ifd(int base)
74 {
75   unsigned entries, tag, type, len, save;
76   int c, wbi = -1;
77 
78   static const int wbtag_kdc[] = {
79       LIBRAW_WBI_Auto,        // 64037 / 0xfa25
80       LIBRAW_WBI_Fluorescent, // 64040 / 0xfa28
81       LIBRAW_WBI_Tungsten,    // 64039 / 0xfa27
82       LIBRAW_WBI_Daylight,    // 64041 / 0xfa29
83       -1,
84       -1,
85       LIBRAW_WBI_Shade // 64042 / 0xfa2a
86   };
87 
88   static const int wbtag_dcr[] = {
89       LIBRAW_WBI_Daylight,    // 2120 / 0x0848
90       LIBRAW_WBI_Tungsten,    // 2121 / 0x0849
91       LIBRAW_WBI_Fluorescent, // 2122 / 0x084a
92       LIBRAW_WBI_Flash,       // 2123 / 0x084b
93       LIBRAW_WBI_Custom,      // 2124 / 0x084c
94       LIBRAW_WBI_Auto         // 2125 / 0x084d
95   };
96 
97   //  int a_blck = 0;
98 
99   entries = get2();
100   if (entries > 1024)
101     return;
102   INT64 fsize = ifp->size();
103   while (entries--)
104   {
105     tiff_get(base, &tag, &type, &len, &save);
106     INT64 savepos = ftell(ifp);
107     if (len > 8 && len + savepos > 2 * fsize)
108     {
109       fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
110       continue;
111     }
112     if (callbacks.exif_cb)
113     {
114       callbacks.exif_cb(callbacks.exifparser_data, tag | 0x20000, type, len,
115                         order, ifp, base);
116       fseek(ifp, savepos, SEEK_SET);
117     }
118     if (tag == 0x03eb) // 1003
119       imgdata.sizes.raw_inset_crops[0].cleft = get2();
120     else if (tag == 0x03ec) // 1004
121       imgdata.sizes.raw_inset_crops[0].ctop = get2();
122     else if (tag == 0x03ed) // 1005
123       imgdata.sizes.raw_inset_crops[0].cwidth = get2();
124     else if (tag == 0x03ee) // 1006
125       imgdata.sizes.raw_inset_crops[0].cheight = get2();
126     else if (tag == 0x03ef) // 1007
127     {
128       if (!strcmp(model, "EOS D2000C"))
129         black = get2();
130       else
131         imKodak.BlackLevelTop = get2();
132     }
133     else if (tag == 0x03f0) // 1008
134     {
135       if (!strcmp(model, "EOS D2000C"))
136       {
137         if (black) // already set by tag 1007 (0x03ef)
138           black = (black + get2()) / 2;
139         else
140           black = get2();
141       }
142       else
143         imKodak.BlackLevelBottom = get2();
144     }
145 
146     else if (tag == 0x03f1)
147     { // 1009 Kodak TextualInfo
148       if (len > 0)
149       {
150         char kti[1024];
151         char *pkti;
152         int nsym = MIN(len, 1023);
153         fread(kti, 1, nsym, ifp);
154         kti[nsym] = 0;
155 #ifdef LIBRAW_WIN32_CALLS
156         pkti = strtok(kti, "\x0a");
157 #else
158         char *last = 0;
159         pkti = strtok_r(kti, "\x0a", &last);
160 #endif
161         while (pkti != NULL)
162         {
163           c = 12;
164           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Camera body:", c)))
165           {
166             while ((pkti[c] == ' ') && (c < (int)strlen(pkti)))
167             {
168               c++;
169             }
170             strcpy(ilm.body, pkti + c);
171           }
172           c = 5;
173           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Lens:", c)))
174           {
175             ilm.CurFocal = atoi(pkti + c);
176           }
177           c = 9;
178           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Aperture:", c)))
179           {
180             while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
181             {
182               c++;
183             }
184             ilm.CurAp = atof(pkti + c);
185           }
186           c = 10;
187           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "ISO Speed:", c)))
188           {
189             iso_speed = atoi(pkti + c);
190           }
191           c = 13;
192           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Focal Length:", c)))
193           {
194             ilm.CurFocal = atoi(pkti + c);
195           }
196           c = 13;
197           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Max Aperture:", c)))
198           {
199             while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
200             {
201               c++;
202             }
203             ilm.MaxAp4CurFocal = atof(pkti + c);
204           }
205           c = 13;
206           if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Min Aperture:", c)))
207           {
208             while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti)))
209             {
210               c++;
211             }
212             ilm.MinAp4CurFocal = atof(pkti + c);
213           }
214 #ifdef LIBRAW_WIN32_CALLS
215           pkti = strtok(NULL, "\x0a");
216 #else
217           pkti = strtok_r(NULL, "\x0a", &last);
218 #endif
219         }
220       }
221     }
222 
223     else if (tag == 0x03f3) // 1011
224       imCommon.FlashEC = getreal(type);
225 
226     else if (tag == 0x03fc) // 1020
227     {
228       wbi = getint(type);
229       if ((wbi >= 0) && (wbi < 6) && (wbi != -2))
230         wbi = wbtag_dcr[wbi];
231     }
232     else if (tag == 0x03fd && len == 72) // 1021
233     {                                    /* WB set in software */
234       fseek(ifp, 40, SEEK_CUR);
235       FORC3 cam_mul[c] = 2048.0 / fMAX(1.0f, get2());
236       wbi = -2;
237     }
238 
239     else if ((tag == 0x0406) && (len == 1)) // 1030
240       imCommon.CameraTemperature = getreal(type);
241     else if ((tag == 0x0413) && (len == 1)) // 1043
242       imCommon.SensorTemperature = getreal(type);
243     else if (tag == 0x0848) // 2120
244       Kodak_DCR_WBtags(LIBRAW_WBI_Daylight, type, wbi);
245     else if (tag == 0x0849) // 2121
246       Kodak_DCR_WBtags(LIBRAW_WBI_Tungsten, type, wbi);
247     else if (tag == 0x084a) // 2122
248       Kodak_DCR_WBtags(LIBRAW_WBI_Fluorescent, type, wbi);
249     else if (tag == 0x084b) // 2123
250       Kodak_DCR_WBtags(LIBRAW_WBI_Flash, type, wbi);
251     else if (tag == 0x084c) // 2124
252       Kodak_DCR_WBtags(LIBRAW_WBI_Custom, type, wbi);
253     else if (tag == 0x084d) // 2125
254     {
255       if (wbi == -1)
256         wbi = LIBRAW_WBI_Auto;
257       Kodak_DCR_WBtags(LIBRAW_WBI_Auto, type, wbi);
258     }
259     else if (tag == 0x089f) // 2207
260       imKodak.ISOCalibrationGain = getreal(type);
261     else if (tag == 0x0903) // 2307
262       imKodak.AnalogISO = iso_speed = getreal(type);
263     else if (tag == 0x090d) // 2317
264       linear_table(len);
265     else if (tag == 0x09ce) // 2510
266       stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp);
267     else if (tag == 0x0e92) // 3730
268     {
269       imKodak.val018percent = get2();
270       imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
271           imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
272               (int)(((float)imKodak.val018percent) / 18.0f * 170.0f);
273     }
274     else if (tag == 0x0e93) // 3731
275       imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
276           imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
277               imKodak.val170percent = get2();
278     else if (tag == 0x0e94) // 3732
279       imKodak.val100percent = get2();
280     /*
281         else if (tag == 0x1784)    // 6020
282           iso_speed = getint(type);
283     */
284     else if (tag == 0xfa00) // 64000
285       stmread(imgdata.shootinginfo.BodySerial, len, ifp);
286     else if (tag == 0xfa0d) // 64013
287     {
288       wbi = fgetc(ifp);
289       if ((wbi >= 0) && (wbi < 7))
290         wbi = wbtag_kdc[wbi];
291     }
292     else if (tag == 0xfa13) // 64019
293       width = getint(type);
294     else if (tag == 0xfa14) // 64020
295       height = (getint(type) + 1) & -2;
296     /*
297           height = getint(type);
298 
299         else if (tag == 0xfa16)  // 64022
300           raw_width = get2();
301         else if (tag == 0xfa17)  // 64023
302           raw_height = get2();
303     */
304     else if (tag == 0xfa18) // 64024
305     {
306       imKodak.offset_left = getint(LIBRAW_EXIFTAG_TYPE_SSHORT);
307       if (type != LIBRAW_EXIFTAG_TYPE_SSHORT)
308         imKodak.offset_left += 1;
309     }
310     else if (tag == 0xfa19) // 64025
311     {
312       imKodak.offset_top = getint(LIBRAW_EXIFTAG_TYPE_SSHORT);
313       if (type != LIBRAW_EXIFTAG_TYPE_SSHORT)
314         imKodak.offset_top += 1;
315     }
316 
317     else if (tag == 0xfa25) // 64037
318       Kodak_KDC_WBtags(LIBRAW_WBI_Auto, wbi);
319     else if (tag == 0xfa27) // 64039
320       Kodak_KDC_WBtags(LIBRAW_WBI_Tungsten, wbi);
321     else if (tag == 0xfa28) // 64040
322       Kodak_KDC_WBtags(LIBRAW_WBI_Fluorescent, wbi);
323     else if (tag == 0xfa29) // 64041
324       Kodak_KDC_WBtags(LIBRAW_WBI_Daylight, wbi);
325     else if (tag == 0xfa2a) // 64042
326       Kodak_KDC_WBtags(LIBRAW_WBI_Shade, wbi);
327 
328     else if (tag == 0xfa31) // 64049
329       imgdata.sizes.raw_inset_crops[0].cwidth = get2();
330     else if (tag == 0xfa32) // 64050
331       imgdata.sizes.raw_inset_crops[0].cheight = get2();
332     else if (tag == 0xfa3e) // 64062
333       imgdata.sizes.raw_inset_crops[0].cleft = get2();
334     else if (tag == 0xfa3f) // 64063
335       imgdata.sizes.raw_inset_crops[0].ctop = get2();
336 
337     else if (((tag == 0x07e4) || (tag == 0xfb01)) &&
338              (len == 9)) // 2020 or 64257
339     {
340       if (KodakIllumMatrix(type, (float *)imKodak.romm_camDaylight))
341       {
342         romm_coeff(imKodak.romm_camDaylight);
343       }
344     }
345     else if (((tag == 0x07e5) || (tag == 0xfb02)) &&
346              (len == 9)) // 2021 or 64258
347       KodakIllumMatrix(type, (float *)imKodak.romm_camTungsten);
348     else if (((tag == 0x07e6) || (tag == 0xfb03)) &&
349              (len == 9)) // 2022 or 64259
350       KodakIllumMatrix(type, (float *)imKodak.romm_camFluorescent);
351     else if (((tag == 0x07e7) || (tag == 0xfb04)) &&
352              (len == 9)) // 2023 or 64260
353       KodakIllumMatrix(type, (float *)imKodak.romm_camFlash);
354     else if (((tag == 0x07e8) || (tag == 0xfb05)) &&
355              (len == 9)) // 2024 or 64261
356       KodakIllumMatrix(type, (float *)imKodak.romm_camCustom);
357     else if (((tag == 0x07e9) || (tag == 0xfb06)) &&
358              (len == 9)) // 2025 or 64262
359       KodakIllumMatrix(type, (float *)imKodak.romm_camAuto);
360 
361     fseek(ifp, save, SEEK_SET);
362   }
363 }
364