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