/src/LibRaw/src/utils/open.cpp
Line | Count | Source |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2025 LibRaw LLC (info@libraw.org) |
3 | | * |
4 | | |
5 | | LibRaw is free software; you can redistribute it and/or modify |
6 | | it under the terms of the one of two licenses as you choose: |
7 | | |
8 | | 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
9 | | (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
10 | | |
11 | | 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
12 | | (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
13 | | |
14 | | */ |
15 | | |
16 | | #include "../../internal/libraw_cxx_defs.h" |
17 | | #include "../../internal/libraw_cameraids.h" |
18 | | |
19 | | #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM |
20 | | int LibRaw::open_file(const char *fname, INT64 max_buf_size) |
21 | | { |
22 | | int big = 0; |
23 | | if (max_buf_size == LIBRAW_OPEN_BIGFILE) |
24 | | big = 1; |
25 | | else if (max_buf_size == LIBRAW_OPEN_FILE) |
26 | | big = 0; |
27 | | else |
28 | | { |
29 | | #ifndef LIBRAW_WIN32_CALLS |
30 | | struct stat st; |
31 | | if (stat(fname, &st)) |
32 | | return LIBRAW_IO_ERROR; |
33 | | big = (st.st_size > max_buf_size) ? 1 : 0; |
34 | | #else |
35 | | struct _stati64 st; |
36 | | if (_stati64(fname, &st)) |
37 | | return LIBRAW_IO_ERROR; |
38 | | big = (st.st_size > max_buf_size) ? 1 : 0; |
39 | | #endif |
40 | | } |
41 | | |
42 | | LibRaw_abstract_datastream *stream; |
43 | | try |
44 | | { |
45 | | if (big) |
46 | | stream = new LibRaw_bigfile_datastream(fname); |
47 | | else |
48 | | stream = new LibRaw_file_datastream(fname); |
49 | | } |
50 | | |
51 | | catch (const std::bad_alloc& ) |
52 | | { |
53 | | recycle(); |
54 | | return LIBRAW_UNSUFFICIENT_MEMORY; |
55 | | } |
56 | | if (!stream->valid()) |
57 | | { |
58 | | delete stream; |
59 | | return LIBRAW_IO_ERROR; |
60 | | } |
61 | | ID.input_internal = 0; // preserve from deletion on error |
62 | | int ret = open_datastream(stream); |
63 | | if (ret == LIBRAW_SUCCESS) |
64 | | { |
65 | | ID.input_internal = 1; // flag to delete datastream on recycle |
66 | | } |
67 | | else |
68 | | { |
69 | | delete stream; |
70 | | ID.input_internal = 0; |
71 | | } |
72 | | return ret; |
73 | | } |
74 | | |
75 | | #if defined(WIN32) || defined(_WIN32) |
76 | | #ifndef LIBRAW_WIN32_UNICODEPATHS |
77 | | int LibRaw::open_file(const wchar_t *, INT64) |
78 | | { |
79 | | return LIBRAW_NOT_IMPLEMENTED; |
80 | | } |
81 | | #else |
82 | | int LibRaw::open_file(const wchar_t *fname, INT64 max_buf_size) |
83 | | { |
84 | | int big = 0; |
85 | | if (max_buf_size == LIBRAW_OPEN_BIGFILE) |
86 | | big = 1; |
87 | | else if (max_buf_size == LIBRAW_OPEN_FILE) |
88 | | big = 0; |
89 | | else |
90 | | { |
91 | | struct _stati64 st; |
92 | | if (_wstati64(fname, &st)) |
93 | | return LIBRAW_IO_ERROR; |
94 | | big = (st.st_size > max_buf_size) ? 1 : 0; |
95 | | } |
96 | | |
97 | | LibRaw_abstract_datastream *stream; |
98 | | try |
99 | | { |
100 | | if (big) |
101 | | stream = new LibRaw_bigfile_datastream(fname); |
102 | | else |
103 | | stream = new LibRaw_file_datastream(fname); |
104 | | } |
105 | | |
106 | | catch (const std::bad_alloc&) |
107 | | { |
108 | | recycle(); |
109 | | return LIBRAW_UNSUFFICIENT_MEMORY; |
110 | | } |
111 | | if (!stream->valid()) |
112 | | { |
113 | | delete stream; |
114 | | return LIBRAW_IO_ERROR; |
115 | | } |
116 | | ID.input_internal = 0; // preserve from deletion on error |
117 | | int ret = open_datastream(stream); |
118 | | if (ret == LIBRAW_SUCCESS) |
119 | | { |
120 | | ID.input_internal = 1; // flag to delete datastream on recycle |
121 | | } |
122 | | else |
123 | | { |
124 | | delete stream; |
125 | | ID.input_internal = 0; |
126 | | } |
127 | | return ret; |
128 | | } |
129 | | #endif |
130 | | #endif |
131 | | |
132 | | #else /* LIBRAW_NO_IOSTREAMS_DATASTREAM*/ |
133 | | |
134 | | int LibRaw::libraw_openfile_tail(LibRaw_abstract_datastream *stream) |
135 | 0 | { |
136 | 0 | if (!stream->valid()) |
137 | 0 | { |
138 | 0 | delete stream; |
139 | 0 | return LIBRAW_IO_ERROR; |
140 | 0 | } |
141 | 0 | ID.input_internal = 0; // preserve from deletion on error |
142 | 0 | int ret = open_datastream(stream); |
143 | 0 | if (ret == LIBRAW_SUCCESS) |
144 | 0 | { |
145 | 0 | ID.input_internal = 1; // flag to delete datastream on recycle |
146 | 0 | } |
147 | 0 | else |
148 | 0 | { |
149 | 0 | delete stream; |
150 | 0 | ID.input_internal = 0; |
151 | 0 | } |
152 | 0 | return ret; |
153 | 0 | } |
154 | | |
155 | | int LibRaw::open_file(const char *fname) |
156 | 0 | { |
157 | 0 | LibRaw_abstract_datastream *stream; |
158 | 0 | try |
159 | 0 | { |
160 | | #ifdef LIBRAW_WIN32_CALLS |
161 | | stream = new LibRaw_bigfile_buffered_datastream(fname); |
162 | | #else |
163 | 0 | stream = new LibRaw_bigfile_datastream(fname); |
164 | 0 | #endif |
165 | 0 | } |
166 | 0 | catch (const std::bad_alloc&) |
167 | 0 | { |
168 | 0 | recycle(); |
169 | 0 | return LIBRAW_UNSUFFICIENT_MEMORY; |
170 | 0 | } |
171 | 0 | if ((stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) |
172 | 0 | && (stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) |
173 | 0 | && (stream->size() > (INT64)LIBRAW_MAX_CR3_RAW_FILE_SIZE) |
174 | 0 | ) |
175 | 0 | { |
176 | 0 | delete stream; |
177 | 0 | return LIBRAW_TOO_BIG; |
178 | 0 | } |
179 | 0 | return libraw_openfile_tail(stream); |
180 | 0 | } |
181 | | |
182 | | #if defined(WIN32) || defined(_WIN32) |
183 | | #ifndef LIBRAW_WIN32_UNICODEPATHS |
184 | | int LibRaw::open_file(const wchar_t *) |
185 | | { |
186 | | return LIBRAW_NOT_IMPLEMENTED; |
187 | | } |
188 | | #else |
189 | | int LibRaw::open_file(const wchar_t *fname) |
190 | | { |
191 | | LibRaw_abstract_datastream *stream; |
192 | | try |
193 | | { |
194 | | #ifdef LIBRAW_WIN32_CALLS |
195 | | stream = new LibRaw_bigfile_buffered_datastream(fname); |
196 | | #else |
197 | | stream = new LibRaw_bigfile_datastream(fname); |
198 | | #endif |
199 | | } |
200 | | catch (const std::bad_alloc&) |
201 | | { |
202 | | recycle(); |
203 | | return LIBRAW_UNSUFFICIENT_MEMORY; |
204 | | } |
205 | | if ((stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) |
206 | | && (stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) && |
207 | | (stream->size() > (INT64)LIBRAW_MAX_CR3_RAW_FILE_SIZE) |
208 | | ) |
209 | | { |
210 | | delete stream; |
211 | | return LIBRAW_TOO_BIG; |
212 | | } |
213 | | |
214 | | return libraw_openfile_tail(stream); |
215 | | } |
216 | | #endif |
217 | | #endif |
218 | | |
219 | | #endif |
220 | | |
221 | | int LibRaw::open_buffer(const void *buffer, size_t size) |
222 | 0 | { |
223 | | // this stream will close on recycle() |
224 | 0 | if (!buffer || buffer == (const void *)-1) |
225 | 0 | return LIBRAW_IO_ERROR; |
226 | | |
227 | 0 | if ((size > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) |
228 | 0 | && (size > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) |
229 | 0 | && (size > (INT64)LIBRAW_MAX_CR3_RAW_FILE_SIZE) |
230 | 0 | ) |
231 | 0 | return LIBRAW_TOO_BIG; |
232 | | |
233 | 0 | LibRaw_buffer_datastream *stream; |
234 | 0 | try |
235 | 0 | { |
236 | 0 | stream = new LibRaw_buffer_datastream(buffer, size); |
237 | 0 | } |
238 | 0 | catch (const std::bad_alloc& ) |
239 | 0 | { |
240 | 0 | recycle(); |
241 | 0 | return LIBRAW_UNSUFFICIENT_MEMORY; |
242 | 0 | } |
243 | 0 | if (!stream->valid()) |
244 | 0 | { |
245 | 0 | delete stream; |
246 | 0 | return LIBRAW_IO_ERROR; |
247 | 0 | } |
248 | 0 | ID.input_internal = 0; // preserve from deletion on error |
249 | 0 | int ret = open_datastream(stream); |
250 | 0 | if (ret == LIBRAW_SUCCESS) |
251 | 0 | { |
252 | 0 | ID.input_internal = 1; // flag to delete datastream on recycle |
253 | 0 | } |
254 | 0 | else |
255 | 0 | { |
256 | 0 | delete stream; |
257 | 0 | ID.input_internal = 0; |
258 | 0 | } |
259 | 0 | return ret; |
260 | 0 | } |
261 | | |
262 | | int LibRaw::open_bayer(const unsigned char *buffer, unsigned datalen, |
263 | | ushort _raw_width, ushort _raw_height, |
264 | | ushort _left_margin, ushort _top_margin, |
265 | | ushort _right_margin, ushort _bottom_margin, |
266 | | unsigned char procflags, unsigned char bayer_pattern, |
267 | | unsigned unused_bits, unsigned otherflags, |
268 | | unsigned black_level) |
269 | 0 | { |
270 | | // this stream will close on recycle() |
271 | 0 | if (!buffer || buffer == (const void *)-1) |
272 | 0 | return LIBRAW_IO_ERROR; |
273 | | |
274 | 0 | LibRaw_buffer_datastream *stream; |
275 | 0 | try |
276 | 0 | { |
277 | 0 | stream = new LibRaw_buffer_datastream(buffer, datalen); |
278 | 0 | } |
279 | 0 | catch (const std::bad_alloc& ) |
280 | 0 | { |
281 | 0 | recycle(); |
282 | 0 | return LIBRAW_UNSUFFICIENT_MEMORY; |
283 | 0 | } |
284 | 0 | if (!stream->valid()) |
285 | 0 | { |
286 | 0 | delete stream; |
287 | 0 | return LIBRAW_IO_ERROR; |
288 | 0 | } |
289 | 0 | ID.input = stream; |
290 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN); |
291 | | // From identify |
292 | 0 | initdata(); |
293 | 0 | strcpy(imgdata.idata.make, "BayerDump"); |
294 | 0 | snprintf(imgdata.idata.model, sizeof(imgdata.idata.model) - 1, |
295 | 0 | "%u x %u pixels", _raw_width, _raw_height); |
296 | 0 | S.flip = procflags >> 2; |
297 | 0 | libraw_internal_data.internal_output_params.zero_is_bad = procflags & 2; |
298 | 0 | libraw_internal_data.unpacker_data.data_offset = 0; |
299 | 0 | S.raw_width = _raw_width; |
300 | 0 | S.raw_height = _raw_height; |
301 | 0 | S.left_margin = _left_margin; |
302 | 0 | S.top_margin = _top_margin; |
303 | 0 | S.width = S.raw_width - S.left_margin - _right_margin; |
304 | 0 | S.height = S.raw_height - S.top_margin - _bottom_margin; |
305 | |
|
306 | 0 | imgdata.idata.filters = 0x1010101 * bayer_pattern; |
307 | 0 | imgdata.idata.colors = |
308 | 0 | 4 - !((imgdata.idata.filters & imgdata.idata.filters >> 1) & 0x5555); |
309 | 0 | libraw_internal_data.unpacker_data.load_flags = otherflags; |
310 | 0 | switch (libraw_internal_data.unpacker_data.tiff_bps = |
311 | 0 | (datalen)*8 / (S.raw_width * S.raw_height)) |
312 | 0 | { |
313 | 0 | case 8: |
314 | 0 | load_raw = &LibRaw::eight_bit_load_raw; |
315 | 0 | break; |
316 | 0 | case 10: |
317 | 0 | if ((datalen) / S.raw_height * 3u >= S.raw_width * 4u) |
318 | 0 | { |
319 | 0 | load_raw = &LibRaw::android_loose_load_raw; |
320 | 0 | break; |
321 | 0 | } |
322 | 0 | else if (libraw_internal_data.unpacker_data.load_flags & 1) |
323 | 0 | { |
324 | 0 | load_raw = &LibRaw::android_tight_load_raw; |
325 | 0 | break; |
326 | 0 | } |
327 | 0 | case 12: |
328 | 0 | libraw_internal_data.unpacker_data.load_flags |= 128; |
329 | 0 | load_raw = &LibRaw::packed_load_raw; |
330 | 0 | break; |
331 | 0 | case 16: |
332 | 0 | libraw_internal_data.unpacker_data.order = |
333 | 0 | 0x4949 | 0x404 * (libraw_internal_data.unpacker_data.load_flags & 1); |
334 | 0 | libraw_internal_data.unpacker_data.tiff_bps -= |
335 | 0 | libraw_internal_data.unpacker_data.load_flags >> 4; |
336 | 0 | libraw_internal_data.unpacker_data.tiff_bps -= |
337 | 0 | libraw_internal_data.unpacker_data.load_flags = |
338 | 0 | libraw_internal_data.unpacker_data.load_flags >> 1 & 7; |
339 | 0 | load_raw = &LibRaw::unpacked_load_raw; |
340 | 0 | } |
341 | 0 | C.maximum = |
342 | 0 | (1 << libraw_internal_data.unpacker_data.tiff_bps) - (1 << unused_bits); |
343 | 0 | C.black = black_level; |
344 | 0 | S.iwidth = S.width; |
345 | 0 | S.iheight = S.height; |
346 | 0 | imgdata.idata.colors = 3; |
347 | 0 | imgdata.idata.filters |= ((imgdata.idata.filters >> 2 & 0x22222222) | |
348 | 0 | (imgdata.idata.filters << 2 & 0x88888888)) & |
349 | 0 | imgdata.idata.filters << 1; |
350 | |
|
351 | 0 | imgdata.idata.raw_count = 1; |
352 | 0 | for (int i = 0; i < 4; i++) |
353 | 0 | imgdata.color.pre_mul[i] = 1.0; |
354 | |
|
355 | 0 | strcpy(imgdata.idata.cdesc, "RGBG"); |
356 | |
|
357 | 0 | ID.input_internal = 1; |
358 | 0 | SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY); |
359 | 0 | return LIBRAW_SUCCESS; |
360 | 0 | } |
361 | | |
362 | | struct foveon_data_t |
363 | | { |
364 | | const char *make; |
365 | | const char *model; |
366 | | const int raw_width, raw_height; |
367 | | const int white; |
368 | | const int left_margin, top_margin; |
369 | | const int width, height; |
370 | | } foveon_data[] = { |
371 | | {"Sigma", "SD9", 2304, 1531, 12000, 20, 8, 2266, 1510}, |
372 | | {"Sigma", "SD9", 1152, 763, 12000, 10, 2, 1132, 755}, |
373 | | {"Sigma", "SD10", 2304, 1531, 12000, 20, 8, 2266, 1510}, |
374 | | {"Sigma", "SD10", 1152, 763, 12000, 10, 2, 1132, 755}, |
375 | | {"Sigma", "SD14", 2688, 1792, 14000, 18, 12, 2651, 1767}, |
376 | | {"Sigma", "SD14", 2688, 896, 14000, 18, 6, 2651, 883}, // 2/3 |
377 | | {"Sigma", "SD14", 1344, 896, 14000, 9, 6, 1326, 883}, // 1/2 |
378 | | {"Sigma", "SD15", 2688, 1792, 2900, 18, 12, 2651, 1767}, |
379 | | {"Sigma", "SD15", 2688, 896, 2900, 18, 6, 2651, 883}, // 2/3 ? |
380 | | {"Sigma", "SD15", 1344, 896, 2900, 9, 6, 1326, 883}, // 1/2 ? |
381 | | {"Sigma", "DP1", 2688, 1792, 2100, 18, 12, 2651, 1767}, |
382 | | {"Sigma", "DP1", 2688, 896, 2100, 18, 6, 2651, 883}, // 2/3 ? |
383 | | {"Sigma", "DP1", 1344, 896, 2100, 9, 6, 1326, 883}, // 1/2 ? |
384 | | {"Sigma", "DP1S", 2688, 1792, 2200, 18, 12, 2651, 1767}, |
385 | | {"Sigma", "DP1S", 2688, 896, 2200, 18, 6, 2651, 883}, // 2/3 |
386 | | {"Sigma", "DP1S", 1344, 896, 2200, 9, 6, 1326, 883}, // 1/2 |
387 | | {"Sigma", "DP1X", 2688, 1792, 3560, 18, 12, 2651, 1767}, |
388 | | {"Sigma", "DP1X", 2688, 896, 3560, 18, 6, 2651, 883}, // 2/3 |
389 | | {"Sigma", "DP1X", 1344, 896, 3560, 9, 6, 1326, 883}, // 1/2 |
390 | | {"Sigma", "DP2", 2688, 1792, 2326, 13, 16, 2651, 1767}, |
391 | | {"Sigma", "DP2", 2688, 896, 2326, 13, 8, 2651, 883}, // 2/3 ?? |
392 | | {"Sigma", "DP2", 1344, 896, 2326, 7, 8, 1325, 883}, // 1/2 ?? |
393 | | {"Sigma", "DP2S", 2688, 1792, 2300, 18, 12, 2651, 1767}, |
394 | | {"Sigma", "DP2S", 2688, 896, 2300, 18, 6, 2651, 883}, // 2/3 |
395 | | {"Sigma", "DP2S", 1344, 896, 2300, 9, 6, 1326, 883}, // 1/2 |
396 | | {"Sigma", "DP2X", 2688, 1792, 2300, 18, 12, 2651, 1767}, |
397 | | {"Sigma", "DP2X", 2688, 896, 2300, 18, 6, 2651, 883}, // 2/3 |
398 | | {"Sigma", "DP2X", 1344, 896, 2300, 9, 6, 1325, 883}, // 1/2 |
399 | | {"Sigma", "SD1", 4928, 3264, 3900, 12, 52, 4807, 3205}, // Full size |
400 | | {"Sigma", "SD1", 4928, 1632, 3900, 12, 26, 4807, 1603}, // 2/3 size |
401 | | {"Sigma", "SD1", 2464, 1632, 3900, 6, 26, 2403, 1603}, // 1/2 size |
402 | | {"Sigma", "SD1 Merrill", 4928, 3264, 3900, 12, 52, 4807, 3205}, // Full size |
403 | | {"Sigma", "SD1 Merrill", 4928, 1632, 3900, 12, 26, 4807, 1603}, // 2/3 size |
404 | | {"Sigma", "SD1 Merrill", 2464, 1632, 3900, 6, 26, 2403, 1603}, // 1/2 size |
405 | | {"Sigma", "DP1 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, |
406 | | {"Sigma", "DP1 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size |
407 | | {"Sigma", "DP1 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size |
408 | | {"Sigma", "DP2 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, |
409 | | {"Sigma", "DP2 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size |
410 | | {"Sigma", "DP2 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size |
411 | | {"Sigma", "DP3 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, |
412 | | {"Sigma", "DP3 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size |
413 | | {"Sigma", "DP3 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size |
414 | | {"Polaroid", "x530", 1440, 1088, 2700, 10, 13, 1419, 1059}, |
415 | | // dp2 Q |
416 | | {"Sigma", "dp3 Quattro", 5888, 3776, 16383, 204, 76, 5446, |
417 | | 3624}, // full size, new fw ?? |
418 | | {"Sigma", "dp3 Quattro", 5888, 3672, 16383, 204, 24, 5446, |
419 | | 3624}, // full size |
420 | | {"Sigma", "dp3 Quattro", 2944, 1836, 16383, 102, 12, 2723, |
421 | | 1812}, // half size |
422 | | {"Sigma", "dp3 Quattro", 2944, 1888, 16383, 102, 38, 2723, |
423 | | 1812}, // half size, new fw?? |
424 | | |
425 | | {"Sigma", "dp2 Quattro", 5888, 3776, 16383, 204, 76, 5446, |
426 | | 3624}, // full size, new fw |
427 | | {"Sigma", "dp2 Quattro", 5888, 3672, 16383, 204, 24, 5446, |
428 | | 3624}, // full size |
429 | | {"Sigma", "dp2 Quattro", 2944, 1836, 16383, 102, 12, 2723, |
430 | | 1812}, // half size |
431 | | {"Sigma", "dp2 Quattro", 2944, 1888, 16383, 102, 38, 2723, |
432 | | 1812}, // half size, new fw |
433 | | |
434 | | {"Sigma", "dp1 Quattro", 5888, 3776, 16383, 204, 76, 5446, |
435 | | 3624}, // full size, new fw?? |
436 | | {"Sigma", "dp1 Quattro", 5888, 3672, 16383, 204, 24, 5446, |
437 | | 3624}, // full size |
438 | | {"Sigma", "dp1 Quattro", 2944, 1836, 16383, 102, 12, 2723, |
439 | | 1812}, // half size |
440 | | {"Sigma", "dp1 Quattro", 2944, 1888, 16383, 102, 38, 2723, |
441 | | 1812}, // half size, new fw |
442 | | |
443 | | {"Sigma", "dp0 Quattro", 5888, 3776, 16383, 204, 76, 5446, |
444 | | 3624}, // full size, new fw?? |
445 | | {"Sigma", "dp0 Quattro", 5888, 3672, 16383, 204, 24, 5446, |
446 | | 3624}, // full size |
447 | | {"Sigma", "dp0 Quattro", 2944, 1836, 16383, 102, 12, 2723, |
448 | | 1812}, // half size |
449 | | {"Sigma", "dp0 Quattro", 2944, 1888, 16383, 102, 38, 2723, |
450 | | 1812}, // half size, new fw |
451 | | // Sigma sd Quattro |
452 | | {"Sigma", "sd Quattro", 5888, 3776, 16383, 204, 76, 5446, |
453 | | 3624}, // full size |
454 | | {"Sigma", "sd Quattro", 2944, 1888, 16383, 102, 38, 2723, |
455 | | 1812}, // half size |
456 | | // Sd Quattro H |
457 | | {"Sigma", "sd Quattro H", 6656, 4480, 4000, 224, 160, 6208, |
458 | | 4160}, // full size |
459 | | {"Sigma", "sd Quattro H", 3328, 2240, 4000, 112, 80, 3104, |
460 | | 2080}, // half size |
461 | | {"Sigma", "sd Quattro H", 5504, 3680, 4000, 0, 4, 5496, 3668}, // full size |
462 | | {"Sigma", "sd Quattro H", 2752, 1840, 4000, 0, 2, 2748, 1834}, // half size |
463 | | }; |
464 | | const int foveon_count = sizeof(foveon_data) / sizeof(foveon_data[0]); |
465 | | |
466 | | int LibRaw::open_datastream(LibRaw_abstract_datastream *stream) |
467 | 31.8k | { |
468 | | |
469 | 31.8k | if (!stream) |
470 | 0 | return ENOENT; |
471 | 31.8k | if (!stream->valid()) |
472 | 0 | return LIBRAW_IO_ERROR; |
473 | 31.8k | if ((stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) |
474 | 0 | && (stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) && |
475 | 0 | (stream->size() > (INT64)LIBRAW_MAX_CR3_RAW_FILE_SIZE) |
476 | 31.8k | ) |
477 | 0 | return LIBRAW_TOO_BIG; |
478 | | |
479 | 31.8k | recycle(); |
480 | 31.8k | if (callbacks.pre_identify_cb) |
481 | 0 | { |
482 | 0 | int r = (callbacks.pre_identify_cb)(this); |
483 | 0 | if (r == 1) |
484 | 0 | goto final; |
485 | 0 | } |
486 | | |
487 | 31.8k | try |
488 | 31.8k | { |
489 | 31.8k | ID.input = stream; |
490 | 31.8k | SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN); |
491 | | |
492 | 31.8k | identify(); |
493 | | |
494 | | // Fuji layout files: either DNG or unpacked_load_raw should be used |
495 | 31.8k | if (libraw_internal_data.internal_output_params.fuji_width || libraw_internal_data.unpacker_data.fuji_layout) |
496 | 86 | { |
497 | 86 | if (!imgdata.idata.dng_version && load_raw != &LibRaw::unpacked_load_raw |
498 | 6 | && load_raw != &LibRaw::unpacked_load_raw_FujiDBP |
499 | 6 | && load_raw != &LibRaw::unpacked_load_raw_fuji_f700s20 |
500 | 86 | ) |
501 | 6 | return LIBRAW_FILE_UNSUPPORTED; |
502 | 86 | } |
503 | | // Remove unsupported Nikon thumbnails |
504 | 31.7k | if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && |
505 | 608 | (!strncasecmp(imgdata.idata.model, "Z 8", 3) || !strcasecmp(imgdata.idata.model, "Z f") |
506 | 588 | || !strncasecmp(imgdata.idata.model, "Z6_3", 4)) |
507 | 22 | && |
508 | 22 | imgdata.thumbs_list.thumbcount > 1) |
509 | 8 | { |
510 | 8 | int tgtidx = 0; |
511 | 24 | for (int idx = 0; idx < imgdata.thumbs_list.thumbcount && idx < LIBRAW_THUMBNAIL_MAXCOUNT; idx++) |
512 | 16 | { |
513 | 16 | int bps = imgdata.thumbs_list.thumblist[idx].tmisc & 0x1f; |
514 | 16 | if (bps > 8) // remove high-bit thumbs |
515 | 8 | { |
516 | | // nothing: just skip this item |
517 | 8 | } |
518 | 8 | else |
519 | 8 | { |
520 | 8 | if (tgtidx < idx) |
521 | 0 | { |
522 | 0 | memmove(&imgdata.thumbs_list.thumblist[tgtidx], &imgdata.thumbs_list.thumblist[idx], |
523 | 0 | sizeof(imgdata.thumbs_list.thumblist[idx])); |
524 | 0 | tgtidx++; |
525 | 0 | } |
526 | 8 | else // same index, just assign next tgtidx |
527 | 8 | tgtidx = idx + 1; |
528 | 8 | } |
529 | 16 | } |
530 | 8 | if (tgtidx > 0 && tgtidx < imgdata.thumbs_list.thumbcount) |
531 | 0 | { |
532 | 0 | int selidx = 0; |
533 | 0 | INT64 maximgbits = INT64(imgdata.thumbs_list.thumblist[0].twidth) * |
534 | 0 | INT64(imgdata.thumbs_list.thumblist[0].theight) * INT64(imgdata.thumbs_list.thumblist[0].tmisc & 0x1f); |
535 | 0 | for (int i = 1; i < tgtidx; i++) |
536 | 0 | { |
537 | 0 | INT64 imgbits = INT64(imgdata.thumbs_list.thumblist[i].twidth) * |
538 | 0 | INT64(imgdata.thumbs_list.thumblist[i].theight) * |
539 | 0 | INT64(imgdata.thumbs_list.thumblist[i].tmisc & 0x1f); |
540 | 0 | if (imgbits > maximgbits) |
541 | 0 | { |
542 | 0 | selidx = i; |
543 | 0 | maximgbits = imgbits; |
544 | 0 | } |
545 | 0 | } |
546 | 0 | libraw_internal_data.internal_data.toffset = imgdata.thumbs_list.thumblist[selidx].toffset; |
547 | 0 | imgdata.thumbnail.tlength = imgdata.thumbs_list.thumblist[selidx].tlength; |
548 | 0 | libraw_internal_data.unpacker_data.thumb_format = imgdata.thumbs_list.thumblist[selidx].tformat; |
549 | 0 | imgdata.thumbnail.twidth = imgdata.thumbs_list.thumblist[selidx].twidth; |
550 | 0 | imgdata.thumbnail.theight = imgdata.thumbs_list.thumblist[selidx].theight; |
551 | 0 | libraw_internal_data.unpacker_data.thumb_misc = imgdata.thumbs_list.thumblist[selidx].tmisc; |
552 | | // find another largest thumb and copy it to single thumbnail data |
553 | 0 | } |
554 | 8 | imgdata.thumbs_list.thumbcount = tgtidx > 0 ? tgtidx : 1; |
555 | 8 | } |
556 | | |
557 | | // promote the old single thumbnail to the thumbs_list if not present already |
558 | 31.7k | if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) |
559 | 18.7k | { |
560 | 18.7k | bool already = false; |
561 | 18.7k | if (imgdata.thumbnail.tlength || libraw_internal_data.internal_data.toffset) |
562 | 2.42k | for (int i = 0; i < imgdata.thumbs_list.thumbcount; i++) |
563 | 366 | if (imgdata.thumbs_list.thumblist[i].toffset == libraw_internal_data.internal_data.toffset |
564 | 316 | && imgdata.thumbs_list.thumblist[i].tlength == imgdata.thumbnail.tlength) |
565 | 310 | { |
566 | 310 | already = true; |
567 | 310 | break; |
568 | 310 | } |
569 | 18.7k | if (!already) |
570 | 18.4k | { |
571 | 18.4k | int idx = imgdata.thumbs_list.thumbcount; |
572 | 18.4k | imgdata.thumbs_list.thumblist[idx].toffset = libraw_internal_data.internal_data.toffset; |
573 | 18.4k | imgdata.thumbs_list.thumblist[idx].tlength = imgdata.thumbnail.tlength; |
574 | 18.4k | imgdata.thumbs_list.thumblist[idx].tflip = 0xffff; |
575 | 18.4k | imgdata.thumbs_list.thumblist[idx].tformat = libraw_internal_data.unpacker_data.thumb_format; |
576 | 18.4k | imgdata.thumbs_list.thumblist[idx].tmisc = libraw_internal_data.unpacker_data.thumb_misc; |
577 | | // promote if set |
578 | 18.4k | imgdata.thumbs_list.thumblist[idx].twidth = imgdata.thumbnail.twidth; |
579 | 18.4k | imgdata.thumbs_list.thumblist[idx].theight = imgdata.thumbnail.theight; |
580 | 18.4k | imgdata.thumbs_list.thumbcount++; |
581 | 18.4k | } |
582 | 18.7k | } |
583 | | |
584 | | |
585 | 31.7k | imgdata.lens.Lens[sizeof(imgdata.lens.Lens) - 1] = 0; // make sure lens is 0-terminated |
586 | | |
587 | 31.7k | if (callbacks.post_identify_cb) |
588 | 0 | (callbacks.post_identify_cb)(this); |
589 | | |
590 | 31.7k | #define isRIC imgdata.sizes.raw_inset_crops[0] |
591 | | |
592 | 31.7k | if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) |
593 | 1.40k | && (!strcmp(imgdata.idata.normalized_model, "S3Pro") |
594 | 1.40k | || !strcmp(imgdata.idata.normalized_model, "S5Pro") |
595 | 1.40k | || !strcmp(imgdata.idata.normalized_model, "S2Pro"))) |
596 | 14 | { |
597 | 14 | isRIC.cleft = isRIC.ctop = 0xffff; |
598 | 14 | isRIC.cwidth = isRIC.cheight = 0; |
599 | 14 | } |
600 | | // Wipe out canon incorrect in-camera crop |
601 | 31.7k | if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Canon) |
602 | 1.26k | && isRIC.cleft == 0 && isRIC.ctop == 0 // non symmetric! |
603 | 8 | && isRIC.cwidth < (imgdata.sizes.raw_width * 4 / 5)) // less than 80% of sensor width |
604 | 2 | { |
605 | 2 | isRIC.cleft = isRIC.ctop = 0xffff; |
606 | 2 | isRIC.cwidth = isRIC.cheight = 0; |
607 | 2 | } |
608 | | |
609 | | // Wipe out non-standard WB |
610 | 31.7k | if (!imgdata.idata.dng_version && |
611 | 15.1k | (makeIs(LIBRAW_CAMERAMAKER_Sony) && !strcmp(imgdata.idata.normalized_model, "DSC-F828")) |
612 | 38 | && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB)) |
613 | 38 | { |
614 | 190 | for (int i = 0; i < 4; i++) imgdata.color.cam_mul[i] = (i == 1); |
615 | 38 | memset(imgdata.color.WB_Coeffs, 0, sizeof(imgdata.color.WB_Coeffs)); |
616 | 38 | memset(imgdata.color.WBCT_Coeffs, 0, sizeof(imgdata.color.WBCT_Coeffs)); |
617 | 38 | } |
618 | | |
619 | 31.7k | if (load_raw == &LibRaw::nikon_load_raw) |
620 | 246 | nikon_read_curve(); |
621 | | |
622 | 31.7k | if (load_raw == &LibRaw::lossless_jpeg_load_raw && |
623 | 1.15k | MN.canon.RecordMode && makeIs(LIBRAW_CAMERAMAKER_Kodak) && |
624 | | /* Not normalized models here, it is intentional */ |
625 | 4 | (!strncasecmp(imgdata.idata.model, "EOS D2000", 9) || // if we want something different for B&W cameras, |
626 | 4 | !strncasecmp(imgdata.idata.model, "EOS D6000", 9))) // it's better to compare with CamIDs |
627 | 2 | { |
628 | 2 | imgdata.color.black = 0; |
629 | 2 | imgdata.color.maximum = 4501; |
630 | 2 | memset(imgdata.color.cblack, 0, sizeof(imgdata.color.cblack)); |
631 | 2 | memset(imgdata.sizes.mask, 0, sizeof(imgdata.sizes.mask)); |
632 | 2 | imgdata.sizes.mask[0][3] = 1; // to skip mask re-calc |
633 | 2 | libraw_internal_data.unpacker_data.load_flags |= 512; |
634 | 2 | } |
635 | | |
636 | 31.7k | if (load_raw == &LibRaw::panasonic_load_raw) |
637 | 86 | { |
638 | 86 | if (libraw_internal_data.unpacker_data.pana_encoding == 6 || |
639 | 86 | libraw_internal_data.unpacker_data.pana_encoding == 7 || |
640 | 86 | libraw_internal_data.unpacker_data.pana_encoding == 8) |
641 | 0 | { |
642 | 0 | for (int i = 0; i < 3; i++) |
643 | 0 | imgdata.color.cblack[i] = |
644 | 0 | libraw_internal_data.internal_data.pana_black[i]; |
645 | 0 | imgdata.color.cblack[3] = imgdata.color.cblack[1]; |
646 | 0 | imgdata.color.cblack[4] = imgdata.color.cblack[5] = 0; |
647 | 0 | imgdata.color.black = 0; |
648 | 0 | imgdata.color.maximum = |
649 | 0 | MAX(imgdata.color.linear_max[0], |
650 | 0 | MAX(imgdata.color.linear_max[1], imgdata.color.linear_max[2])); |
651 | 0 | } |
652 | | |
653 | 86 | if (libraw_internal_data.unpacker_data.pana_encoding == 6) |
654 | 0 | { |
655 | 0 | int rowbytes11 = imgdata.sizes.raw_width / 11 * 16; |
656 | 0 | int rowbytes14 = imgdata.sizes.raw_width / 14 * 16; |
657 | 0 | INT64 ds = INT64(libraw_internal_data.unpacker_data.data_size); |
658 | 0 | if (!ds) |
659 | 0 | ds = libraw_internal_data.internal_data.input->size() - libraw_internal_data.unpacker_data.data_offset; |
660 | 0 | if ((imgdata.sizes.raw_width % 11) == 0 && |
661 | 0 | (INT64(imgdata.sizes.raw_height) * rowbytes11 == ds)) |
662 | 0 | load_raw = &LibRaw::panasonicC6_load_raw; |
663 | 0 | else if ((imgdata.sizes.raw_width % 14) == 0 && |
664 | 0 | (INT64(imgdata.sizes.raw_height) * rowbytes14 == ds)) |
665 | 0 | load_raw = &LibRaw::panasonicC6_load_raw; |
666 | 0 | else |
667 | 0 | imgdata.idata.raw_count = 0; // incorrect size |
668 | 0 | } |
669 | 86 | else if (libraw_internal_data.unpacker_data.pana_encoding == 7) |
670 | 0 | { |
671 | 0 | int pixperblock = |
672 | 0 | libraw_internal_data.unpacker_data.pana_bpp == 14 ? 9 : 10; |
673 | 0 | int rowbytes = imgdata.sizes.raw_width / pixperblock * 16; |
674 | 0 | if ((imgdata.sizes.raw_width % pixperblock) == 0 && |
675 | 0 | (INT64(imgdata.sizes.raw_height) * rowbytes == |
676 | 0 | INT64(libraw_internal_data.unpacker_data.data_size))) |
677 | 0 | load_raw = &LibRaw::panasonicC7_load_raw; |
678 | 0 | else |
679 | 0 | imgdata.idata.raw_count = 0; // incorrect size |
680 | 0 | } |
681 | 86 | else if (libraw_internal_data.unpacker_data.pana_encoding == 8) |
682 | 0 | { |
683 | 0 | if (libraw_internal_data.unpacker_data.pana8.stripe_count > 0) |
684 | 0 | load_raw = &LibRaw::panasonicC8_load_raw; |
685 | 0 | else |
686 | 0 | imgdata.idata.raw_count = 0; // incorrect stripes count |
687 | 0 | } |
688 | 86 | } |
689 | | |
690 | 31.7k | #define NIKON_14BIT_SIZE(rw, rh) \ |
691 | 31.7k | (((unsigned)(ceilf((float)(rw * 7 / 4) / 16.f)) * 16) * rh) |
692 | | |
693 | 31.7k | #define NIKON_14BIT_SIZE3COLOR(rw, rh) ( ceilf(float(rw * 21 / 4)/16.f) * 16 * rh) |
694 | | |
695 | | // Ugly hack, replace with proper data/line size for different |
696 | | // cameras/format when available |
697 | 31.7k | if (makeIs(LIBRAW_CAMERAMAKER_Nikon) |
698 | 608 | && (!strncasecmp(imgdata.idata.model, "Z", 1) || !strcasecmp(imgdata.idata.model, "D6")) |
699 | 31.7k | ) |
700 | 32 | { |
701 | 32 | if (NIKON_14BIT_SIZE(imgdata.sizes.raw_width, imgdata.sizes.raw_height) == |
702 | 32 | libraw_internal_data.unpacker_data.data_size) |
703 | 12 | { |
704 | 12 | load_raw = &LibRaw::nikon_14bit_load_raw; |
705 | 12 | } |
706 | 32 | if (NIKON_14BIT_SIZE3COLOR(imgdata.sizes.raw_width, imgdata.sizes.raw_height) == |
707 | 32 | libraw_internal_data.unpacker_data.data_size) |
708 | 12 | { |
709 | 12 | load_raw = &LibRaw::nikon_14bit_load_raw; |
710 | 12 | imgdata.idata.filters = 0; // 3-color nefx image |
711 | 12 | } |
712 | 32 | } |
713 | 31.7k | #undef NIKON_14BIT_SIZE |
714 | 31.7k | #undef NIKON_14BIT_SIZE3COLOR |
715 | | |
716 | | // Linear max from 14-bit camera, but on 12-bit data? |
717 | 31.7k | if (makeIs(LIBRAW_CAMERAMAKER_Sony) && |
718 | 1.42k | imgdata.color.maximum > 0 && |
719 | 752 | imgdata.color.linear_max[0] > imgdata.color.maximum && |
720 | 6 | imgdata.color.linear_max[0] <= imgdata.color.maximum * 4) |
721 | 10 | for (int c = 0; c < 4; c++) |
722 | 8 | imgdata.color.linear_max[c] /= 4; |
723 | | |
724 | 31.7k | if (makeIs(LIBRAW_CAMERAMAKER_Canon)) |
725 | 1.64k | { |
726 | 1.64k | if (!imgdata.idata.dng_version && (MN.canon.DefaultCropAbsolute.l != -1)) // tag 0x00e0 SensorInfo was parsed |
727 | 180 | { |
728 | 180 | if (imgdata.sizes.raw_aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN) |
729 | 14 | { // tag 0x009a AspectInfo was parsed |
730 | 14 | isRIC.cleft += MN.canon.DefaultCropAbsolute.l; |
731 | 14 | isRIC.ctop += MN.canon.DefaultCropAbsolute.t; |
732 | 14 | } |
733 | 166 | else |
734 | 166 | { |
735 | 166 | isRIC.cleft = MN.canon.DefaultCropAbsolute.l; |
736 | 166 | isRIC.ctop = MN.canon.DefaultCropAbsolute.t; |
737 | 166 | isRIC.cwidth = MN.canon.DefaultCropAbsolute.r - MN.canon.DefaultCropAbsolute.l + 1; |
738 | 166 | isRIC.cheight = MN.canon.DefaultCropAbsolute.b - MN.canon.DefaultCropAbsolute.t + 1; |
739 | 166 | } |
740 | 180 | } |
741 | 1.46k | else |
742 | 1.46k | { |
743 | 1.46k | if (imgdata.sizes.raw_aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN) |
744 | 50 | { |
745 | 50 | } |
746 | 1.41k | else |
747 | 1.41k | { // Canon PowerShot S2 IS |
748 | 1.41k | } |
749 | 1.46k | } |
750 | 1.64k | #undef isRIC |
751 | 1.64k | if (imgdata.color.raw_bps < 14 && !imgdata.idata.dng_version && load_raw != &LibRaw::canon_sraw_load_raw) |
752 | 1.18k | { |
753 | 1.18k | int xmax = (1 << imgdata.color.raw_bps) - 1; |
754 | 1.18k | if (MN.canon.SpecularWhiteLevel > xmax) // Adjust 14-bit metadata to real bps |
755 | 50 | { |
756 | 50 | int div = 1 << (14 - imgdata.color.raw_bps); |
757 | 250 | for (int c = 0; c < 4; c++) imgdata.color.linear_max[c] /= div; |
758 | 250 | for (int c = 0; c < 4; c++) MN.canon.ChannelBlackLevel[c] /= div; |
759 | 50 | MN.canon.AverageBlackLevel /= div; |
760 | 50 | MN.canon.SpecularWhiteLevel /= div; |
761 | 50 | MN.canon.NormalWhiteLevel /= div; |
762 | 50 | } |
763 | 1.18k | } |
764 | 1.64k | } |
765 | | |
766 | 31.7k | if (makeIs(LIBRAW_CAMERAMAKER_Canon) && |
767 | 1.64k | (load_raw == &LibRaw::canon_sraw_load_raw) && |
768 | 72 | imgdata.sizes.raw_width > 0) |
769 | 70 | { |
770 | 70 | float ratio = |
771 | 70 | float(imgdata.sizes.raw_height) / float(imgdata.sizes.raw_width); |
772 | 70 | if ((ratio < 0.57 || ratio > 0.75) && |
773 | 44 | MN.canon.SensorHeight > 1 && |
774 | 42 | MN.canon.SensorWidth > 1) |
775 | 34 | { |
776 | 34 | imgdata.sizes.raw_width = MN.canon.SensorWidth; |
777 | 34 | imgdata.sizes.left_margin = MN.canon.DefaultCropAbsolute.l; |
778 | 34 | imgdata.sizes.iwidth = imgdata.sizes.width = |
779 | 34 | MN.canon.DefaultCropAbsolute.r - MN.canon.DefaultCropAbsolute.l + 1; |
780 | 34 | imgdata.sizes.raw_height = MN.canon.SensorHeight; |
781 | 34 | imgdata.sizes.top_margin = MN.canon.DefaultCropAbsolute.t; |
782 | 34 | imgdata.sizes.iheight = imgdata.sizes.height = |
783 | 34 | MN.canon.DefaultCropAbsolute.b - MN.canon.DefaultCropAbsolute.t + 1; |
784 | 34 | libraw_internal_data.unpacker_data.load_flags |= |
785 | 34 | 256; // reset width/height in canon_sraw_load_raw() |
786 | 34 | imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width; |
787 | 34 | } |
788 | 36 | else if (imgdata.sizes.raw_width == 4032 && |
789 | 0 | imgdata.sizes.raw_height == 3402 && |
790 | 0 | !strcasecmp(imgdata.idata.model, "EOS 80D")) // 80D hardcoded |
791 | 0 | { |
792 | 0 | imgdata.sizes.raw_width = 4536; |
793 | 0 | imgdata.sizes.left_margin = 28; |
794 | 0 | imgdata.sizes.iwidth = imgdata.sizes.width = |
795 | 0 | imgdata.sizes.raw_width - imgdata.sizes.left_margin; |
796 | 0 | imgdata.sizes.raw_height = 3024; |
797 | 0 | imgdata.sizes.top_margin = 8; |
798 | 0 | imgdata.sizes.iheight = imgdata.sizes.height = |
799 | 0 | imgdata.sizes.raw_height - imgdata.sizes.top_margin; |
800 | 0 | libraw_internal_data.unpacker_data.load_flags |= 256; |
801 | 0 | imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width; |
802 | 0 | } |
803 | 70 | } |
804 | | |
805 | | #ifdef USE_DNGSDK |
806 | | if (imgdata.idata.dng_version |
807 | | &&libraw_internal_data.unpacker_data.tiff_compress == 34892 |
808 | | && libraw_internal_data.unpacker_data.tiff_bps == 8 |
809 | | && libraw_internal_data.unpacker_data.tiff_samples == 3 |
810 | | && load_raw == &LibRaw::lossy_dng_load_raw) |
811 | | { |
812 | | // Data should be linearized by DNG SDK |
813 | | C.black = 0; |
814 | | memset(C.cblack, 0, sizeof(C.cblack)); |
815 | | } |
816 | | #endif |
817 | | |
818 | | // XTrans Compressed? |
819 | 31.7k | if (!imgdata.idata.dng_version && |
820 | 15.1k | makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && |
821 | 1.40k | (load_raw == &LibRaw::unpacked_load_raw)) |
822 | 1.30k | { |
823 | 1.30k | if (imgdata.sizes.raw_width * (imgdata.sizes.raw_height * 2ul) != |
824 | 1.30k | libraw_internal_data.unpacker_data.data_size) |
825 | 1.26k | { |
826 | 1.26k | if ((imgdata.sizes.raw_width * (imgdata.sizes.raw_height * 7ul)) / 4 == |
827 | 1.26k | libraw_internal_data.unpacker_data.data_size) |
828 | 0 | load_raw = &LibRaw::fuji_14bit_load_raw; |
829 | 1.26k | else |
830 | 1.26k | parse_fuji_compressed_header(); |
831 | 1.26k | } |
832 | 42 | else if (!strcmp(imgdata.idata.normalized_model, "X-H2S") |
833 | 8 | && libraw_internal_data.internal_data.input->size() |
834 | 8 | < (libraw_internal_data.unpacker_data.data_size + libraw_internal_data.unpacker_data.data_offset)) |
835 | 6 | { |
836 | 6 | parse_fuji_compressed_header(); // try to use compressed header: X-H2S may record wrong data size |
837 | 6 | } |
838 | 1.30k | } |
839 | | // set raw_inset_crops[1] via raw_aspect |
840 | 31.7k | if (imgdata.sizes.raw_aspect >= LIBRAW_IMAGE_ASPECT_MINIMAL_REAL_ASPECT_VALUE |
841 | 262 | && imgdata.sizes.raw_aspect <= LIBRAW_IMAGE_ASPECT_MAXIMAL_REAL_ASPECT_VALUE |
842 | | /* crops[0] is valid*/ |
843 | 262 | && (imgdata.sizes.raw_inset_crops[0].cleft < 0xffff) |
844 | 56 | && (imgdata.sizes.raw_inset_crops[0].cleft + imgdata.sizes.raw_inset_crops[0].cwidth <= imgdata.sizes.raw_width) |
845 | 28 | && (imgdata.sizes.raw_inset_crops[0].ctop < 0xffff) |
846 | 26 | && (imgdata.sizes.raw_inset_crops[0].ctop + imgdata.sizes.raw_inset_crops[0].cheight <= imgdata.sizes.raw_height) |
847 | 10 | && imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cheight >0 |
848 | | /* crops[1] is not set*/ |
849 | 8 | && (imgdata.sizes.raw_inset_crops[1].cleft == 0xffff) |
850 | 8 | && (imgdata.sizes.raw_inset_crops[1].ctop == 0xffff) |
851 | 31.7k | ) |
852 | 8 | { |
853 | 8 | float c0_ratio = float(imgdata.sizes.raw_inset_crops[0].cwidth) / float(imgdata.sizes.raw_inset_crops[0].cheight); |
854 | 8 | float c1_ratio = float(imgdata.sizes.raw_aspect) / 1000.f; |
855 | 8 | if (c0_ratio / c1_ratio < 0.98 || c0_ratio / c1_ratio > 1.02) // set crops[1] |
856 | 6 | { |
857 | 6 | if (c1_ratio > c0_ratio) // requested image is wider, cut from top/bottom |
858 | 2 | { |
859 | 2 | int newheight = int(imgdata.sizes.raw_inset_crops[0].cwidth / c1_ratio); |
860 | 2 | int dtop = (imgdata.sizes.raw_inset_crops[0].cheight - newheight) / 2; |
861 | 2 | imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop + dtop; |
862 | 2 | imgdata.sizes.raw_inset_crops[1].cheight = newheight; |
863 | 2 | imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft; |
864 | 2 | imgdata.sizes.raw_inset_crops[1].cwidth = imgdata.sizes.raw_inset_crops[0].cwidth; |
865 | 2 | } |
866 | 4 | else |
867 | 4 | { |
868 | 4 | int newwidth = int(imgdata.sizes.raw_inset_crops[0].cheight * c1_ratio); |
869 | 4 | int dleft = (imgdata.sizes.raw_inset_crops[0].cwidth - newwidth) / 2; |
870 | 4 | imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft + dleft; |
871 | 4 | imgdata.sizes.raw_inset_crops[1].cwidth = newwidth; |
872 | 4 | imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop; |
873 | 4 | imgdata.sizes.raw_inset_crops[1].cheight = imgdata.sizes.raw_inset_crops[0].cheight; |
874 | 4 | } |
875 | 6 | } |
876 | 8 | } |
877 | | |
878 | 31.7k | int adjust_margins = 0; |
879 | 31.7k | if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && (imgdata.idata.filters == 9)) |
880 | 10 | { |
881 | | // Adjust top/left margins for X-Trans |
882 | 10 | int newtm = imgdata.sizes.top_margin % 6 |
883 | 10 | ? (imgdata.sizes.top_margin / 6 + 1) * 6 |
884 | 10 | : imgdata.sizes.top_margin; |
885 | 10 | int newlm = imgdata.sizes.left_margin % 6 |
886 | 10 | ? (imgdata.sizes.left_margin / 6 + 1) * 6 |
887 | 10 | : imgdata.sizes.left_margin; |
888 | 10 | if (newtm != imgdata.sizes.top_margin || |
889 | 8 | newlm != imgdata.sizes.left_margin) |
890 | 2 | { |
891 | 2 | imgdata.sizes.height -= (newtm - imgdata.sizes.top_margin); |
892 | 2 | imgdata.sizes.top_margin = newtm; |
893 | 2 | imgdata.sizes.width -= (newlm - imgdata.sizes.left_margin); |
894 | 2 | imgdata.sizes.left_margin = newlm; |
895 | 14 | for (int c1 = 0; c1 < 6; c1++) |
896 | 84 | for (int c2 = 0; c2 < 6; c2++) |
897 | 72 | imgdata.idata.xtrans[c1][c2] = imgdata.idata.xtrans_abs[c1][c2]; |
898 | 2 | } |
899 | 10 | adjust_margins = 6; |
900 | 10 | } |
901 | 31.7k | else if (!libraw_internal_data.internal_output_params.fuji_width |
902 | 18.6k | && imgdata.idata.filters >= 1000) |
903 | 17.1k | { |
904 | 17.1k | if ((imgdata.sizes.top_margin % 2) || (imgdata.sizes.left_margin % 2)) |
905 | 282 | { |
906 | 282 | int crop[2] = { 0,0 }; |
907 | 282 | unsigned filt; |
908 | 282 | int c; |
909 | 282 | if (imgdata.sizes.top_margin % 2) |
910 | 150 | { |
911 | 150 | imgdata.sizes.top_margin += 1; |
912 | 150 | imgdata.sizes.height -= 1; |
913 | 150 | crop[1] = 1; |
914 | 150 | } |
915 | 282 | if (imgdata.sizes.left_margin % 2) |
916 | 234 | { |
917 | 234 | imgdata.sizes.left_margin += 1; |
918 | 234 | imgdata.sizes.width -= 1; |
919 | 234 | crop[0] = 1; |
920 | 234 | } |
921 | 4.79k | for (filt = c = 0; c < 16; c++) |
922 | 4.51k | filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2; |
923 | 282 | imgdata.idata.filters = filt; |
924 | 282 | } |
925 | 17.1k | adjust_margins = 2; |
926 | 17.1k | } |
927 | | |
928 | 31.7k | if(adjust_margins) // adjust crop_inset margins |
929 | 51.4k | for (int i = 0; i < 2; i++) |
930 | 34.3k | { |
931 | 34.3k | if (imgdata.sizes.raw_inset_crops[i].cleft && imgdata.sizes.raw_inset_crops[i].cleft < 0xffff |
932 | 284 | && imgdata.sizes.raw_inset_crops[i].cwidth && imgdata.sizes.raw_inset_crops[i].cwidth < 0xffff |
933 | 150 | && (imgdata.sizes.raw_inset_crops[i].cleft%adjust_margins) |
934 | 32 | && (imgdata.sizes.raw_inset_crops[i].cwidth > adjust_margins)) |
935 | 28 | { |
936 | 28 | int newleft = ((imgdata.sizes.raw_inset_crops[i].cleft / adjust_margins) + 1) * adjust_margins; |
937 | 28 | int diff = newleft - imgdata.sizes.raw_inset_crops[i].cleft; |
938 | 28 | if (diff > 0) |
939 | 28 | { |
940 | 28 | imgdata.sizes.raw_inset_crops[i].cleft += diff; |
941 | 28 | imgdata.sizes.raw_inset_crops[i].cwidth -= diff; |
942 | 28 | } |
943 | 28 | } |
944 | 34.3k | if (imgdata.sizes.raw_inset_crops[i].ctop && imgdata.sizes.raw_inset_crops[i].ctop < 0xffff |
945 | 384 | && imgdata.sizes.raw_inset_crops[i].cheight && imgdata.sizes.raw_inset_crops[i].cheight < 0xffff |
946 | 174 | && (imgdata.sizes.raw_inset_crops[i].ctop%adjust_margins) |
947 | 50 | && (imgdata.sizes.raw_inset_crops[i].cheight > adjust_margins)) |
948 | 40 | { |
949 | 40 | int newtop = ((imgdata.sizes.raw_inset_crops[i].ctop / adjust_margins) + 1) * adjust_margins; |
950 | 40 | int diff = newtop - imgdata.sizes.raw_inset_crops[i].ctop; |
951 | 40 | if (diff > 0) |
952 | 40 | { |
953 | 40 | imgdata.sizes.raw_inset_crops[i].ctop += diff; |
954 | 40 | imgdata.sizes.raw_inset_crops[i].cheight -= diff; |
955 | 40 | } |
956 | 40 | } |
957 | 34.3k | } |
958 | | |
959 | | |
960 | | #ifdef USE_DNGSDK |
961 | | if ( |
962 | | imgdata.rawparams.use_dngsdk && |
963 | | !(imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2 | LIBRAW_RAWOPTIONS_DNG_STAGE3 | LIBRAW_RAWOPTIONS_DNG_DISABLEWBADJUST))) |
964 | | #endif |
965 | 31.7k | { |
966 | | // Fix DNG white balance if needed: observed only for Kalpanika X3F tools produced DNGs |
967 | 31.7k | if (imgdata.idata.dng_version && (imgdata.idata.filters == 0) && |
968 | 517 | imgdata.idata.colors > 1 && imgdata.idata.colors < 5) |
969 | 346 | { |
970 | 346 | float delta[4] = { 0.f, 0.f, 0.f, 0.f }; |
971 | 346 | int black[4]; |
972 | 1.73k | for (int c = 0; c < 4; c++) |
973 | 1.38k | black[c] = imgdata.color.dng_levels.dng_black + |
974 | 1.38k | imgdata.color.dng_levels.dng_cblack[c]; |
975 | 1.43k | for (int c = 0; c < imgdata.idata.colors; c++) |
976 | 1.08k | delta[c] = float(imgdata.color.dng_levels.dng_whitelevel[c] - black[c]); |
977 | 346 | float mindelta = delta[0], maxdelta = delta[0]; |
978 | 1.08k | for (int c = 1; c < imgdata.idata.colors; c++) |
979 | 740 | { |
980 | 740 | if (mindelta > delta[c]) |
981 | 46 | mindelta = delta[c]; |
982 | 740 | if (maxdelta < delta[c]) |
983 | 14 | maxdelta = delta[c]; |
984 | 740 | } |
985 | 346 | if (mindelta > 1 && maxdelta < (mindelta * 20)) // safety |
986 | 100 | { |
987 | 392 | for (int c = 0; c < imgdata.idata.colors; c++) |
988 | 292 | { |
989 | 292 | imgdata.color.cam_mul[c] /= (delta[c] / maxdelta); |
990 | 292 | imgdata.color.pre_mul[c] /= (delta[c] / maxdelta); |
991 | 292 | } |
992 | 100 | imgdata.color.maximum = unsigned(imgdata.color.cblack[0] + maxdelta); |
993 | 100 | } |
994 | 346 | } |
995 | 31.7k | } |
996 | | |
997 | 31.7k | if (imgdata.idata.dng_version && |
998 | 3.66k | makeIs(LIBRAW_CAMERAMAKER_Panasonic) |
999 | 2 | && !strcasecmp(imgdata.idata.normalized_model, "DMC-LX100")) |
1000 | 0 | imgdata.sizes.width = 4288; |
1001 | | |
1002 | 31.7k | if (imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Leica)) |
1003 | 46 | { |
1004 | 46 | if (!strcasecmp(imgdata.idata.normalized_model, "SL2")) |
1005 | 0 | imgdata.sizes.height -= 16; |
1006 | 46 | else if (!strcasecmp(imgdata.idata.normalized_model, "SL3")) |
1007 | 0 | { |
1008 | 0 | if (imgdata.sizes.raw_width == 9536) |
1009 | 0 | imgdata.sizes.width -= 12; |
1010 | 0 | else if (imgdata.sizes.raw_width == 7424) |
1011 | 0 | imgdata.sizes.width -= 14; |
1012 | 0 | else if (imgdata.sizes.raw_width == 5312) |
1013 | 0 | imgdata.sizes.width -= 18; |
1014 | 0 | } |
1015 | 46 | } |
1016 | | |
1017 | 31.7k | if (makeIs(LIBRAW_CAMERAMAKER_Sony) && |
1018 | 1.42k | imgdata.idata.dng_version) |
1019 | 428 | { |
1020 | 428 | if (S.raw_width == 3984) |
1021 | 0 | S.width = 3925; |
1022 | 428 | else if (S.raw_width == 4288) |
1023 | 0 | S.width = S.raw_width - 32; |
1024 | 428 | else if (S.raw_width == 4928 && S.height < 3280) |
1025 | 0 | S.width = S.raw_width - 8; |
1026 | 428 | else if (S.raw_width == 5504) |
1027 | 0 | S.width = S.raw_width - (S.height > 3664 ? 8 : 32); |
1028 | 428 | } |
1029 | | |
1030 | 31.7k | if (makeIs(LIBRAW_CAMERAMAKER_Sony) && |
1031 | 1.42k | !imgdata.idata.dng_version) |
1032 | 998 | { |
1033 | 998 | if(load_raw ==&LibRaw::sony_arq_load_raw) |
1034 | 0 | { |
1035 | 0 | if(S.raw_width > 12000) // A7RM4 16x, both APS-C and APS |
1036 | 0 | S.width = S.raw_width - 64; |
1037 | 0 | else // A7RM3/M4 4x merge |
1038 | 0 | S.width = S.raw_width - 32; |
1039 | 0 | } |
1040 | | |
1041 | 998 | if (((!strncasecmp(imgdata.idata.model, "ILCE-7RM", 8) || |
1042 | 982 | !strcasecmp(imgdata.idata.model, "ILCA-99M2")) && |
1043 | 22 | (S.raw_width == 5216 || S.raw_width == 6304)) // A7RM2/M3/A99M2 in APS mode; A7RM4 in APS-C |
1044 | 998 | || |
1045 | 998 | (!strcasecmp(imgdata.idata.model, "ILCE-7R") && S.raw_width >= 4580 && |
1046 | 0 | S.raw_width < 5020) // A7R in crop mode, no samples, so size est. |
1047 | 998 | || (!strcasecmp(imgdata.idata.model, "ILCE-7") && |
1048 | 2 | S.raw_width == 3968) // A7 in crop mode |
1049 | 998 | || |
1050 | 998 | ((!strncasecmp(imgdata.idata.model, "ILCE-7M", 7) || |
1051 | 988 | !strcasecmp(imgdata.idata.model, "ILCE-9") || |
1052 | | #if 0 |
1053 | | !strcasecmp(imgdata.idata.model, |
1054 | | "SLT-A99V")) // Does SLT-A99 also have APS-C mode?? |
1055 | | #endif |
1056 | 980 | (mnCamID == SonyID_SLT_A99)) // 2 reasons: some cameras are SLT-A99, no 'V'; some are Hasselblad HV |
1057 | 18 | && S.raw_width > 3750 && |
1058 | 4 | S.raw_width < 4120) // A7M2, A7M3, AA9, most likely APS-C raw_width |
1059 | | // is 3968 (same w/ A7), but no samples, so guess |
1060 | 996 | || (!strncasecmp(imgdata.idata.model, "ILCE-7S", 7) && |
1061 | 10 | S.raw_width == 2816) // A7S2=> exact, hope it works for A7S-I too |
1062 | 998 | ) |
1063 | 2 | S.width = S.raw_width - 32; |
1064 | 998 | } |
1065 | | |
1066 | | |
1067 | | // FIXME: it is possible that DNG contains 4x main frames + some previews; in this case imgdata.idata.raw_count will be greater than 4 |
1068 | 31.7k | if (makeIs(LIBRAW_CAMERAMAKER_Pentax) && |
1069 | | /*!strcasecmp(imgdata.idata.model,"K-3 II") &&*/ |
1070 | 340 | imgdata.idata.raw_count == 4 && |
1071 | 0 | (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES)) |
1072 | 0 | { |
1073 | 0 | imgdata.idata.raw_count = 1; |
1074 | 0 | imgdata.idata.filters = 0; |
1075 | 0 | imgdata.idata.colors = 4; |
1076 | 0 | imgdata.sizes.top_margin+=2; |
1077 | 0 | imgdata.sizes.left_margin+=2; |
1078 | 0 | imgdata.sizes.width-=4; |
1079 | 0 | imgdata.sizes.height-=4; |
1080 | 0 | IO.mix_green = 1; |
1081 | 0 | pentax_component_load_raw = load_raw; |
1082 | 0 | load_raw = &LibRaw::pentax_4shot_load_raw; |
1083 | 0 | } |
1084 | | |
1085 | 31.7k | if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Leaf) && |
1086 | 224 | !strcmp(imgdata.idata.model, "Credo 50")) |
1087 | 4 | { |
1088 | 4 | imgdata.color.pre_mul[0] = 1.f / 0.3984f; |
1089 | 4 | imgdata.color.pre_mul[2] = 1.f / 0.7666f; |
1090 | 4 | imgdata.color.pre_mul[1] = imgdata.color.pre_mul[3] = 1.0; |
1091 | 4 | } |
1092 | | |
1093 | 31.7k | if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && |
1094 | 1.40k | (!strncmp(imgdata.idata.model, "S20Pro", 6) || |
1095 | 1.39k | !strncmp(imgdata.idata.model, "F700", 4))) |
1096 | 44 | { |
1097 | 44 | imgdata.sizes.raw_width /= 2; |
1098 | 44 | load_raw = &LibRaw::unpacked_load_raw_fuji_f700s20; |
1099 | 44 | } |
1100 | | |
1101 | 31.7k | if (load_raw == &LibRaw::packed_load_raw && |
1102 | 498 | makeIs(LIBRAW_CAMERAMAKER_Nikon) && |
1103 | 226 | !libraw_internal_data.unpacker_data.load_flags && |
1104 | 174 | (!strncasecmp(imgdata.idata.model, "D810", 4) || |
1105 | 170 | !strcasecmp(imgdata.idata.model, "D4S")) && |
1106 | 4 | libraw_internal_data.unpacker_data.data_size * 2u == |
1107 | 4 | imgdata.sizes.raw_height * imgdata.sizes.raw_width * 3u) |
1108 | 2 | { |
1109 | 2 | libraw_internal_data.unpacker_data.load_flags = 80; |
1110 | 2 | } |
1111 | | // Adjust BL for Sony A900/A850 |
1112 | 31.7k | if (load_raw == &LibRaw::packed_load_raw && |
1113 | 498 | makeIs(LIBRAW_CAMERAMAKER_Sony)) // 12 bit sony, but metadata may be for 14-bit range |
1114 | 102 | { |
1115 | 102 | if (C.maximum > 4095) |
1116 | 36 | C.maximum = 4095; |
1117 | 102 | if (C.black > 256 || C.cblack[0] > 256) |
1118 | 4 | { |
1119 | 4 | C.black /= 4; |
1120 | 20 | for (int c = 0; c < 4; c++) |
1121 | 16 | C.cblack[c] /= 4; |
1122 | 6.06k | for (unsigned c = 0; c < C.cblack[4] * C.cblack[5]; c++) |
1123 | 6.05k | C.cblack[6 + c] /= 4; |
1124 | 4 | } |
1125 | 102 | } |
1126 | | |
1127 | 31.7k | if (load_raw == &LibRaw::nikon_yuv_load_raw) // Is it Nikon sRAW? |
1128 | 120 | { |
1129 | 120 | load_raw = &LibRaw::nikon_load_sraw; |
1130 | 120 | C.black = 0; |
1131 | 120 | memset(C.cblack, 0, sizeof(C.cblack)); |
1132 | 120 | imgdata.idata.filters = 0; |
1133 | 120 | libraw_internal_data.unpacker_data.tiff_samples = 3; |
1134 | 120 | imgdata.idata.colors = 3; |
1135 | 120 | double beta_1 = -5.79342238397656E-02; |
1136 | 120 | double beta_2 = 3.28163551282665; |
1137 | 120 | double beta_3 = -8.43136004842678; |
1138 | 120 | double beta_4 = 1.03533181861023E+01; |
1139 | 368k | for (int i = 0; i <= 3072; i++) |
1140 | 368k | { |
1141 | 368k | double x = (double)i / 3072.; |
1142 | 368k | double y = (1. - exp(-beta_1 * x - beta_2 * x * x - beta_3 * x * x * x - |
1143 | 368k | beta_4 * x * x * x * x)); |
1144 | 368k | if (y < 0.) |
1145 | 6.72k | y = 0.; |
1146 | 368k | imgdata.color.curve[i] = ushort(y * 16383.f); |
1147 | 368k | } |
1148 | 480 | for (int i = 0; i < 3; i++) |
1149 | 1.80k | for (int j = 0; j < 4; j++) |
1150 | 1.44k | imgdata.color.rgb_cam[i][j] = float(i == j); |
1151 | 120 | } |
1152 | | // Adjust BL for Nikon 12bit |
1153 | 31.7k | if ((load_raw == &LibRaw::nikon_load_raw || |
1154 | 18.5k | load_raw == &LibRaw::packed_load_raw || |
1155 | 18.0k | load_raw == &LibRaw::nikon_load_padded_packed_raw) && |
1156 | 736 | makeIs(LIBRAW_CAMERAMAKER_Nikon) && |
1157 | 232 | strncmp(imgdata.idata.model, "COOLPIX", 7) && |
1158 | 208 | libraw_internal_data.unpacker_data.tiff_bps == 12) |
1159 | 44 | { |
1160 | 44 | C.maximum = 4095; |
1161 | 44 | C.black /= 4; |
1162 | 220 | for (int c = 0; c < 4; c++) |
1163 | 176 | C.cblack[c] /= 4; |
1164 | 828 | for (unsigned c = 0; c < C.cblack[4] * C.cblack[5]; c++) |
1165 | 784 | C.cblack[6 + c] /= 4; |
1166 | 44 | } |
1167 | | |
1168 | | // Adjust wb_already_applied |
1169 | 31.7k | if (load_raw == &LibRaw::nikon_load_sraw) |
1170 | 120 | imgdata.color.as_shot_wb_applied = |
1171 | 120 | LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON_SRAW; |
1172 | 31.6k | else if (makeIs(LIBRAW_CAMERAMAKER_Canon) && |
1173 | 1.64k | MN.canon.multishot[0] >= 8 && |
1174 | 18 | MN.canon.multishot[1] > 0) |
1175 | 18 | imgdata.color.as_shot_wb_applied = |
1176 | 18 | LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_CANON; |
1177 | 31.6k | else if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && |
1178 | 602 | MN.nikon.ExposureMode == 1) |
1179 | 2 | imgdata.color.as_shot_wb_applied = |
1180 | 2 | LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON; |
1181 | 31.6k | else if (makeIs(LIBRAW_CAMERAMAKER_Pentax) && |
1182 | 340 | ((MN.pentax.MultiExposure & 0x01) == 1)) |
1183 | 4 | imgdata.color.as_shot_wb_applied = |
1184 | 4 | LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_PENTAX; |
1185 | 31.6k | else if (makeIs(LIBRAW_CAMERAMAKER_Sony) && load_raw == &LibRaw::sony_ycbcr_load_raw) |
1186 | 0 | imgdata.color.as_shot_wb_applied = LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_SONY; |
1187 | 31.6k | else |
1188 | 31.6k | imgdata.color.as_shot_wb_applied = 0; |
1189 | | |
1190 | | // Adjust Highlight Linearity limit |
1191 | 31.7k | if (C.linear_max[0] < 0) |
1192 | 0 | { |
1193 | 0 | if (imgdata.idata.dng_version) |
1194 | 0 | { |
1195 | 0 | for (int c = 0; c < 4; c++) |
1196 | 0 | C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c + 6]; |
1197 | 0 | } |
1198 | 0 | else |
1199 | 0 | { |
1200 | 0 | for (int c = 0; c < 4; c++) |
1201 | 0 | C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c]; |
1202 | 0 | } |
1203 | 0 | } |
1204 | | |
1205 | 31.7k | if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && |
1206 | 608 | (!C.linear_max[0]) && (C.maximum > 1024) && (load_raw != &LibRaw::nikon_load_sraw)) |
1207 | 332 | { |
1208 | 332 | C.linear_max[0] = C.linear_max[1] = C.linear_max[2] = C.linear_max[3] = |
1209 | 332 | (long)((float)(C.maximum) / 1.07f); |
1210 | 332 | } |
1211 | | |
1212 | | // Correct WB for Samsung GX20 |
1213 | 31.7k | if ( |
1214 | | #if 0 |
1215 | | /* GX20 should be corrected, but K20 is not */ |
1216 | | makeIs(LIBRAW_CAMERAMAKER_Pentax) && |
1217 | | !strcasecmp(imgdata.idata.normalized_model, "K20D") |
1218 | | #endif |
1219 | | #if 0 |
1220 | | !strcasecmp(imgdata.idata.make, "Samsung") && |
1221 | | !strcasecmp(imgdata.idata.model, "GX20") |
1222 | | #endif |
1223 | 31.7k | makeIs(LIBRAW_CAMERAMAKER_Pentax) && |
1224 | 340 | (mnCamID == PentaxID_GX20) // Samsung rebranding |
1225 | 31.7k | ) |
1226 | 4 | { |
1227 | 104 | for (int cnt = LIBRAW_WBI_Unknown; cnt <= LIBRAW_WBI_StudioTungsten; cnt++) { |
1228 | 100 | if (C.WB_Coeffs[cnt][1]) { |
1229 | 36 | C.WB_Coeffs[cnt][0] = (int)((float)(C.WB_Coeffs[cnt][0]) * 1.0503f); |
1230 | 36 | C.WB_Coeffs[cnt][2] = (int)((float)(C.WB_Coeffs[cnt][2]) * 2.2867f); |
1231 | 36 | } |
1232 | 100 | } |
1233 | 260 | for (int cnt = 0; cnt < 64; cnt++) { |
1234 | 256 | if (C.WBCT_Coeffs[cnt][0] > 0.0f) { |
1235 | 22 | C.WBCT_Coeffs[cnt][1] *= 1.0503f; |
1236 | 22 | C.WBCT_Coeffs[cnt][3] *= 2.2867f; |
1237 | 22 | } |
1238 | 256 | } |
1239 | 20 | for(int cnt = 0; cnt < 4; cnt++) |
1240 | 16 | imgdata.color.pre_mul[cnt] = |
1241 | 16 | float(C.WB_Coeffs[LIBRAW_WBI_Daylight][cnt]); |
1242 | 4 | } |
1243 | | |
1244 | | // Adjust BL for Panasonic |
1245 | 31.7k | if (load_raw == &LibRaw::panasonic_load_raw && |
1246 | 86 | makeIs(LIBRAW_CAMERAMAKER_Panasonic) && |
1247 | 18 | ID.pana_black[0] && ID.pana_black[1] && ID.pana_black[2]) |
1248 | 0 | { |
1249 | 0 | if (libraw_internal_data.unpacker_data.pana_encoding == 5) |
1250 | 0 | libraw_internal_data.internal_output_params.zero_is_bad = 0; |
1251 | 0 | C.black = 0; |
1252 | 0 | int add = libraw_internal_data.unpacker_data.pana_encoding == 4 ? 15 : 0; |
1253 | 0 | C.cblack[0] = ID.pana_black[0] + add; |
1254 | 0 | C.cblack[1] = C.cblack[3] = ID.pana_black[1] + add; |
1255 | 0 | C.cblack[2] = ID.pana_black[2] + add; |
1256 | 0 | unsigned i = C.cblack[3]; |
1257 | 0 | for (int c = 0; c < 3; c++) |
1258 | 0 | if (i > C.cblack[c]) |
1259 | 0 | i = C.cblack[c]; |
1260 | 0 | for (int c = 0; c < 4; c++) |
1261 | 0 | C.cblack[c] -= i; |
1262 | 0 | C.black = i; |
1263 | 0 | } |
1264 | | |
1265 | | // Adjust sizes for X3F processing |
1266 | | #ifdef USE_X3FTOOLS |
1267 | | if (load_raw == &LibRaw::x3f_load_raw) |
1268 | | { |
1269 | | for (int i = 0; i < foveon_count; i++) |
1270 | | if (!strcasecmp(imgdata.idata.make, foveon_data[i].make) && |
1271 | | !strcasecmp(imgdata.idata.model, foveon_data[i].model) && |
1272 | | imgdata.sizes.raw_width == foveon_data[i].raw_width && |
1273 | | imgdata.sizes.raw_height == foveon_data[i].raw_height) |
1274 | | { |
1275 | | imgdata.sizes.top_margin = foveon_data[i].top_margin; |
1276 | | imgdata.sizes.left_margin = foveon_data[i].left_margin; |
1277 | | imgdata.sizes.width = imgdata.sizes.iwidth = foveon_data[i].width; |
1278 | | imgdata.sizes.height = imgdata.sizes.iheight = foveon_data[i].height; |
1279 | | C.maximum = foveon_data[i].white; |
1280 | | break; |
1281 | | } |
1282 | | } |
1283 | | #endif |
1284 | | #if 0 |
1285 | | size_t bytes = ID.input->size()-libraw_internal_data.unpacker_data.data_offset; |
1286 | | float bpp = float(bytes)/float(S.raw_width)/float(S.raw_height); |
1287 | | float bpp2 = float(bytes)/float(S.width)/float(S.height); |
1288 | | if(!strcasecmp(imgdata.idata.make,"Hasselblad") && bpp == 6.0f) |
1289 | | { |
1290 | | load_raw = &LibRaw::hasselblad_full_load_raw; |
1291 | | S.width = S.raw_width; |
1292 | | S.height = S.raw_height; |
1293 | | P1.filters = 0; |
1294 | | P1.colors=3; |
1295 | | P1.raw_count=1; |
1296 | | C.maximum=0xffff; |
1297 | | } |
1298 | | #endif |
1299 | 31.7k | if (C.profile_length) |
1300 | 70 | { |
1301 | 70 | if (C.profile) |
1302 | 0 | free(C.profile); |
1303 | 70 | INT64 profile_sz = MIN(INT64(C.profile_length), ID.input->size() - ID.profile_offset); |
1304 | 70 | if (profile_sz > 0LL && profile_sz < LIBRAW_MAX_PROFILE_SIZE_MB * 1024LL * 1024LL) |
1305 | 70 | { |
1306 | 70 | C.profile = calloc(size_t(profile_sz),1); |
1307 | 70 | C.profile_length = unsigned(profile_sz); |
1308 | 70 | ID.input->seek(ID.profile_offset, SEEK_SET); |
1309 | 70 | ID.input->read(C.profile, size_t(profile_sz), 1); |
1310 | 70 | } |
1311 | 0 | else |
1312 | 0 | C.profile = NULL; |
1313 | 70 | } |
1314 | | |
1315 | 31.7k | SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY); |
1316 | 31.7k | } |
1317 | 31.8k | catch (const std::bad_alloc&) |
1318 | 31.8k | { |
1319 | 0 | EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); |
1320 | 0 | } |
1321 | 31.8k | catch (const LibRaw_exceptions& err) |
1322 | 31.8k | { |
1323 | 13.0k | EXCEPTION_HANDLER(err); |
1324 | 13.0k | } |
1325 | 31.8k | catch (const std::exception& ) |
1326 | 31.8k | { |
1327 | 0 | EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT); |
1328 | 0 | } |
1329 | | |
1330 | 18.7k | final:; |
1331 | | |
1332 | 18.7k | if (P1.raw_count < 1) |
1333 | 11.0k | return LIBRAW_FILE_UNSUPPORTED; |
1334 | | |
1335 | 7.75k | write_fun = &LibRaw::write_ppm_tiff; |
1336 | | |
1337 | 7.75k | if (load_raw == &LibRaw::kodak_ycbcr_load_raw) |
1338 | 90 | { |
1339 | 90 | S.height += S.height & 1; |
1340 | 90 | S.width += S.width & 1; |
1341 | 90 | } |
1342 | | |
1343 | 7.75k | IO.shrink = |
1344 | 7.75k | P1.filters && |
1345 | 6.60k | (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1))); |
1346 | 7.75k | if (IO.shrink && P1.filters >= 1000) |
1347 | 0 | { |
1348 | 0 | S.width &= 65534; |
1349 | 0 | S.height &= 65534; |
1350 | 0 | } |
1351 | | |
1352 | 7.75k | S.iheight = (S.height + IO.shrink) >> IO.shrink; |
1353 | 7.75k | S.iwidth = (S.width + IO.shrink) >> IO.shrink; |
1354 | | |
1355 | | // Save color,sizes and internal data into raw_image fields |
1356 | 7.75k | memmove(&imgdata.rawdata.color, &imgdata.color, sizeof(imgdata.color)); |
1357 | 7.75k | memmove(&imgdata.rawdata.sizes, &imgdata.sizes, sizeof(imgdata.sizes)); |
1358 | 7.75k | memmove(&imgdata.rawdata.iparams, &imgdata.idata, sizeof(imgdata.idata)); |
1359 | 7.75k | memmove(&imgdata.rawdata.ioparams, |
1360 | 7.75k | &libraw_internal_data.internal_output_params, |
1361 | 7.75k | sizeof(libraw_internal_data.internal_output_params)); |
1362 | | |
1363 | 7.75k | SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST); |
1364 | | |
1365 | 7.75k | return LIBRAW_SUCCESS; |
1366 | 18.7k | } |