/src/libraw/src/decoders/unpack.cpp
Line | Count | Source |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2025 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 | | #include "../../internal/libraw_cameraids.h" |
15 | | #include "../../internal/libraw_cxx_defs.h" |
16 | | |
17 | | #ifdef USE_RAWSPEED3 |
18 | | #include "rawspeed3_capi.h" |
19 | | #include <array> |
20 | | #endif |
21 | | |
22 | | int LibRaw::unpack(void) |
23 | 4.82k | { |
24 | 4.82k | CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW); |
25 | 4.82k | CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY); |
26 | 4.82k | try |
27 | 4.82k | { |
28 | | |
29 | 4.82k | if (!libraw_internal_data.internal_data.input) |
30 | 0 | return LIBRAW_INPUT_CLOSED; |
31 | | |
32 | 4.82k | RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW, 0, 2); |
33 | 4.82k | if (imgdata.rawparams.shot_select >= P1.raw_count) |
34 | 0 | return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE; |
35 | | |
36 | 4.82k | if (!load_raw) |
37 | 0 | return LIBRAW_UNSPECIFIED_ERROR; |
38 | | |
39 | | // already allocated ? |
40 | 4.82k | if (imgdata.image) |
41 | 0 | { |
42 | 0 | free(imgdata.image); |
43 | 0 | imgdata.image = 0; |
44 | 0 | } |
45 | 4.82k | if (imgdata.rawdata.raw_alloc) |
46 | 0 | { |
47 | 0 | free(imgdata.rawdata.raw_alloc); |
48 | 0 | imgdata.rawdata.raw_alloc = 0; |
49 | 0 | } |
50 | 4.82k | if (libraw_internal_data.unpacker_data.meta_length) |
51 | 339 | { |
52 | 339 | if (libraw_internal_data.unpacker_data.meta_length > |
53 | 339 | INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
54 | 0 | throw LIBRAW_EXCEPTION_TOOBIG; |
55 | | |
56 | 339 | libraw_internal_data.internal_data.meta_data = |
57 | | #ifdef LIBRAW_CALLOC_RAWSTORE |
58 | | (char *)calloc(libraw_internal_data.unpacker_data.meta_length,1); |
59 | | #else |
60 | 339 | (char *)malloc(libraw_internal_data.unpacker_data.meta_length); |
61 | 339 | #endif |
62 | 339 | } |
63 | | |
64 | 4.82k | libraw_decoder_info_t decoder_info; |
65 | 4.82k | get_decoder_info(&decoder_info); |
66 | | |
67 | 4.82k | int save_iwidth = S.iwidth, save_iheight = S.iheight, |
68 | 4.82k | save_shrink = IO.shrink; |
69 | | |
70 | 4.82k | int rwidth = S.raw_width, rheight = S.raw_height; |
71 | 4.82k | if (!IO.fuji_width) |
72 | 4.67k | { |
73 | | // adjust non-Fuji allocation |
74 | 4.67k | if (rwidth < S.width + S.left_margin) |
75 | 99 | rwidth = S.width + S.left_margin; |
76 | 4.67k | if (rheight < S.height + S.top_margin) |
77 | 42 | rheight = S.height + S.top_margin; |
78 | 4.67k | } |
79 | 4.82k | if (rwidth > 65535 || |
80 | 4.82k | rheight > 65535) // No way to make image larger than 64k pix |
81 | 1 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
82 | | |
83 | 4.82k | imgdata.rawdata.raw_image = 0; |
84 | 4.82k | imgdata.rawdata.color4_image = 0; |
85 | 4.82k | imgdata.rawdata.color3_image = 0; |
86 | 4.82k | imgdata.rawdata.float_image = 0; |
87 | 4.82k | imgdata.rawdata.float3_image = 0; |
88 | | |
89 | | #ifdef USE_DNGSDK |
90 | | if (imgdata.idata.dng_version && dnghost |
91 | | && libraw_internal_data.unpacker_data.tiff_samples != 2 // Fuji SuperCCD; it is better to detect is more rigid way |
92 | | && valid_for_dngsdk() && load_raw != &LibRaw::pentax_4shot_load_raw) |
93 | | { |
94 | | // Data size check |
95 | | INT64 pixcount = |
96 | | INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height)); |
97 | | INT64 planecount = |
98 | | (imgdata.idata.filters || P1.colors == 1) ? 1 : LIM(P1.colors, 3, 4); |
99 | | INT64 samplesize = is_floating_point() ? 4 : 2; |
100 | | INT64 bytes = pixcount * planecount * samplesize; |
101 | | if (bytes + INT64(libraw_internal_data.unpacker_data.meta_length ) |
102 | | > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
103 | | throw LIBRAW_EXCEPTION_TOOBIG; |
104 | | |
105 | | // find ifd to check sample |
106 | | try_dngsdk(); |
107 | | if (raw_was_read()) |
108 | | imgdata.process_warnings |= LIBRAW_WARN_DNGSDK_PROCESSED; |
109 | | } |
110 | | #endif |
111 | | #ifdef USE_RAWSPEED3 |
112 | | if (!raw_was_read() |
113 | | && ID.input->size() < 2147483615LL |
114 | | && (!IO.fuji_width) // Do not use for fuji rotated |
115 | | && ((imgdata.idata.raw_count == 1) |
116 | | // Canon dual pixel, 1st frame |
117 | | || (makeIs(LIBRAW_CAMERAMAKER_Canon) && imgdata.idata.raw_count == 2 && imgdata.rawparams.shot_select==0) |
118 | | ) |
119 | | #ifdef USE_RAWSPEED_BITS |
120 | | && (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_USE) |
121 | | #else |
122 | | && imgdata.rawparams.use_rawspeed |
123 | | #endif |
124 | | && (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED3) |
125 | | ) |
126 | | { |
127 | | INT64 pixcount = INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height)); |
128 | | INT64 planecount = (imgdata.idata.filters || P1.colors == 1) ? 1 : LIM(P1.colors, 3, 4); |
129 | | INT64 bytes = pixcount * planecount * 2; // sample size is always 2 for rawspeed |
130 | | if (bytes + INT64(libraw_internal_data.unpacker_data.meta_length) |
131 | | > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
132 | | throw LIBRAW_EXCEPTION_TOOBIG; |
133 | | |
134 | | if (!_rawspeed3_handle) |
135 | | _rawspeed3_handle = rawspeed3_initdefault(); |
136 | | |
137 | | if (_rawspeed3_handle && ID.input->size() > 0) // large bound is checked at identify |
138 | | { |
139 | | void *_rawspeed_buffer = 0; |
140 | | try { |
141 | | ID.input->seek(0, SEEK_SET); |
142 | | INT64 _rawspeed_buffer_sz = ID.input->size() + 32; |
143 | | _rawspeed_buffer = malloc(_rawspeed_buffer_sz); |
144 | | if (!_rawspeed_buffer) |
145 | | throw LIBRAW_EXCEPTION_ALLOC; |
146 | | ID.input->read(_rawspeed_buffer, ID.input->size(), 1); |
147 | | |
148 | | rawspeed3_ret_t rs3ret; |
149 | | rawspeed3_clearresult(&rs3ret); |
150 | | int status = rawspeed3_decodefile(_rawspeed3_handle, &rs3ret, _rawspeed_buffer, ID.input->size(), |
151 | | #ifdef USE_RAWSPEED_BITS |
152 | | !(imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_FAILONUNKNOWN) |
153 | | #else |
154 | | false |
155 | | #endif |
156 | | ); |
157 | | if (status != rawspeed3_ok) |
158 | | imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED; |
159 | | |
160 | | if (status == rawspeed3_not_supported) |
161 | | imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_NOTLISTED; |
162 | | |
163 | | if (status == rawspeed3_ok |
164 | | #ifdef USE_RAWSPEED_BITS |
165 | | || |
166 | | (status == rawspeed3_ok_warnings && (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_IGNOREERRORS)) |
167 | | #endif |
168 | | ) |
169 | | { |
170 | | |
171 | | if ((S.raw_width != rs3ret.width) || (S.raw_height != rs3ret.height)) |
172 | | throw "Size mismatch"; |
173 | | |
174 | | // DECODED w/ success |
175 | | if (rs3ret.cpp == 4) |
176 | | { |
177 | | imgdata.rawdata.color4_image = (ushort(*)[4])rs3ret.pixeldata; |
178 | | //if (r->whitePoint > 0 && r->whitePoint < 65536) |
179 | | // C.maximum = r->whitePoint; |
180 | | } |
181 | | else if (rs3ret.cpp == 3) |
182 | | { |
183 | | imgdata.rawdata.color3_image = (ushort(*)[3])rs3ret.pixeldata; |
184 | | //if (r->whitePoint > 0 && r->whitePoint < 65536) |
185 | | // C.maximum = r->whitePoint; |
186 | | } |
187 | | else if (rs3ret.cpp == 1 && rs3ret.filters > 1) // Fuji or bayer |
188 | | { |
189 | | imgdata.rawdata.raw_image = (ushort *)rs3ret.pixeldata; |
190 | | } |
191 | | |
192 | | if (raw_was_read()) // buffers are assigned above |
193 | | { |
194 | | // set sizes |
195 | | S.raw_pitch = rs3ret.pitch; |
196 | | S.raw_width = rs3ret.width; |
197 | | S.raw_height = rs3ret.height; |
198 | | imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_PROCESSED; |
199 | | |
200 | | if (imgdata.rawdata.raw_image && |
201 | | load_raw == &LibRaw::phase_one_load_raw_c && imgdata.color.phase_one_data.format != 8) |
202 | | { |
203 | | // Scale data to match libraw own decoder |
204 | | for (unsigned row = 0; row < rs3ret.height; row++) |
205 | | for (unsigned col = 0; col < rs3ret.pitch / 2; col++) |
206 | | imgdata.rawdata.raw_image[row * rs3ret.pitch / 2 + col] <<= 2; |
207 | | } |
208 | | |
209 | | // if (r->whitePoint > 0 && r->whitePoint < 65536) |
210 | | // C.maximum = r->whitePoint; |
211 | | } |
212 | | } |
213 | | free(_rawspeed_buffer); |
214 | | } |
215 | | catch (...) |
216 | | { |
217 | | imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_PROBLEM; |
218 | | if (_rawspeed_buffer) |
219 | | free(_rawspeed_buffer); |
220 | | } |
221 | | } |
222 | | } |
223 | | #endif |
224 | | #ifdef USE_RAWSPEED |
225 | | if (!raw_was_read() && ID.input->size() < 2147483615LL) |
226 | | { |
227 | | int rawspeed_enabled = 1; |
228 | | |
229 | | if (imgdata.idata.dng_version && (libraw_internal_data.unpacker_data.tiff_samples == 2 || imgdata.idata.raw_count > 1)) |
230 | | rawspeed_enabled = 0; |
231 | | |
232 | | if (libraw_internal_data.unpacker_data.is_NikonTransfer) |
233 | | rawspeed_enabled = 0; |
234 | | |
235 | | if (libraw_internal_data.unpacker_data.pana_encoding == 5) |
236 | | rawspeed_enabled = 0; |
237 | | |
238 | | if (imgdata.idata.raw_count > 1) |
239 | | rawspeed_enabled = 0; |
240 | | if (!strncasecmp(imgdata.idata.software, "Magic", 5)) |
241 | | rawspeed_enabled = 0; |
242 | | // Disable rawspeed for double-sized Oly files |
243 | | if (makeIs(LIBRAW_CAMERAMAKER_Olympus) && |
244 | | ((imgdata.sizes.raw_width > 6000) || |
245 | | !strncasecmp(imgdata.idata.model, "SH-", 3) || |
246 | | !strncasecmp(imgdata.idata.model, "TG-", 3) )) |
247 | | rawspeed_enabled = 0; |
248 | | |
249 | | if (makeIs(LIBRAW_CAMERAMAKER_Canon) && |
250 | | (libraw_internal_data.identify_data.unique_id == CanonID_EOS_6D_Mark_II)) |
251 | | rawspeed_enabled = 0; |
252 | | |
253 | | if (imgdata.idata.dng_version && imgdata.idata.filters == 0 && |
254 | | libraw_internal_data.unpacker_data.tiff_bps == 8) // Disable for 8 bit |
255 | | rawspeed_enabled = 0; |
256 | | |
257 | | if (load_raw == &LibRaw::packed_load_raw && |
258 | | makeIs(LIBRAW_CAMERAMAKER_Nikon) && |
259 | | (!strncasecmp(imgdata.idata.model, "E", 1) || |
260 | | !strncasecmp(imgdata.idata.model, "COOLPIX B", 9) || |
261 | | !strncasecmp(imgdata.idata.model, "COOLPIX P9", 10) || |
262 | | !strncasecmp(imgdata.idata.model, "COOLPIX P1000", 13))) |
263 | | rawspeed_enabled = 0; |
264 | | |
265 | | if (load_raw == &LibRaw::nikon_load_raw && makeIs(LIBRAW_CAMERAMAKER_Nikon) && |
266 | | !strcasecmp(imgdata.idata.model, "D6")) |
267 | | rawspeed_enabled = 0; |
268 | | |
269 | | if (load_raw == &LibRaw::lossless_jpeg_load_raw && |
270 | | MN.canon.RecordMode && makeIs(LIBRAW_CAMERAMAKER_Kodak) && |
271 | | /* Not normalized models here, it is intentional */ |
272 | | (!strncasecmp(imgdata.idata.model, "EOS D2000", 9) || |
273 | | !strncasecmp(imgdata.idata.model, "EOS D6000", 9))) |
274 | | rawspeed_enabled = 0; |
275 | | |
276 | | if (load_raw == &LibRaw::nikon_load_raw && |
277 | | makeIs(LIBRAW_CAMERAMAKER_Nikon) && |
278 | | (!strncasecmp(imgdata.idata.model, "Z", 1) || !strncasecmp(imgdata.idata.model,"D780",4))) |
279 | | rawspeed_enabled = 0; |
280 | | |
281 | | if (load_raw == &LibRaw::panasonic_load_raw && |
282 | | libraw_internal_data.unpacker_data.pana_encoding > 4) |
283 | | rawspeed_enabled = 0; |
284 | | |
285 | | // RawSpeed Supported, |
286 | | if ( |
287 | | #ifdef USE_RAWSPEED_BITS |
288 | | (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV1_USE) |
289 | | #else |
290 | | imgdata.rawparams.use_rawspeed |
291 | | #endif |
292 | | && rawspeed_enabled && |
293 | | !(is_sraw() && (imgdata.rawparams.specials & |
294 | | (LIBRAW_RAWSPECIAL_SRAW_NO_RGB | |
295 | | LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE))) && |
296 | | (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED) && |
297 | | _rawspeed_camerameta) |
298 | | { |
299 | | INT64 pixcount = INT64(MAX(S.width, S.raw_width)) * |
300 | | INT64(MAX(S.height, S.raw_height)); |
301 | | INT64 planecount = (imgdata.idata.filters || P1.colors == 1) |
302 | | ? 1 |
303 | | : LIM(P1.colors, 3, 4); |
304 | | INT64 bytes = |
305 | | pixcount * planecount * 2; // sample size is always 2 for rawspeed |
306 | | if (bytes + +INT64(libraw_internal_data.unpacker_data.meta_length) > |
307 | | INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
308 | | throw LIBRAW_EXCEPTION_TOOBIG; |
309 | | |
310 | | /*int rr = */ try_rawspeed(); |
311 | | |
312 | | } |
313 | | } |
314 | | #endif |
315 | 4.82k | if (!raw_was_read()) // RawSpeed failed or not run |
316 | 4.82k | { |
317 | | // Not allocated on RawSpeed call, try call LibRaow |
318 | 4.82k | int zero_rawimage = 0; |
319 | 4.82k | if (decoder_info.decoder_flags & LIBRAW_DECODER_OWNALLOC) |
320 | 224 | { |
321 | | // x3f foveon decoder and DNG float |
322 | | // Do nothing! Decoder will allocate data internally |
323 | 224 | } |
324 | 4.82k | if (decoder_info.decoder_flags & LIBRAW_DECODER_SINAR4SHOT) |
325 | 36 | { |
326 | 36 | if (imgdata.rawparams.shot_select) // single image extract |
327 | 0 | { |
328 | 0 | if (INT64(rwidth) * INT64(rheight + 8) * |
329 | 0 | INT64(sizeof(imgdata.rawdata.raw_image[0])) |
330 | 0 | + +INT64(libraw_internal_data.unpacker_data.meta_length) > |
331 | 0 | INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
332 | 0 | throw LIBRAW_EXCEPTION_TOOBIG; |
333 | | #ifdef LIBRAW_CALLOC_RAWSTORE |
334 | | imgdata.rawdata.raw_alloc = calloc(size_t(rwidth) * (size_t(rheight) + 8), sizeof(imgdata.rawdata.raw_image[0])); |
335 | | #else |
336 | 0 | imgdata.rawdata.raw_alloc = malloc( |
337 | 0 | size_t(rwidth) * (size_t(rheight) + 8) * sizeof(imgdata.rawdata.raw_image[0])); |
338 | 0 | #endif |
339 | 0 | imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; |
340 | 0 | if (!S.raw_pitch) |
341 | 0 | S.raw_pitch = S.raw_width * 2; // Bayer case, not set before |
342 | 0 | } |
343 | 36 | else // Full image extract |
344 | 36 | { |
345 | 36 | if (INT64(rwidth) * INT64(rheight + 8) * |
346 | 36 | INT64(sizeof(imgdata.rawdata.raw_image[0])) * 4 |
347 | 36 | +INT64(libraw_internal_data.unpacker_data.meta_length) > |
348 | 36 | INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
349 | 0 | throw LIBRAW_EXCEPTION_TOOBIG; |
350 | 36 | S.raw_pitch = S.raw_width * 8; |
351 | 36 | imgdata.rawdata.raw_alloc = 0; |
352 | | #ifdef LIBRAW_CALLOC_RAWSTORE |
353 | | imgdata.image = (ushort(*)[4])calloc( |
354 | | size_t(MAX(S.width, S.raw_width)) * |
355 | | (size_t(MAX(S.height, S.raw_height)) + 8), |
356 | | sizeof(*imgdata.image)); |
357 | | #else |
358 | 36 | imgdata.image = (ushort(*)[4])malloc( |
359 | 36 | size_t(MAX(S.width, S.raw_width)) * (size_t(MAX(S.height, S.raw_height)) + 8) * sizeof(*imgdata.image)); |
360 | 36 | #endif |
361 | 36 | } |
362 | 36 | } |
363 | 4.78k | else if (decoder_info.decoder_flags & LIBRAW_DECODER_3CHANNEL) |
364 | 0 | { |
365 | 0 | if (INT64(rwidth) * INT64(rheight + 8) * |
366 | 0 | INT64(sizeof(imgdata.rawdata.raw_image[0])) * 3 |
367 | 0 | + INT64(libraw_internal_data.unpacker_data.meta_length) > |
368 | 0 | INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
369 | 0 | throw LIBRAW_EXCEPTION_TOOBIG; |
370 | | |
371 | | #ifdef LIBRAW_CALLOC_RAWSTORE |
372 | | imgdata.rawdata.raw_alloc = |
373 | | calloc(size_t(rwidth) * (size_t(rheight) + 8), sizeof(imgdata.rawdata.raw_image[0]) * 3); |
374 | | #else |
375 | 0 | imgdata.rawdata.raw_alloc = malloc( |
376 | 0 | size_t(rwidth) * (size_t(rheight) + 8) * sizeof(imgdata.rawdata.raw_image[0]) * 3); |
377 | 0 | #endif |
378 | 0 | imgdata.rawdata.color3_image = (ushort(*)[3])imgdata.rawdata.raw_alloc; |
379 | 0 | if (!S.raw_pitch) |
380 | 0 | S.raw_pitch = S.raw_width * 6; |
381 | 0 | } |
382 | 4.78k | else if (imgdata.idata.filters || |
383 | 774 | P1.colors == |
384 | 774 | 1) // Bayer image or single color -> decode to raw_image |
385 | 4.29k | { |
386 | 4.29k | if (INT64(rwidth) * INT64(rheight + 8) * |
387 | 4.29k | INT64(sizeof(imgdata.rawdata.raw_image[0])) |
388 | 4.29k | + INT64(libraw_internal_data.unpacker_data.meta_length) > |
389 | 4.29k | INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
390 | 3 | throw LIBRAW_EXCEPTION_TOOBIG; |
391 | | #ifdef LIBRAW_CALLOC_RAWSTORE |
392 | | imgdata.rawdata.raw_alloc = |
393 | | calloc(size_t(rwidth) * (size_t(rheight) + 8),sizeof(imgdata.rawdata.raw_image[0])); |
394 | | #else |
395 | 4.29k | imgdata.rawdata.raw_alloc = malloc( |
396 | 4.29k | size_t(rwidth) * (size_t(rheight) + 8) * sizeof(imgdata.rawdata.raw_image[0])); |
397 | 4.29k | #endif |
398 | 4.29k | imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; |
399 | 4.29k | if (!S.raw_pitch) |
400 | 4.29k | S.raw_pitch = S.raw_width * 2; // Bayer case, not set before |
401 | 4.29k | } |
402 | 496 | else // NO LEGACY FLAG if (decoder_info.decoder_flags & |
403 | | // LIBRAW_DECODER_LEGACY) |
404 | 496 | { |
405 | 496 | if (decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL) |
406 | 50 | { |
407 | 50 | S.raw_pitch = S.raw_width * 8; |
408 | 50 | } |
409 | 446 | else |
410 | 446 | { |
411 | 446 | S.iwidth = S.width; |
412 | 446 | S.iheight = S.height; |
413 | 446 | IO.shrink = 0; |
414 | 446 | if (!S.raw_pitch) |
415 | 439 | S.raw_pitch = (decoder_info.decoder_flags & |
416 | 439 | LIBRAW_DECODER_LEGACY_WITH_MARGINS) |
417 | 439 | ? S.raw_width * 8 |
418 | 439 | : S.width * 8; |
419 | 446 | } |
420 | | // sRAW and old Foveon decoders only, so extra buffer size is just 1/4 |
421 | | // allocate image as temporary buffer, size |
422 | 496 | if (INT64(MAX(S.width, S.raw_width)) * |
423 | 496 | INT64(MAX(S.height, S.raw_height) + 8) * |
424 | 496 | INT64(sizeof(*imgdata.image)) |
425 | 496 | + INT64(libraw_internal_data.unpacker_data.meta_length) > |
426 | 496 | INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
427 | 1 | throw LIBRAW_EXCEPTION_TOOBIG; |
428 | | |
429 | 495 | imgdata.rawdata.raw_alloc = 0; |
430 | 495 | imgdata.image = |
431 | 495 | (ushort(*)[4])calloc(unsigned(MAX(S.width, S.raw_width)) * |
432 | 495 | unsigned(MAX(S.height, S.raw_height) + 8), |
433 | 495 | sizeof(*imgdata.image)); |
434 | 495 | if (!(decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL)) |
435 | 445 | { |
436 | 445 | imgdata.rawdata.raw_image = (ushort *)imgdata.image; |
437 | 445 | zero_rawimage = 1; |
438 | 445 | } |
439 | 495 | } |
440 | 4.82k | ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); |
441 | | |
442 | 4.82k | unsigned m_save = C.maximum; |
443 | 4.82k | if (load_raw == &LibRaw::unpacked_load_raw && |
444 | 243 | (!strcasecmp(imgdata.idata.make, "Nikon") || !strcasecmp(imgdata.idata.make, "Hasselblad")) |
445 | 4.82k | ) |
446 | 39 | C.maximum = 65535; |
447 | 4.82k | (this->*load_raw)(); |
448 | 4.82k | if (zero_rawimage) |
449 | 275 | imgdata.rawdata.raw_image = 0; |
450 | 4.82k | if (load_raw == &LibRaw::unpacked_load_raw && |
451 | 150 | (!strcasecmp(imgdata.idata.make, "Nikon") || !strcasecmp(imgdata.idata.make, "Hasselblad")) |
452 | 4.82k | ) |
453 | 31 | C.maximum = m_save; |
454 | 4.82k | if (decoder_info.decoder_flags & LIBRAW_DECODER_OWNALLOC) |
455 | 205 | { |
456 | | // x3f foveon decoder only: do nothing |
457 | 205 | } |
458 | 4.61k | else if (decoder_info.decoder_flags & LIBRAW_DECODER_SINAR4SHOT && |
459 | 7 | imgdata.rawparams.shot_select == 0) |
460 | 7 | { |
461 | 7 | imgdata.rawdata.raw_alloc = imgdata.image; |
462 | 7 | imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc; |
463 | 7 | imgdata.image = 0; |
464 | 7 | } |
465 | 4.60k | else if (!(imgdata.idata.filters || |
466 | 277 | P1.colors == 1)) // legacy decoder, ownalloc handled above |
467 | 257 | { |
468 | | // successfully decoded legacy image, attach image to raw_alloc |
469 | 257 | imgdata.rawdata.raw_alloc = imgdata.image; |
470 | 257 | imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc; |
471 | 257 | imgdata.image = 0; |
472 | | // Restore saved values. Note: Foveon have masked frame |
473 | | // Other 4-color legacy data: no borders |
474 | 257 | if (!(libraw_internal_data.unpacker_data.load_flags & 256) && |
475 | 251 | !(decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL) && |
476 | 247 | !(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY_WITH_MARGINS)) |
477 | 247 | { |
478 | 247 | S.raw_width = S.width; |
479 | 247 | S.left_margin = 0; |
480 | 247 | S.raw_height = S.height; |
481 | 247 | S.top_margin = 0; |
482 | 247 | } |
483 | 257 | } |
484 | 4.82k | } |
485 | | |
486 | 4.82k | if (imgdata.rawdata.raw_image) |
487 | 2.31k | crop_masked_pixels(); // calculate black levels |
488 | | |
489 | | // recover image sizes |
490 | 4.82k | S.iwidth = save_iwidth; |
491 | 4.82k | S.iheight = save_iheight; |
492 | 4.82k | IO.shrink = save_shrink; |
493 | | |
494 | | // adjust black to possible maximum |
495 | 4.82k | unsigned int i = C.cblack[3]; |
496 | 4.82k | unsigned int c; |
497 | 12.6k | for (c = 0; c < 3; c++) |
498 | 7.80k | if (i > C.cblack[c]) |
499 | 90 | i = C.cblack[c]; |
500 | 15.2k | for (c = 0; c < 4; c++) |
501 | 10.4k | C.cblack[c] -= i; |
502 | 4.82k | C.black += i; |
503 | | |
504 | | // Save color,sizes and internal data into raw_image fields |
505 | 4.82k | memmove(&imgdata.rawdata.color, &imgdata.color, sizeof(imgdata.color)); |
506 | 4.82k | memmove(&imgdata.rawdata.sizes, &imgdata.sizes, sizeof(imgdata.sizes)); |
507 | 4.82k | memmove(&imgdata.rawdata.iparams, &imgdata.idata, sizeof(imgdata.idata)); |
508 | 4.82k | memmove(&imgdata.rawdata.ioparams, |
509 | 4.82k | &libraw_internal_data.internal_output_params, |
510 | 4.82k | sizeof(libraw_internal_data.internal_output_params)); |
511 | | |
512 | 4.82k | SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW); |
513 | 4.82k | RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW, 1, 2); |
514 | | |
515 | 4.82k | return 0; |
516 | 4.82k | } |
517 | 4.82k | catch (const std::bad_alloc&) |
518 | 4.82k | { |
519 | 0 | EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); |
520 | 0 | } |
521 | 4.82k | catch (const LibRaw_exceptions& err) |
522 | 4.82k | { |
523 | 2.22k | EXCEPTION_HANDLER(err); |
524 | 2.22k | } |
525 | 4.82k | catch (const std::exception& ) |
526 | 4.82k | { |
527 | 0 | EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT); |
528 | 0 | } |
529 | 4.82k | } |