/src/libraw/src/decoders/decoders_libraw_dcrdefs.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 | | |
15 | | #include "../../internal/dcraw_defs.h" |
16 | | |
17 | | |
18 | | void LibRaw::nikon_he_load_raw() |
19 | 0 | { |
20 | 0 | if(dng_version) |
21 | 0 | throw LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT; // Never reached |
22 | 0 | throw LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT; |
23 | 0 | } |
24 | | |
25 | | void LibRaw::packed_tiled_dng_load_raw() |
26 | 32 | { |
27 | 32 | ushort *rp; |
28 | 32 | unsigned row, col; |
29 | | |
30 | 32 | int ss = shot_select; |
31 | 32 | shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss, 0, (LIBRAW_IFD_MAXCOUNT * 2 - 1))] & 0xff; |
32 | 32 | std::vector<ushort> pixel; |
33 | | |
34 | 32 | try |
35 | 32 | { |
36 | 32 | int ntiles = 1 + (raw_width) / tile_width; |
37 | 32 | if ((unsigned)ntiles * tile_width > raw_width * 2u) throw LIBRAW_EXCEPTION_ALLOC; |
38 | 32 | pixel.resize(tile_width * ntiles * tiff_samples); |
39 | 32 | } |
40 | 32 | catch (...) |
41 | 32 | { |
42 | 0 | throw LIBRAW_EXCEPTION_ALLOC; // rethrow |
43 | 0 | } |
44 | 32 | try |
45 | 32 | { |
46 | 32 | unsigned trow = 0, tcol = 0; |
47 | 32 | INT64 save; |
48 | 459 | while (trow < raw_height) |
49 | 427 | { |
50 | 427 | checkCancel(); |
51 | 427 | save = ftell(ifp); |
52 | 427 | if (tile_length < INT_MAX) |
53 | 427 | fseek(ifp, get4(), SEEK_SET); |
54 | | |
55 | 6.46k | for (row = 0; row < tile_length && (row + trow) < raw_height; row++) |
56 | 6.04k | { |
57 | 6.04k | if (tiff_bps == 16) |
58 | 679 | read_shorts(pixel.data(), tile_width * tiff_samples); |
59 | 5.36k | else |
60 | 5.36k | { |
61 | 5.36k | getbits(-1); |
62 | 34.4k | for (col = 0; col < tile_width * tiff_samples; col++) |
63 | 29.0k | pixel[col] = getbits(tiff_bps); |
64 | 5.36k | } |
65 | 41.4k | for (rp = pixel.data(), col = 0; col < tile_width; col++) |
66 | 35.4k | adobe_copy_pixel(trow+row, tcol+col, &rp); |
67 | 6.04k | } |
68 | 427 | fseek(ifp, save + 4, SEEK_SET); |
69 | 427 | if ((tcol += tile_width) >= raw_width) |
70 | 75 | trow += tile_length + (tcol = 0); |
71 | 427 | } |
72 | 32 | } |
73 | 32 | catch (...) |
74 | 32 | { |
75 | 31 | shot_select = ss; |
76 | 31 | throw; |
77 | 31 | } |
78 | 1 | shot_select = ss; |
79 | 1 | } |
80 | | |
81 | | |
82 | | void LibRaw::sony_ljpeg_load_raw() |
83 | 5 | { |
84 | 5 | unsigned trow = 0, tcol = 0, jrow, jcol, row, col; |
85 | 5 | INT64 save; |
86 | 5 | struct jhead jh; |
87 | | |
88 | 5 | while (trow < raw_height) |
89 | 5 | { |
90 | 5 | checkCancel(); |
91 | 5 | save = ftell(ifp); // We're at |
92 | 5 | if (tile_length < INT_MAX) |
93 | 0 | fseek(ifp, get4(), SEEK_SET); |
94 | 5 | if (!ljpeg_start(&jh, 0)) |
95 | 5 | break; |
96 | 0 | try |
97 | 0 | { |
98 | 0 | for (row = jrow = 0; jrow < (unsigned)jh.high && trow+row < raw_height-1; jrow++, row += 2) |
99 | 0 | { |
100 | 0 | checkCancel(); |
101 | 0 | ushort(*rowp)[4] = (ushort(*)[4])ljpeg_row(jrow, &jh); |
102 | 0 | for (col = jcol = 0; jcol < (unsigned)jh.wide && tcol+col < raw_width-1; jcol++, col += 2) |
103 | 0 | { |
104 | 0 | RAW(trow + row, tcol + col) = rowp[jcol][0]; |
105 | 0 | RAW(trow + row, tcol + col + 1) = rowp[jcol][1]; |
106 | 0 | RAW(trow + row + 1, tcol + col) = rowp[jcol][2]; |
107 | 0 | RAW(trow + row + 1, tcol + col + 1) = rowp[jcol][3]; |
108 | 0 | } |
109 | 0 | } |
110 | 0 | } |
111 | 0 | catch (...) |
112 | 0 | { |
113 | 0 | ljpeg_end(&jh); |
114 | 0 | throw; |
115 | 0 | } |
116 | 0 | fseek(ifp, save + 4, SEEK_SET); |
117 | 0 | if ((tcol += tile_width) >= raw_width) |
118 | 0 | trow += tile_length + (tcol = 0); |
119 | 0 | ljpeg_end(&jh); |
120 | 0 | } |
121 | 5 | } |
122 | | |
123 | | void LibRaw::nikon_coolscan_load_raw() |
124 | 63 | { |
125 | 63 | int clrs = colors == 3 ? 3 : 1; |
126 | | |
127 | 63 | if (clrs == 3 && !image) |
128 | 1 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
129 | | |
130 | 62 | if(clrs == 1 && !raw_image) |
131 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
132 | | |
133 | 62 | int bypp = tiff_bps <= 8 ? 1 : 2; |
134 | 62 | int bufsize = width * clrs * bypp; |
135 | 62 | unsigned char *buf = (unsigned char *)calloc(bufsize,1); |
136 | 62 | unsigned short *ubuf = (unsigned short *)buf; |
137 | | |
138 | 62 | if (tiff_bps <= 8) |
139 | 41 | gamma_curve(1.0 / imgdata.rawparams.coolscan_nef_gamma, 0., 1, 255); |
140 | 21 | else |
141 | 21 | gamma_curve(1.0 / imgdata.rawparams.coolscan_nef_gamma, 0., 1, 65535); |
142 | 62 | fseek(ifp, data_offset, SEEK_SET); |
143 | 9.68k | for (int row = 0; row < raw_height; row++) |
144 | 9.61k | { |
145 | 9.61k | if(tiff_bps <=8) |
146 | 9.19k | fread(buf, 1, bufsize, ifp); |
147 | 425 | else |
148 | 425 | read_shorts(ubuf,width*clrs); |
149 | | |
150 | 9.61k | unsigned short(*ip)[4] = (unsigned short(*)[4])image + row * width; |
151 | 9.61k | unsigned short *rp = raw_image + row * raw_width; |
152 | | |
153 | 9.61k | if (is_NikonTransfer == 2) |
154 | 1.50k | { // it is also (tiff_bps == 8) |
155 | 1.50k | if (clrs == 3) |
156 | 915 | { |
157 | 326k | for (int col = 0; col < width; col++) |
158 | 325k | { |
159 | 325k | ip[col][0] = ushort(((float)curve[buf[col * 3]]) / 255.0f); |
160 | 325k | ip[col][1] = ushort(((float)curve[buf[col * 3 + 1]]) / 255.0f); |
161 | 325k | ip[col][2] = ushort(((float)curve[buf[col * 3 + 2]]) / 255.0f); |
162 | 325k | ip[col][3] = 0; |
163 | 325k | } |
164 | 915 | } |
165 | 587 | else |
166 | 587 | { |
167 | 27.6k | for (int col = 0; col < width; col++) |
168 | 27.0k | rp[col] = ushort(((float)curve[buf[col]]) / 255.0f); |
169 | 587 | } |
170 | 1.50k | } |
171 | 8.11k | else if (tiff_bps <= 8) |
172 | 7.69k | { |
173 | 7.69k | if (clrs == 3) |
174 | 6.22k | { |
175 | 413k | for (int col = 0; col < width; col++) |
176 | 407k | { |
177 | 407k | ip[col][0] = curve[buf[col * 3]]; |
178 | 407k | ip[col][1] = curve[buf[col * 3 + 1]]; |
179 | 407k | ip[col][2] = curve[buf[col * 3 + 2]]; |
180 | 407k | ip[col][3] = 0; |
181 | 407k | } |
182 | 6.22k | } |
183 | 1.46k | else |
184 | 1.46k | { |
185 | 239k | for (int col = 0; col < width; col++) |
186 | 237k | rp[col] = curve[buf[col]]; |
187 | 1.46k | } |
188 | 7.69k | } |
189 | 425 | else |
190 | 425 | { |
191 | 425 | if (clrs == 3) |
192 | 148 | { |
193 | 4.45k | for (int col = 0; col < width; col++) |
194 | 4.31k | { |
195 | 4.31k | ip[col][0] = curve[ubuf[col * 3]]; |
196 | 4.31k | ip[col][1] = curve[ubuf[col * 3 + 1]]; |
197 | 4.31k | ip[col][2] = curve[ubuf[col * 3 + 2]]; |
198 | 4.31k | ip[col][3] = 0; |
199 | 4.31k | } |
200 | 148 | } |
201 | 277 | else |
202 | 277 | { |
203 | 6.81k | for (int col = 0; col < width; col++) |
204 | 6.54k | rp[col] = curve[ubuf[col]]; |
205 | 277 | } |
206 | 425 | } |
207 | 9.61k | } |
208 | 62 | free(buf); |
209 | 62 | } |
210 | | |
211 | | void LibRaw::broadcom_load_raw() |
212 | 0 | { |
213 | 0 | uchar *dp; |
214 | 0 | int rev, row, col, c; |
215 | 0 | rev = 3 * (order == 0x4949); |
216 | 0 | std::vector<uchar> data(raw_stride * 2); |
217 | |
|
218 | 0 | for (row = 0; row < raw_height; row++) |
219 | 0 | { |
220 | 0 | if (fread(data.data() + raw_stride, 1, raw_stride, ifp) < raw_stride) |
221 | 0 | derror(); |
222 | 0 | FORC(raw_stride) data[c] = data[raw_stride + (c ^ rev)]; |
223 | 0 | for (dp = data.data(), col = 0; col < raw_width; dp += 5, col += 4) |
224 | 0 | FORC4 RAW(row, col + c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); |
225 | 0 | } |
226 | 0 | } |
227 | | |
228 | | void LibRaw::android_tight_load_raw() |
229 | 0 | { |
230 | 0 | uchar *data, *dp; |
231 | 0 | int bwide, row, col, c; |
232 | |
|
233 | 0 | bwide = -(-5 * raw_width >> 5) << 3; |
234 | 0 | data = (uchar *)calloc(bwide,1); |
235 | 0 | for (row = 0; row < raw_height; row++) |
236 | 0 | { |
237 | 0 | if (fread(data, 1, bwide, ifp) < bwide) |
238 | 0 | derror(); |
239 | 0 | for (dp = data, col = 0; col < raw_width; dp += 5, col += 4) |
240 | 0 | FORC4 RAW(row, col + c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); |
241 | 0 | } |
242 | 0 | free(data); |
243 | 0 | } |
244 | | |
245 | | void LibRaw::android_loose_load_raw() |
246 | 0 | { |
247 | 0 | uchar *data, *dp; |
248 | 0 | int bwide, row, col, c; |
249 | 0 | UINT64 bitbuf = 0; |
250 | |
|
251 | 0 | bwide = (raw_width + 5) / 6 << 3; |
252 | 0 | data = (uchar *)calloc(bwide,1); |
253 | 0 | for (row = 0; row < raw_height; row++) |
254 | 0 | { |
255 | 0 | if (fread(data, 1, bwide, ifp) < bwide) |
256 | 0 | derror(); |
257 | 0 | for (dp = data, col = 0; col < raw_width; dp += 8, col += 6) |
258 | 0 | { |
259 | 0 | FORC(8) bitbuf = (bitbuf << 8) | dp[c ^ 7]; |
260 | 0 | FORC(6) RAW(row, col + c) = (bitbuf >> c * 10) & 0x3ff; |
261 | 0 | } |
262 | 0 | } |
263 | 0 | free(data); |
264 | 0 | } |
265 | | |
266 | | void LibRaw::unpacked_load_raw_reversed() |
267 | 0 | { |
268 | 0 | int row, col, bits = 0; |
269 | 0 | while (1 << ++bits < (int)maximum) |
270 | 0 | ; |
271 | 0 | for (row = raw_height - 1; row >= 0; row--) |
272 | 0 | { |
273 | 0 | checkCancel(); |
274 | 0 | read_shorts(&raw_image[row * raw_width], raw_width); |
275 | 0 | for (col = 0; col < raw_width; col++) |
276 | 0 | if ((RAW(row, col) >>= load_flags) >> bits && |
277 | 0 | (unsigned)(row - top_margin) < height && |
278 | 0 | (unsigned)(col - left_margin) < width) |
279 | 0 | derror(); |
280 | 0 | } |
281 | 0 | } |
282 | | |
283 | | #ifdef USE_6BY9RPI |
284 | | |
285 | | void LibRaw::rpi_load_raw8() |
286 | | { |
287 | | uchar *data, *dp; |
288 | | int rev, dwide, row, col, c; |
289 | | double sum[] = { 0,0 }; |
290 | | rev = 3 * (order == 0x4949); |
291 | | if (raw_stride == 0) |
292 | | dwide = raw_width; |
293 | | else |
294 | | dwide = raw_stride; |
295 | | data = (uchar *)calloc(dwide, 2); |
296 | | for (row = 0; row < raw_height; row++) { |
297 | | if (fread(data + dwide, 1, dwide, ifp) < dwide) derror(); |
298 | | FORC(dwide) data[c] = data[dwide + (c ^ rev)]; |
299 | | for (dp = data, col = 0; col < raw_width; dp++, col++) |
300 | | RAW(row, col + c) = dp[c]; |
301 | | } |
302 | | free(data); |
303 | | maximum = 0xff; |
304 | | if (!strcmp(make, "OmniVision") || |
305 | | !strcmp(make, "Sony") || |
306 | | !strcmp(make, "RaspberryPi")) return; |
307 | | |
308 | | row = raw_height / 2; |
309 | | FORC(width - 1) { |
310 | | sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); |
311 | | sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); |
312 | | } |
313 | | if (sum[1] > sum[0]) filters = 0x4b4b4b4b; |
314 | | } |
315 | | |
316 | | void LibRaw::rpi_load_raw12() |
317 | | { |
318 | | uchar *data, *dp; |
319 | | int rev, dwide, row, col, c; |
320 | | double sum[] = { 0,0 }; |
321 | | rev = 3 * (order == 0x4949); |
322 | | if (raw_stride == 0) |
323 | | dwide = (raw_width * 3 + 1) / 2; |
324 | | else |
325 | | dwide = raw_stride; |
326 | | data = (uchar *)calloc(dwide, 2); |
327 | | for (row = 0; row < raw_height; row++) { |
328 | | if (fread(data + dwide, 1, dwide, ifp) < dwide) derror(); |
329 | | FORC(dwide) data[c] = data[dwide + (c ^ rev)]; |
330 | | for (dp = data, col = 0; col < raw_width; dp += 3, col += 2) |
331 | | FORC(2) RAW(row, col + c) = (dp[c] << 4) | (dp[2] >> (c << 2) & 0xF); |
332 | | } |
333 | | free(data); |
334 | | maximum = 0xfff; |
335 | | if (!strcmp(make, "OmniVision") || |
336 | | !strcmp(make, "Sony") || |
337 | | !strcmp(make, "RaspberryPi")) return; |
338 | | |
339 | | row = raw_height / 2; |
340 | | FORC(width - 1) { |
341 | | sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); |
342 | | sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); |
343 | | } |
344 | | if (sum[1] > sum[0]) filters = 0x4b4b4b4b; |
345 | | } |
346 | | |
347 | | void LibRaw::rpi_load_raw14() |
348 | | { |
349 | | uchar *data, *dp; |
350 | | int rev, dwide, row, col, c; |
351 | | double sum[] = { 0,0 }; |
352 | | rev = 3 * (order == 0x4949); |
353 | | if (raw_stride == 0) |
354 | | dwide = ((raw_width * 7) + 3) >> 2; |
355 | | else |
356 | | dwide = raw_stride; |
357 | | data = (uchar *)calloc(dwide, 2); |
358 | | for (row = 0; row < raw_height; row++) { |
359 | | if (fread(data + dwide, 1, dwide, ifp) < dwide) derror(); |
360 | | FORC(dwide) data[c] = data[dwide + (c ^ rev)]; |
361 | | for (dp = data, col = 0; col < raw_width; dp += 7, col += 4) { |
362 | | RAW(row, col + 0) = (dp[0] << 6) | (dp[4] >> 2); |
363 | | RAW(row, col + 1) = (dp[1] << 6) | ((dp[4] & 0x3) << 4) | ((dp[5] & 0xf0) >> 4); |
364 | | RAW(row, col + 2) = (dp[2] << 6) | ((dp[5] & 0xf) << 2) | ((dp[6] & 0xc0) >> 6); |
365 | | RAW(row, col + 3) = (dp[3] << 6) | ((dp[6] & 0x3f) << 2); |
366 | | } |
367 | | } |
368 | | free(data); |
369 | | maximum = 0x3fff; |
370 | | if (!strcmp(make, "OmniVision") || |
371 | | !strcmp(make, "Sony") || |
372 | | !strcmp(make, "RaspberryPi")) return; |
373 | | |
374 | | row = raw_height / 2; |
375 | | FORC(width - 1) { |
376 | | sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); |
377 | | sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); |
378 | | } |
379 | | if (sum[1] > sum[0]) filters = 0x4b4b4b4b; |
380 | | } |
381 | | |
382 | | void LibRaw::rpi_load_raw16() |
383 | | { |
384 | | uchar *data, *dp; |
385 | | int rev, dwide, row, col, c; |
386 | | double sum[] = { 0,0 }; |
387 | | rev = 3 * (order == 0x4949); |
388 | | if (raw_stride == 0) |
389 | | dwide = (raw_width * 2); |
390 | | else |
391 | | dwide = raw_stride; |
392 | | data = (uchar *)calloc(dwide, 2); |
393 | | for (row = 0; row < raw_height; row++) { |
394 | | if (fread(data + dwide, 1, dwide, ifp) < dwide) derror(); |
395 | | FORC(dwide) data[c] = data[dwide + (c ^ rev)]; |
396 | | for (dp = data, col = 0; col < raw_width; dp += 2, col++) |
397 | | RAW(row, col + c) = (dp[1] << 8) | dp[0]; |
398 | | } |
399 | | free(data); |
400 | | maximum = 0xffff; |
401 | | if (!strcmp(make, "OmniVision") || |
402 | | !strcmp(make, "Sony") || |
403 | | !strcmp(make, "RaspberryPi")) return; |
404 | | |
405 | | row = raw_height / 2; |
406 | | FORC(width - 1) { |
407 | | sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); |
408 | | sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); |
409 | | } |
410 | | if (sum[1] > sum[0]) filters = 0x4b4b4b4b; |
411 | | } |
412 | | |
413 | | #endif |