/src/libraw/src/preprocessing/raw2image.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2024 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 | | |
18 | | void LibRaw::raw2image_start() |
19 | 37.1k | { |
20 | | // restore color,sizes and internal data into raw_image fields |
21 | 37.1k | memmove(&imgdata.color, &imgdata.rawdata.color, sizeof(imgdata.color)); |
22 | 37.1k | memmove(&imgdata.sizes, &imgdata.rawdata.sizes, sizeof(imgdata.sizes)); |
23 | 37.1k | memmove(&imgdata.idata, &imgdata.rawdata.iparams, sizeof(imgdata.idata)); |
24 | 37.1k | memmove(&libraw_internal_data.internal_output_params, |
25 | 37.1k | &imgdata.rawdata.ioparams, |
26 | 37.1k | sizeof(libraw_internal_data.internal_output_params)); |
27 | | |
28 | 37.1k | if (O.user_flip >= 0) |
29 | 37.1k | S.flip = O.user_flip; |
30 | | |
31 | 37.1k | switch ((S.flip + 3600) % 360) |
32 | 37.1k | { |
33 | 0 | case 270: |
34 | 0 | S.flip = 5; |
35 | 0 | break; |
36 | 0 | case 180: |
37 | 0 | S.flip = 3; |
38 | 0 | break; |
39 | 0 | case 90: |
40 | 0 | S.flip = 6; |
41 | 0 | break; |
42 | 37.1k | } |
43 | | |
44 | 185k | for (int c = 0; c < 4; c++) |
45 | 148k | if (O.aber[c] < 0.001 || O.aber[c] > 1000.f) |
46 | 21.1k | O.aber[c] = 1.0; |
47 | | |
48 | | // adjust for half mode! |
49 | 37.1k | IO.shrink = |
50 | 37.1k | !imgdata.rawdata.color4_image && !imgdata.rawdata.color3_image && |
51 | 37.1k | !imgdata.rawdata.float4_image && !imgdata.rawdata.float3_image && |
52 | 37.1k | P1.filters && |
53 | 37.1k | (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1))); |
54 | | |
55 | 37.1k | S.iheight = (S.height + IO.shrink) >> IO.shrink; |
56 | 37.1k | S.iwidth = (S.width + IO.shrink) >> IO.shrink; |
57 | 37.1k | } |
58 | | |
59 | | int LibRaw::raw2image(void) |
60 | 5.27k | { |
61 | | |
62 | 5.27k | CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); |
63 | | |
64 | 5.27k | try |
65 | 5.27k | { |
66 | 5.27k | raw2image_start(); |
67 | | |
68 | 5.27k | bool free_p1_buffer = false; |
69 | 5.27k | if (is_phaseone_compressed() && (imgdata.rawdata.raw_alloc || (imgdata.process_warnings & LIBRAW_WARN_RAWSPEED3_PROCESSED))) |
70 | 871 | { |
71 | 871 | phase_one_allocate_tempbuffer(); |
72 | 871 | free_p1_buffer = true; |
73 | 871 | int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc, |
74 | 871 | imgdata.rawdata.raw_image); |
75 | 871 | if (rc == 0 && imgdata.params.use_p1_correction) |
76 | 871 | rc = phase_one_correct(); |
77 | 871 | if (rc != 0) |
78 | 351 | { |
79 | 351 | phase_one_free_tempbuffer(); |
80 | 351 | return rc; |
81 | 351 | } |
82 | 871 | } |
83 | | |
84 | | // free and re-allocate image bitmap |
85 | 4.92k | int extra = P1.filters ? (P1.filters == 9 ? 6 : 2) : 0; |
86 | 4.92k | if (imgdata.image) |
87 | 28 | { |
88 | 28 | imgdata.image = (ushort(*)[4])realloc( |
89 | 28 | imgdata.image, (S.iheight+extra) * (S.iwidth+extra) * sizeof(*imgdata.image)); |
90 | 28 | memset(imgdata.image, 0, (S.iheight+extra) * (S.iwidth+extra) * sizeof(*imgdata.image)); |
91 | 28 | } |
92 | 4.89k | else |
93 | 4.89k | imgdata.image = |
94 | 4.89k | (ushort(*)[4])calloc((S.iheight+extra) * (S.iwidth+extra), sizeof(*imgdata.image)); |
95 | | |
96 | | |
97 | 4.92k | libraw_decoder_info_t decoder_info; |
98 | 4.92k | get_decoder_info(&decoder_info); |
99 | | |
100 | | // Copy area size |
101 | 4.92k | int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin))); |
102 | 4.92k | int copywidth = MAX(0, MIN(int(S.width), int(S.raw_width) - int(S.left_margin))); |
103 | | |
104 | | // Move saved bitmap to imgdata.image |
105 | 4.92k | if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image) |
106 | 4.48k | { |
107 | 4.48k | if (IO.fuji_width) |
108 | 662 | { |
109 | 662 | unsigned r, c; |
110 | 662 | int row, col; |
111 | 24.8k | for (row = 0; row < S.raw_height - S.top_margin * 2; row++) |
112 | 24.2k | { |
113 | 24.2k | for (col = 0; |
114 | 198M | col < IO.fuji_width |
115 | 198M | << int(!libraw_internal_data.unpacker_data.fuji_layout); |
116 | 198M | col++) |
117 | 198M | { |
118 | 198M | if (libraw_internal_data.unpacker_data.fuji_layout) |
119 | 129M | { |
120 | 129M | r = IO.fuji_width - 1 - col + (row >> 1); |
121 | 129M | c = col + ((row + 1) >> 1); |
122 | 129M | } |
123 | 69.2M | else |
124 | 69.2M | { |
125 | 69.2M | r = IO.fuji_width - 1 + row - (col >> 1); |
126 | 69.2M | c = row + ((col + 1) >> 1); |
127 | 69.2M | } |
128 | 198M | if (r < S.height && c < S.width && col + int(S.left_margin) < int(S.raw_width)) |
129 | 943k | imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)] |
130 | 943k | [FC(r, c)] = |
131 | 943k | imgdata.rawdata |
132 | 943k | .raw_image[(row + S.top_margin) * S.raw_pitch / 2 + |
133 | 943k | (col + S.left_margin)]; |
134 | 198M | } |
135 | 24.2k | } |
136 | 662 | } |
137 | 3.82k | else |
138 | 3.82k | { |
139 | 3.82k | int row, col; |
140 | 1.36M | for (row = 0; row < copyheight; row++) |
141 | 329M | for (col = 0; col < copywidth; col++) |
142 | 328M | imgdata.image[((row) >> IO.shrink) * S.iwidth + |
143 | 328M | ((col) >> IO.shrink)][fcol(row, col)] = |
144 | 328M | imgdata.rawdata |
145 | 328M | .raw_image[(row + S.top_margin) * S.raw_pitch / 2 + |
146 | 328M | (col + S.left_margin)]; |
147 | 3.82k | } |
148 | 4.48k | } |
149 | 440 | else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY) |
150 | 440 | { |
151 | 440 | if (imgdata.rawdata.color4_image) |
152 | 411 | { |
153 | 411 | if (S.width * 8u == S.raw_pitch && S.height == S.raw_height) |
154 | 352 | memmove(imgdata.image, imgdata.rawdata.color4_image, |
155 | 352 | S.width * S.height * sizeof(*imgdata.image)); |
156 | 59 | else |
157 | 59 | { |
158 | 16.1k | for (int row = 0; row < copyheight; row++) |
159 | 16.1k | memmove(&imgdata.image[row * S.width], |
160 | 16.1k | &imgdata.rawdata |
161 | 16.1k | .color4_image[(row + S.top_margin) * S.raw_pitch / 8 + |
162 | 16.1k | S.left_margin], |
163 | 16.1k | copywidth * sizeof(*imgdata.image)); |
164 | 59 | } |
165 | 411 | } |
166 | 29 | else if (imgdata.rawdata.color3_image) |
167 | 28 | { |
168 | 28 | unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image; |
169 | 121k | for (int row = 0; row < copyheight; row++) |
170 | 121k | { |
171 | 121k | ushort(*srcrow)[3] = |
172 | 121k | (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch]; |
173 | 121k | ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width]; |
174 | 5.19M | for (int col = 0; col < copywidth; col++) |
175 | 5.07M | { |
176 | 20.3M | for (int c = 0; c < 3; c++) |
177 | 15.2M | dstrow[col][c] = srcrow[S.left_margin + col][c]; |
178 | 5.07M | dstrow[col][3] = 0; |
179 | 5.07M | } |
180 | 121k | } |
181 | 28 | } |
182 | 1 | else |
183 | 1 | { |
184 | | // legacy decoder, but no data? |
185 | 1 | throw LIBRAW_EXCEPTION_DECODE_RAW; |
186 | 1 | } |
187 | 440 | } |
188 | | |
189 | | // Free PhaseOne separate copy allocated at function start |
190 | 4.92k | if (free_p1_buffer) |
191 | 520 | { |
192 | 520 | phase_one_free_tempbuffer(); |
193 | 520 | } |
194 | | // hack - clear later flags! |
195 | | |
196 | 4.92k | if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width) |
197 | 109 | { |
198 | 109 | canon_600_correct(); |
199 | 109 | } |
200 | | |
201 | 4.92k | imgdata.progress_flags = |
202 | 4.92k | LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN | |
203 | 4.92k | LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY | |
204 | 4.92k | LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW; |
205 | 4.92k | return 0; |
206 | 4.92k | } |
207 | 5.27k | catch (const std::bad_alloc&) |
208 | 5.27k | { |
209 | 0 | EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); |
210 | 0 | } |
211 | 5.27k | catch (const LibRaw_exceptions& err) |
212 | 5.27k | { |
213 | 1 | EXCEPTION_HANDLER(err); |
214 | 1 | } |
215 | 5.27k | } |
216 | | |
217 | | void LibRaw::copy_fuji_uncropped(unsigned short cblack[4], |
218 | | unsigned short *dmaxp) |
219 | 4.11k | { |
220 | | #if defined(LIBRAW_USE_OPENMP) |
221 | | #pragma omp parallel for schedule(dynamic) default(none) firstprivate(cblack) shared(dmaxp) |
222 | | #endif |
223 | 133k | for (int row = 0; row < int(S.raw_height) - int(S.top_margin) * 2; row++) |
224 | 129k | { |
225 | 129k | int col; |
226 | 129k | unsigned short ldmax = 0; |
227 | 129k | for (col = 0; |
228 | 7.24M | col < IO.fuji_width << int(!libraw_internal_data.unpacker_data.fuji_layout) |
229 | 7.24M | && col + int(S.left_margin) < int(S.raw_width); |
230 | 7.11M | col++) |
231 | 7.11M | { |
232 | 7.11M | unsigned r, c; |
233 | 7.11M | if (libraw_internal_data.unpacker_data.fuji_layout) |
234 | 844k | { |
235 | 844k | r = IO.fuji_width - 1 - col + (row >> 1); |
236 | 844k | c = col + ((row + 1) >> 1); |
237 | 844k | } |
238 | 6.27M | else |
239 | 6.27M | { |
240 | 6.27M | r = IO.fuji_width - 1 + row - (col >> 1); |
241 | 6.27M | c = row + ((col + 1) >> 1); |
242 | 6.27M | } |
243 | 7.11M | if (r < S.height && c < S.width) |
244 | 6.60M | { |
245 | 6.60M | unsigned short val = |
246 | 6.60M | imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 + |
247 | 6.60M | (col + S.left_margin)]; |
248 | 6.60M | int cc = FC(r, c); |
249 | 6.60M | if (val > cblack[cc]) |
250 | 2.09M | { |
251 | 2.09M | val -= cblack[cc]; |
252 | 2.09M | if (val > ldmax) |
253 | 334k | ldmax = val; |
254 | 2.09M | } |
255 | 4.51M | else |
256 | 4.51M | val = 0; |
257 | 6.60M | imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)][cc] = |
258 | 6.60M | val; |
259 | 6.60M | } |
260 | 7.11M | } |
261 | | #if defined(LIBRAW_USE_OPENMP) |
262 | | #pragma omp critical(dataupdate) |
263 | | #endif |
264 | 129k | { |
265 | 129k | if (*dmaxp < ldmax) |
266 | 9.61k | *dmaxp = ldmax; |
267 | 129k | } |
268 | 129k | } |
269 | 4.11k | } |
270 | | |
271 | | void LibRaw::copy_bayer(unsigned short cblack[4], unsigned short *dmaxp) |
272 | 24.6k | { |
273 | | // Both cropped and uncropped |
274 | 24.6k | int maxHeight = MIN(int(S.height),int(S.raw_height)-int(S.top_margin)); |
275 | | #if defined(LIBRAW_USE_OPENMP) |
276 | | #pragma omp parallel for schedule(dynamic) default(none) shared(dmaxp) firstprivate(cblack, maxHeight) |
277 | | #endif |
278 | 8.64M | for (int row = 0; row < maxHeight ; row++) |
279 | 8.62M | { |
280 | 8.62M | int col; |
281 | 8.62M | unsigned short ldmax = 0; |
282 | 2.03G | for (col = 0; col < S.width && col + S.left_margin < S.raw_width; col++) |
283 | 2.02G | { |
284 | 2.02G | unsigned short val = |
285 | 2.02G | imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 + |
286 | 2.02G | (col + S.left_margin)]; |
287 | 2.02G | int cc = fcol(row, col); |
288 | 2.02G | if (val > cblack[cc]) |
289 | 1.13G | { |
290 | 1.13G | val -= cblack[cc]; |
291 | 1.13G | if (val > ldmax) |
292 | 20.2M | ldmax = val; |
293 | 1.13G | } |
294 | 888M | else |
295 | 888M | val = 0; |
296 | 2.02G | imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][cc] = val; |
297 | 2.02G | } |
298 | | #if defined(LIBRAW_USE_OPENMP) |
299 | | #pragma omp critical(dataupdate) |
300 | | #endif |
301 | 8.62M | { |
302 | 8.62M | if (*dmaxp < ldmax) |
303 | 50.6k | *dmaxp = ldmax; |
304 | 8.62M | } |
305 | 8.62M | } |
306 | 24.6k | } |
307 | | |
308 | | int LibRaw::raw2image_ex(int do_subtract_black) |
309 | 31.8k | { |
310 | | |
311 | 31.8k | CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); |
312 | | |
313 | 31.8k | try |
314 | 31.8k | { |
315 | 31.8k | raw2image_start(); |
316 | 31.8k | bool free_p1_buffer = false; |
317 | | |
318 | | // Compressed P1 files with bl data! |
319 | 31.8k | if (is_phaseone_compressed() && (imgdata.rawdata.raw_alloc || (imgdata.process_warnings & LIBRAW_WARN_RAWSPEED3_PROCESSED))) |
320 | 2.76k | { |
321 | 2.76k | phase_one_allocate_tempbuffer(); |
322 | 2.76k | free_p1_buffer = true; |
323 | 2.76k | int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc, |
324 | 2.76k | imgdata.rawdata.raw_image); |
325 | 2.76k | if (rc == 0 && imgdata.params.use_p1_correction) |
326 | 2.76k | rc = phase_one_correct(); |
327 | 2.76k | if (rc != 0) |
328 | 0 | { |
329 | 0 | phase_one_free_tempbuffer(); |
330 | 0 | return rc; |
331 | 0 | } |
332 | 2.76k | } |
333 | | |
334 | | // process cropping |
335 | 31.8k | int do_crop = 0; |
336 | 31.8k | if (~O.cropbox[2] && ~O.cropbox[3]) |
337 | 0 | { |
338 | 0 | int crop[4], c, filt; |
339 | 0 | for (int q = 0; q < 4; q++) |
340 | 0 | { |
341 | 0 | crop[q] = O.cropbox[q]; |
342 | 0 | if (crop[q] < 0) |
343 | 0 | crop[q] = 0; |
344 | 0 | } |
345 | |
|
346 | 0 | if (IO.fuji_width && imgdata.idata.filters >= 1000) |
347 | 0 | { |
348 | 0 | crop[0] = (crop[0] / 4) * 4; |
349 | 0 | crop[1] = (crop[1] / 4) * 4; |
350 | 0 | if (!libraw_internal_data.unpacker_data.fuji_layout) |
351 | 0 | { |
352 | 0 | crop[2] = int(crop[2] * sqrtf(2.f)); |
353 | 0 | crop[3] = int(crop[3] / sqrtf(2.f)); |
354 | 0 | } |
355 | 0 | crop[2] = (crop[2] / 4 + 1) * 4; |
356 | 0 | crop[3] = (crop[3] / 4 + 1) * 4; |
357 | 0 | } |
358 | 0 | else if (imgdata.idata.filters == 1) |
359 | 0 | { |
360 | 0 | crop[0] = (crop[0] / 16) * 16; |
361 | 0 | crop[1] = (crop[1] / 16) * 16; |
362 | 0 | } |
363 | 0 | else if (imgdata.idata.filters == LIBRAW_XTRANS) |
364 | 0 | { |
365 | 0 | crop[0] = (crop[0] / 6) * 6; |
366 | 0 | crop[1] = (crop[1] / 6) * 6; |
367 | 0 | } |
368 | 0 | do_crop = 1; |
369 | |
|
370 | 0 | crop[2] = MIN(crop[2], (signed)S.width - crop[0]); |
371 | 0 | crop[3] = MIN(crop[3], (signed)S.height - crop[1]); |
372 | 0 | if (crop[2] <= 0 || crop[3] <= 0) |
373 | 0 | throw LIBRAW_EXCEPTION_BAD_CROP; |
374 | | |
375 | | // adjust sizes! |
376 | 0 | S.left_margin += crop[0]; |
377 | 0 | S.top_margin += crop[1]; |
378 | 0 | S.width = crop[2]; |
379 | 0 | S.height = crop[3]; |
380 | |
|
381 | 0 | S.iheight = (S.height + IO.shrink) >> IO.shrink; |
382 | 0 | S.iwidth = (S.width + IO.shrink) >> IO.shrink; |
383 | 0 | if (!IO.fuji_width && imgdata.idata.filters && |
384 | 0 | imgdata.idata.filters >= 1000) |
385 | 0 | { |
386 | 0 | for (filt = c = 0; c < 16; c++) |
387 | 0 | filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2; |
388 | 0 | imgdata.idata.filters = filt; |
389 | 0 | } |
390 | 0 | } |
391 | | |
392 | 31.8k | int extra = P1.filters ? (P1.filters == 9 ? 6 : 2) : 0; |
393 | 31.8k | int alloc_width = S.iwidth + extra; |
394 | 31.8k | int alloc_height = S.iheight + extra; |
395 | | |
396 | 31.8k | if (IO.fuji_width && do_crop) |
397 | 0 | { |
398 | 0 | int IO_fw = S.width >> int(!libraw_internal_data.unpacker_data.fuji_layout); |
399 | 0 | int t_alloc_width = |
400 | 0 | (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO_fw; |
401 | 0 | int t_alloc_height = t_alloc_width - 1; |
402 | 0 | alloc_height = (t_alloc_height + IO.shrink) >> IO.shrink; |
403 | 0 | alloc_width = (t_alloc_width + IO.shrink) >> IO.shrink; |
404 | 0 | } |
405 | 31.8k | int alloc_sz = alloc_width * alloc_height; |
406 | | |
407 | 31.8k | if (imgdata.image) |
408 | 26.9k | { |
409 | 26.9k | imgdata.image = (ushort(*)[4])realloc(imgdata.image, |
410 | 26.9k | alloc_sz * sizeof(*imgdata.image)); |
411 | 26.9k | memset(imgdata.image, 0, alloc_sz * sizeof(*imgdata.image)); |
412 | 26.9k | } |
413 | 4.92k | else |
414 | 4.92k | imgdata.image = (ushort(*)[4])calloc(alloc_sz, sizeof(*imgdata.image)); |
415 | | |
416 | 31.8k | libraw_decoder_info_t decoder_info; |
417 | 31.8k | get_decoder_info(&decoder_info); |
418 | | |
419 | | // Adjust black levels |
420 | 31.8k | unsigned short cblack[4] = {0, 0, 0, 0}; |
421 | 31.8k | unsigned short dmax = 0; |
422 | 31.8k | if (do_subtract_black) |
423 | 27.4k | { |
424 | 27.4k | adjust_bl(); |
425 | 137k | for (int i = 0; i < 4; i++) |
426 | 109k | cblack[i] = (unsigned short)C.cblack[i]; |
427 | 27.4k | } |
428 | | |
429 | | // Max area size to definitely not overrun in/out buffers |
430 | 31.8k | int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin))); |
431 | 31.8k | int copywidth = MAX(0, MIN(int(S.width), int(S.raw_width) - int(S.left_margin))); |
432 | | |
433 | | // Move saved bitmap to imgdata.image |
434 | 31.8k | if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image) |
435 | 28.7k | { |
436 | 28.7k | if (IO.fuji_width) |
437 | 4.11k | { |
438 | 4.11k | if (do_crop) |
439 | 0 | { |
440 | 0 | IO.fuji_width = |
441 | 0 | S.width >> int(!libraw_internal_data.unpacker_data.fuji_layout); |
442 | 0 | int IO_fwidth = |
443 | 0 | (S.height >> int(libraw_internal_data.unpacker_data.fuji_layout)) + |
444 | 0 | IO.fuji_width; |
445 | 0 | int IO_fheight = IO_fwidth - 1; |
446 | |
|
447 | 0 | int row, col; |
448 | 0 | for (row = 0; row < S.height; row++) |
449 | 0 | { |
450 | 0 | for (col = 0; col < S.width; col++) |
451 | 0 | { |
452 | 0 | int r, c; |
453 | 0 | if (libraw_internal_data.unpacker_data.fuji_layout) |
454 | 0 | { |
455 | 0 | r = IO.fuji_width - 1 - col + (row >> 1); |
456 | 0 | c = col + ((row + 1) >> 1); |
457 | 0 | } |
458 | 0 | else |
459 | 0 | { |
460 | 0 | r = IO.fuji_width - 1 + row - (col >> 1); |
461 | 0 | c = row + ((col + 1) >> 1); |
462 | 0 | } |
463 | |
|
464 | 0 | unsigned short val = |
465 | 0 | imgdata.rawdata |
466 | 0 | .raw_image[(row + S.top_margin) * S.raw_pitch / 2 + |
467 | 0 | (col + S.left_margin)]; |
468 | 0 | int cc = FCF(row, col); |
469 | 0 | if (val > cblack[cc]) |
470 | 0 | { |
471 | 0 | val -= cblack[cc]; |
472 | 0 | if (dmax < val) |
473 | 0 | dmax = val; |
474 | 0 | } |
475 | 0 | else |
476 | 0 | val = 0; |
477 | 0 | imgdata.image[((r) >> IO.shrink) * alloc_width + |
478 | 0 | ((c) >> IO.shrink)][cc] = val; |
479 | 0 | } |
480 | 0 | } |
481 | 0 | S.height = IO_fheight; |
482 | 0 | S.width = IO_fwidth; |
483 | 0 | S.iheight = (S.height + IO.shrink) >> IO.shrink; |
484 | 0 | S.iwidth = (S.width + IO.shrink) >> IO.shrink; |
485 | 0 | S.raw_height -= 2 * S.top_margin; |
486 | 0 | } |
487 | 4.11k | else |
488 | 4.11k | { |
489 | 4.11k | copy_fuji_uncropped(cblack, &dmax); |
490 | 4.11k | } |
491 | 4.11k | } // end Fuji |
492 | 24.6k | else |
493 | 24.6k | { |
494 | 24.6k | copy_bayer(cblack, &dmax); |
495 | 24.6k | } |
496 | 28.7k | } |
497 | 3.07k | else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY) |
498 | 3.07k | { |
499 | 3.07k | if (imgdata.rawdata.color4_image) |
500 | 2.87k | { |
501 | 2.87k | if (S.raw_pitch != S.width * 8u || S.height != S.raw_height) |
502 | 413 | { |
503 | 113k | for (int row = 0; row < copyheight; row++) |
504 | 112k | memmove(&imgdata.image[row * S.width], |
505 | 112k | &imgdata.rawdata |
506 | 112k | .color4_image[(row + S.top_margin) * S.raw_pitch / 8 + |
507 | 112k | S.left_margin], |
508 | 112k | copywidth * sizeof(*imgdata.image)); |
509 | 413 | } |
510 | 2.46k | else |
511 | 2.46k | { |
512 | | // legacy is always 4channel and not shrinked! |
513 | 2.46k | memmove(imgdata.image, imgdata.rawdata.color4_image, |
514 | 2.46k | S.width*copyheight * sizeof(*imgdata.image)); |
515 | 2.46k | } |
516 | 2.87k | } |
517 | 196 | else if (imgdata.rawdata.color3_image) |
518 | 196 | { |
519 | 196 | unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image; |
520 | 848k | for (int row = 0; row < copyheight; row++) |
521 | 848k | { |
522 | 848k | ushort(*srcrow)[3] = |
523 | 848k | (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch]; |
524 | 848k | ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width]; |
525 | 36.3M | for (int col = 0; col < copywidth; col++) |
526 | 35.5M | { |
527 | 142M | for (int c = 0; c < 3; c++) |
528 | 106M | dstrow[col][c] = srcrow[S.left_margin + col][c]; |
529 | 35.5M | dstrow[col][3] = 0; |
530 | 35.5M | } |
531 | 848k | } |
532 | 196 | } |
533 | 0 | else |
534 | 0 | { |
535 | | // legacy decoder, but no data? |
536 | 0 | throw LIBRAW_EXCEPTION_DECODE_RAW; |
537 | 0 | } |
538 | 3.07k | } |
539 | | |
540 | | // Free PhaseOne separate copy allocated at function start |
541 | 31.8k | if (free_p1_buffer) |
542 | 2.76k | { |
543 | 2.76k | phase_one_free_tempbuffer(); |
544 | 2.76k | } |
545 | 31.8k | if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width) |
546 | 763 | { |
547 | 763 | canon_600_correct(); |
548 | 763 | } |
549 | | |
550 | 31.8k | if (do_subtract_black) |
551 | 27.4k | { |
552 | 27.4k | C.data_maximum = (int)dmax; |
553 | 27.4k | C.maximum -= C.black; |
554 | | // ZERO(C.cblack); |
555 | 27.4k | C.cblack[0] = C.cblack[1] = C.cblack[2] = C.cblack[3] = 0; |
556 | 27.4k | C.black = 0; |
557 | 27.4k | } |
558 | | |
559 | | // hack - clear later flags! |
560 | 31.8k | imgdata.progress_flags = |
561 | 31.8k | LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN | |
562 | 31.8k | LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY | |
563 | 31.8k | LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW; |
564 | 31.8k | return 0; |
565 | 31.8k | } |
566 | 31.8k | catch (const LibRaw_exceptions& err) |
567 | 31.8k | { |
568 | 0 | EXCEPTION_HANDLER(err); |
569 | 0 | } |
570 | 31.8k | } |