/src/libraw/src/metadata/ciff.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2024 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 | | #ifdef _MSC_VER |
21 | | #if _MSC_VER < 1800 /* below MSVC 2013 */ |
22 | | float roundf(float f) |
23 | | { |
24 | | return floorf(f + 0.5); |
25 | | } |
26 | | |
27 | | #endif |
28 | | #endif |
29 | | |
30 | | /* |
31 | | CIFF block 0x1030 contains an 8x8 white sample. |
32 | | Load this into white[][] for use in scale_colors(). |
33 | | */ |
34 | | void LibRaw::ciff_block_1030() |
35 | 3.78k | { |
36 | 3.78k | static const ushort key[] = {0x410, 0x45f3}; |
37 | 3.78k | int i, bpp, row, col, vbits = 0; |
38 | 3.78k | unsigned long bitbuf = 0; |
39 | | |
40 | 3.78k | if ((get2(), get4()) != 0x80008 || !get4()) |
41 | 2.28k | return; |
42 | 1.50k | bpp = get2(); |
43 | 1.50k | if (bpp != 10 && bpp != 12) |
44 | 685 | return; |
45 | 7.38k | for (i = row = 0; row < 8; row++) |
46 | 59.0k | for (col = 0; col < 8; col++) |
47 | 52.4k | { |
48 | 52.4k | if (vbits < bpp) |
49 | 36.1k | { |
50 | 36.1k | bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]); |
51 | 36.1k | vbits += 16; |
52 | 36.1k | } |
53 | 52.4k | white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp); |
54 | 52.4k | } |
55 | 820 | } |
56 | | |
57 | | /* |
58 | | Parse a CIFF file, better known as Canon CRW format. |
59 | | */ |
60 | | void LibRaw::parse_ciff(INT64 offset, int length, int depth) |
61 | 75.8k | { |
62 | 75.8k | int nrecs, c, type, len, wbi = -1; |
63 | 75.8k | INT64 save, tboff; |
64 | 75.8k | ushort key[] = {0x410, 0x45f3}; |
65 | 75.8k | ushort CanonColorInfo1_key; |
66 | 75.8k | ushort Appendix_A = 0; |
67 | 75.8k | INT64 WB_table_offset = 0; |
68 | 75.8k | int UseWBfromTable_as_AsShot = 1; |
69 | 75.8k | int Got_AsShotWB = 0; |
70 | 75.8k | INT64 fsize = ifp->size(); |
71 | 75.8k | if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS) |
72 | 42 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
73 | | |
74 | 75.8k | fseek(ifp, offset + length - 4, SEEK_SET); |
75 | 75.8k | tboff = INT64(get4()) + offset; |
76 | 75.8k | fseek(ifp, tboff, SEEK_SET); |
77 | 75.8k | nrecs = get2(); |
78 | 75.8k | if (nrecs < 1) |
79 | 2.09k | return; |
80 | 73.7k | if ((nrecs | depth) > 127) |
81 | 39.3k | return; |
82 | | |
83 | 34.3k | if (nrecs * 10 + offset > fsize) |
84 | 1.15k | return; |
85 | | |
86 | 1.69M | while (nrecs--) |
87 | 1.66M | { |
88 | 1.66M | type = get2(); |
89 | 1.66M | len = get4(); |
90 | 1.66M | INT64 see = offset + get4(); |
91 | 1.66M | save = ftell(ifp); |
92 | | |
93 | | /* the following tags are not sub-tables |
94 | | * they contain the value in the "len" field |
95 | | * for such tags skip the check against filesize |
96 | | */ |
97 | 1.66M | if ((type != 0x2007) && (type != 0x580b) && (type != 0x501c) && |
98 | 1.66M | (type != 0x5029) && (type != 0x5813) && (type != 0x5814) && |
99 | 1.66M | (type != 0x5817) && (type != 0x5834) && (type != 0x580e)) |
100 | 1.65M | { |
101 | | |
102 | 1.65M | if (see >= fsize) |
103 | 1.24M | { // At least one byte |
104 | 1.24M | fseek(ifp, save, SEEK_SET); |
105 | 1.24M | continue; |
106 | 1.24M | } |
107 | 411k | fseek(ifp, see, SEEK_SET); |
108 | 411k | if ((((type >> 8) + 8) | 8) == 0x38) |
109 | 62.3k | { |
110 | 62.3k | parse_ciff(ftell(ifp), len, depth + 1); /* Parse a sub-table */ |
111 | 62.3k | } |
112 | 411k | } |
113 | | |
114 | 421k | if (type == 0x3004) |
115 | 12.4k | { |
116 | 12.4k | parse_ciff(ftell(ifp), len, depth + 1); |
117 | 12.4k | } |
118 | 408k | else if (type == 0x0810) |
119 | 551 | { |
120 | 551 | fread(artist, 64, 1, ifp); |
121 | 551 | } |
122 | 408k | else if (type == 0x080a) |
123 | 1.83k | { |
124 | 1.83k | fread(make, 64, 1, ifp); |
125 | 1.83k | fseek(ifp, strbuflen(make) - 63, SEEK_CUR); |
126 | 1.83k | fread(model, 64, 1, ifp); |
127 | | |
128 | 406k | } else if (type == 0x080b) { |
129 | 2.40k | stmread(imCommon.firmware, (unsigned)len, ifp); |
130 | 2.40k | if (!strncasecmp(imCommon.firmware, "Firmware Version", 16)) |
131 | 34 | memmove(imCommon.firmware, imCommon.firmware + 16, strlen(imCommon.firmware) - 15); |
132 | 2.40k | trimSpaces(imCommon.firmware); |
133 | | |
134 | 403k | } else if (type == 0x1810) |
135 | 916 | { |
136 | 916 | width = get4(); |
137 | 916 | height = get4(); |
138 | 916 | pixel_aspect = int_to_float(get4()); |
139 | 916 | flip = get4(); |
140 | 916 | } |
141 | 402k | else if (type == 0x1835) |
142 | 310 | { /* Get the decoder table */ |
143 | 310 | tiff_compress = get4(); |
144 | 310 | } |
145 | 402k | else if (type == 0x2007) |
146 | 2.76k | { |
147 | 2.76k | thumb_offset = see; |
148 | 2.76k | thumb_length = len; |
149 | 2.76k | } |
150 | 399k | else if (type == 0x1818) |
151 | 2.90k | { |
152 | 2.90k | shutter = libraw_powf64l(2.0f, -int_to_float((get4(), get4()))); |
153 | 2.90k | ilm.CurAp = aperture = libraw_powf64l(2.0f, int_to_float(get4()) / 2); |
154 | 2.90k | } |
155 | 396k | else if (type == 0x102a) // CanonShotInfo |
156 | 18.5k | { |
157 | | // iso_speed = pow (2.0, (get4(),get2())/32.0 - 4) * 50; |
158 | 18.5k | get2(); // skip one |
159 | 18.5k | iso_speed = |
160 | 18.5k | libraw_powf64l(2.0f, (get2() + get2()) / 32.0f - 5.0f) * 100.0f; |
161 | 18.5k | ilm.CurAp = aperture = _CanonConvertAperture((get2(), get2())); |
162 | 18.5k | shutter = libraw_powf64l(2.0f, -float((short)get2()) / 32.f); |
163 | 18.5k | imCanon.wbi = wbi = (get2(), get2()); |
164 | 18.5k | if (wbi >= (int)Canon_wbi2std.size()) |
165 | 6.78k | wbi = 0; |
166 | 18.5k | fseek(ifp, 32, SEEK_CUR); |
167 | 18.5k | if (shutter > 1e6) |
168 | 979 | shutter = float(get2()) / 10.f; |
169 | 18.5k | } |
170 | 378k | else if (type == 0x102c) // CanonColorInfo2 / Appendix A: Pro90IS, G1, G2, S30, S40 |
171 | 5.32k | { |
172 | 5.32k | int CanonColorInfo2_type = get2(); // G1 1028, G2 272, Pro90 IS 769, S30 274, S40 273, EOS D30 276 |
173 | 5.32k | if (CanonColorInfo2_type > 512) { /* Pro90 IS, G1 */ |
174 | 851 | fseek(ifp, 118, SEEK_CUR); |
175 | 3.40k | FORC4 cam_mul[BG2RG1_2_RGBG(c)] = get2(); |
176 | 851 | } |
177 | 4.47k | else if (CanonColorInfo2_type != 276) { /* G2, S30, S40 */ |
178 | 3.60k | Appendix_A = 1; |
179 | 3.60k | WB_table_offset = -14; |
180 | 3.60k | fseek(ifp, 98, SEEK_CUR); |
181 | 14.4k | FORC4 cam_mul[GRBG_2_RGBG(c)] = get2(); |
182 | 3.60k | if (cam_mul[0] > 0.001f) Got_AsShotWB = 1; |
183 | 3.60k | } |
184 | 5.32k | } |
185 | 373k | else if (type == 0x10a9) // ColorBalance: Canon D60, 10D, 300D, and clones |
186 | 5.24k | { |
187 | 5.24k | int bls = 0; |
188 | | /* |
189 | | int table[] = { |
190 | | LIBRAW_WBI_Auto, // 0 |
191 | | LIBRAW_WBI_Daylight, // 1 |
192 | | LIBRAW_WBI_Cloudy, // 2 |
193 | | LIBRAW_WBI_Tungsten, // 3 |
194 | | LIBRAW_WBI_FL_W, // 4 |
195 | | LIBRAW_WBI_Flash, // 5 |
196 | | LIBRAW_WBI_Custom, // 6, absent in Canon D60 |
197 | | LIBRAW_WBI_Auto, // 7, use this if camera is set to b/w JPEG |
198 | | LIBRAW_WBI_Shade, // 8 |
199 | | LIBRAW_WBI_Kelvin // 9, absent in Canon D60 |
200 | | }; |
201 | | */ |
202 | 5.24k | int nWB = |
203 | 5.24k | ((get2() - 2) / 8) - |
204 | 5.24k | 1; // 2 bytes this, N recs 4*2bytes each, last rec is black level |
205 | 5.24k | if (nWB) |
206 | 20.2k | FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); |
207 | 5.24k | if (nWB >= 7) |
208 | 4.64k | Canon_WBpresets(0, 0); |
209 | 604 | else |
210 | 2.41k | FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); |
211 | 5.24k | if (nWB == 7) // mostly Canon EOS D60 + some fw#s for 300D; |
212 | | // check for 0x1668000 is unreliable |
213 | 2.35k | { |
214 | 2.35k | if ((wbi >= 0) && (wbi < 9) && (wbi != 6)) |
215 | 1.12k | { |
216 | 4.50k | FORC4 cam_mul[c] = float(icWBC[Canon_wbi2std[wbi]][c]); |
217 | 1.12k | } |
218 | 1.23k | else |
219 | 1.23k | { |
220 | 4.92k | FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); |
221 | 1.23k | } |
222 | 2.35k | } |
223 | 2.88k | else if (nWB == 9) // Canon 10D, 300D |
224 | 2.11k | { |
225 | 8.47k | FORC4 icWBC[LIBRAW_WBI_Custom][RGGB_2_RGBG(c)] = get2(); |
226 | 8.47k | FORC4 icWBC[LIBRAW_WBI_Kelvin][RGGB_2_RGBG(c)] = get2(); |
227 | 2.11k | if ((wbi >= 0) && (wbi < 10)) |
228 | 1.14k | { |
229 | 4.57k | FORC4 cam_mul[c] = float(icWBC[Canon_wbi2std[wbi]][c]); |
230 | 1.14k | } |
231 | 975 | else |
232 | 975 | { |
233 | 3.90k | FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); |
234 | 975 | } |
235 | 2.11k | } |
236 | 5.24k | FORC4 |
237 | 20.9k | bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2()); |
238 | 5.24k | imCanon.AverageBlackLevel = bls / 4; |
239 | 5.24k | } |
240 | 367k | else if (type == 0x102d) |
241 | 2.43k | { |
242 | 2.43k | Canon_CameraSettings(len >> 1); |
243 | 2.43k | } |
244 | | |
245 | 365k | else if (type == 0x10b4) { |
246 | 3.80k | switch (get2()) { |
247 | 441 | case 1: |
248 | 441 | imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; |
249 | 441 | break; |
250 | 685 | case 2: |
251 | 685 | imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; |
252 | 685 | break; |
253 | 2.68k | default: |
254 | 2.68k | imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; |
255 | 2.68k | break; |
256 | 3.80k | } |
257 | | |
258 | 361k | } else if (type == 0x580b) |
259 | 755 | { |
260 | 755 | if (strcmp(model, "Canon EOS D30")) |
261 | 755 | sprintf(imgdata.shootinginfo.BodySerial, "%d", len); |
262 | 0 | else |
263 | 0 | sprintf(imgdata.shootinginfo.BodySerial, "%0x-%05d", len >> 16, |
264 | 0 | len & 0xffff); |
265 | 755 | } |
266 | 360k | else if (type == 0x0032) // CanonColorInfo1 |
267 | 12.9k | { |
268 | 12.9k | if (len == 768) { // EOS D30 |
269 | | |
270 | 1.32k | ushort q; |
271 | 1.32k | fseek(ifp, 4, SEEK_CUR); |
272 | 9.24k | for (unsigned linenum = 0; linenum < Canon_D30_linenums_2_StdWBi.size(); linenum++) { |
273 | 7.92k | if (Canon_D30_linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown) { |
274 | 31.6k | FORC4 { |
275 | 31.6k | q = get2(); |
276 | 31.6k | icWBC[Canon_D30_linenums_2_StdWBi[linenum]][RGGB_2_RGBG(c)] = |
277 | 31.6k | (int)(roundf(1024000.0f / (float)MAX(1, q))); |
278 | 31.6k | } |
279 | | // if (Canon_wbi2std[imCanon.wbi] == *(Canon_D30_linenums_2_StdWBi + linenum)) { |
280 | | // FORC4 cam_mul[c] = icWBC[*(Canon_D30_linenums_2_StdWBi + linenum)][c]; |
281 | | // Got_AsShotWB = 1; |
282 | | // } |
283 | 7.92k | } |
284 | 7.92k | } |
285 | 1.32k | fseek (ifp, 68-int(Canon_D30_linenums_2_StdWBi.size())*8, SEEK_CUR); |
286 | | |
287 | 5.28k | FORC4 { |
288 | 5.28k | q = get2(); |
289 | 5.28k | cam_mul[RGGB_2_RGBG(c)] = 1024.f / float(MAX(1, q)); |
290 | 5.28k | } |
291 | 1.32k | if (!wbi) |
292 | 754 | cam_mul[0] = -1; // use my auto white balance |
293 | | |
294 | 1.32k | } |
295 | 11.6k | else if ((cam_mul[0] <= 0.001f) || // Pro1, G3, G5, G6, S45, S50, S60, S70 |
296 | 11.6k | Appendix_A) // G2, S30, S40 |
297 | 10.2k | { |
298 | 10.2k | libraw_static_table_t linenums_2_StdWBi; |
299 | 10.2k | unsigned AsShotWB_linenum = Canon_wbi2std.size(); |
300 | | |
301 | 10.2k | CanonColorInfo1_key = get2(); |
302 | 10.2k | if ((CanonColorInfo1_key == key[0]) && (len == 2048)) { // Pro1 |
303 | 1.01k | linenums_2_StdWBi = Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi; |
304 | 1.01k | WB_table_offset = 8; |
305 | | |
306 | 9.19k | } else if ((CanonColorInfo1_key == key[0]) && (len == 3072)) { // S60, S70, G6 |
307 | 2.39k | linenums_2_StdWBi = Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi; |
308 | 2.39k | WB_table_offset = 16; |
309 | | |
310 | 6.79k | } else if (!CanonColorInfo1_key && (len == 2048)) { // G2, S30, S40; S45, S50, G3, G5 |
311 | 2.51k | key[0] = key[1] = 0; |
312 | 2.51k | linenums_2_StdWBi = Canon_KeyIsZero_Len2048_linenums_2_StdWBi; |
313 | 2.51k | if (atof(imCommon.firmware) < 1.02f) |
314 | 2.51k | UseWBfromTable_as_AsShot = 0; |
315 | | |
316 | 4.27k | } else goto next_tag; |
317 | | |
318 | 5.92k | if ((Canon_wbi2std[wbi] == LIBRAW_WBI_Auto) || |
319 | 5.92k | (Canon_wbi2std[wbi] == LIBRAW_WBI_Unknown) || |
320 | 5.92k | Got_AsShotWB) |
321 | 3.61k | UseWBfromTable_as_AsShot = 0; |
322 | | |
323 | 5.92k | if (UseWBfromTable_as_AsShot) { |
324 | 1.30k | int temp_wbi; |
325 | 1.30k | if (Canon_wbi2std[wbi] == LIBRAW_WBI_Custom) temp_wbi = LIBRAW_WBI_Daylight; |
326 | 908 | else temp_wbi = wbi; |
327 | 8.69k | for (AsShotWB_linenum = 0; AsShotWB_linenum < linenums_2_StdWBi.size(); AsShotWB_linenum++) { |
328 | 8.17k | if (Canon_wbi2std[temp_wbi] == linenums_2_StdWBi[AsShotWB_linenum]) { |
329 | 782 | break; |
330 | 782 | } |
331 | 8.17k | } |
332 | 1.30k | } |
333 | | |
334 | 5.92k | fseek (ifp, 78LL+WB_table_offset, SEEK_CUR); |
335 | 63.5k | for (unsigned linenum = 0; linenum < linenums_2_StdWBi.size(); linenum++) { |
336 | 57.6k | if (linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown) { |
337 | 185k | FORC4 icWBC[linenums_2_StdWBi[linenum]][GRBG_2_RGBG(c)] = get2() ^ key[c & 1]; |
338 | 46.2k | if (UseWBfromTable_as_AsShot && (AsShotWB_linenum == linenum)) { |
339 | 3.12k | FORC4 cam_mul[c] = float(icWBC[linenums_2_StdWBi[linenum]][c]); |
340 | 782 | Got_AsShotWB = 1; |
341 | 782 | } |
342 | 46.2k | } else { |
343 | 11.3k | fseek(ifp, 8, SEEK_CUR); |
344 | 11.3k | } |
345 | 57.6k | } |
346 | 5.92k | if (!Got_AsShotWB) |
347 | 4.21k | cam_mul[0] = -1; |
348 | 5.92k | } |
349 | 12.9k | } |
350 | 347k | else if (type == 0x1030 && wbi >= 0 && (0x18040 >> wbi & 1)) |
351 | 3.78k | { |
352 | 3.78k | ciff_block_1030(); // all that don't have 0x10a9 |
353 | 3.78k | } |
354 | 344k | else if (type == 0x1031) |
355 | 1.69k | { |
356 | 1.69k | raw_width = imCanon.SensorWidth = (get2(), get2()); |
357 | 1.69k | raw_height = imCanon.SensorHeight = get2(); |
358 | 1.69k | fseek(ifp, 4, SEEK_CUR); |
359 | 1.69k | imCanon.DefaultCropAbsolute = get_CanonArea(); |
360 | 1.69k | imCanon.LeftOpticalBlack = get_CanonArea(); |
361 | 1.69k | } |
362 | 342k | else if (type == 0x501c) |
363 | 457 | { |
364 | 457 | iso_speed = float(len & 0xffff); |
365 | 457 | } |
366 | 341k | else if (type == 0x5029) |
367 | 1.20k | { |
368 | 1.20k | ilm.CurFocal = float( len >> 16); |
369 | 1.20k | ilm.FocalType = len & 0xffff; |
370 | 1.20k | if (ilm.FocalType == LIBRAW_FT_ZOOM_LENS) |
371 | 435 | { |
372 | 435 | ilm.FocalUnits = 32; |
373 | 435 | if (ilm.FocalUnits > 1) |
374 | 435 | ilm.CurFocal /= (float)ilm.FocalUnits; |
375 | 435 | } |
376 | 1.20k | focal_len = ilm.CurFocal; |
377 | 1.20k | } |
378 | 340k | else if (type == 0x5813) |
379 | 702 | { |
380 | 702 | flash_used = int_to_float(len); |
381 | 702 | } |
382 | 340k | else if (type == 0x5814) |
383 | 880 | { |
384 | 880 | canon_ev = int_to_float(len); |
385 | 880 | } |
386 | 339k | else if (type == 0x5817) |
387 | 765 | { |
388 | 765 | shot_order = len; |
389 | 765 | } |
390 | 338k | else if (type == 0x5834) |
391 | 1.01k | { |
392 | 1.01k | unique_id = ((unsigned long long)len << 32) >> 32; |
393 | 1.01k | setCanonBodyFeatures(unique_id); |
394 | 1.01k | } |
395 | 337k | else if (type == 0x580e) |
396 | 1.52k | { |
397 | 1.52k | timestamp = len; |
398 | 1.52k | } |
399 | 335k | else if (type == 0x180e) |
400 | 686 | { |
401 | 686 | timestamp = get4(); |
402 | 686 | } |
403 | | |
404 | 416k | next_tag:; |
405 | | #ifdef LOCALTIME |
406 | | if ((type | 0x4000) == 0x580e) |
407 | | timestamp = mktime(gmtime(×tamp)); |
408 | | #endif |
409 | 416k | fseek(ifp, save, SEEK_SET); |
410 | 416k | } |
411 | 33.2k | } |