/src/LibRaw/src/decoders/kodak_decoders.cpp
Line | Count | Source |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2025 LibRaw LLC (info@libraw.org) |
3 | | * |
4 | | LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, |
5 | | dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. |
6 | | LibRaw do not use RESTRICTED code from dcraw.c |
7 | | |
8 | | LibRaw is free software; you can redistribute it and/or modify |
9 | | it under the terms of the one of two licenses as you choose: |
10 | | |
11 | | 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
12 | | (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
13 | | |
14 | | 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
15 | | (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
16 | | |
17 | | */ |
18 | | |
19 | | #include "../../internal/dcraw_defs.h" |
20 | | |
21 | 997k | #define radc_token(tree) ((signed char)getbithuff(8, huff + (tree) * 256)) |
22 | | |
23 | | #define FORYX \ |
24 | 1.46M | for (y = 1; y < 3; y++) \ |
25 | 2.92M | for (x = col + 1; x >= col; x--) |
26 | | |
27 | | #define PREDICTOR \ |
28 | 1.51M | (c ? (buf[c][y - 1][x] + buf[c][y][x + 1]) / 2 \ |
29 | 1.51M | : (buf[c][y - 1][x + 1] + 2 * buf[c][y - 1][x] + buf[c][y][x + 1]) / 4) |
30 | | |
31 | | #ifdef __GNUC__ |
32 | | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) |
33 | | #pragma GCC optimize("no-aggressive-loop-optimizations") |
34 | | #endif |
35 | | #endif |
36 | | |
37 | | void LibRaw::kodak_radc_load_raw() |
38 | 121 | { |
39 | | // All kodak radc images are 768x512 |
40 | 121 | if (width > 768 || raw_width > 768 || height > 512 || raw_height > 512) |
41 | 4 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
42 | 117 | static const signed char src[] = { |
43 | 117 | 1, 1, 2, 3, 3, 4, 4, 2, 5, 7, 6, 5, 7, 6, 7, 8, 1, 0, |
44 | 117 | 2, 1, 3, 3, 4, 4, 5, 2, 6, 7, 7, 6, 8, 5, 8, 8, 2, 1, |
45 | 117 | 2, 3, 3, 0, 3, 2, 3, 4, 4, 6, 5, 5, 6, 7, 6, 8, 2, 0, |
46 | 117 | 2, 1, 2, 3, 3, 2, 4, 4, 5, 6, 6, 7, 7, 5, 7, 8, 2, 1, |
47 | 117 | 2, 4, 3, 0, 3, 2, 3, 3, 4, 7, 5, 5, 6, 6, 6, 8, 2, 3, |
48 | 117 | 3, 1, 3, 2, 3, 4, 3, 5, 3, 6, 4, 7, 5, 0, 5, 8, 2, 3, |
49 | 117 | 2, 6, 3, 0, 3, 1, 4, 4, 4, 5, 4, 7, 5, 2, 5, 8, 2, 4, |
50 | 117 | 2, 7, 3, 3, 3, 6, 4, 1, 4, 2, 4, 5, 5, 0, 5, 8, 2, 6, |
51 | 117 | 3, 1, 3, 3, 3, 5, 3, 7, 3, 8, 4, 0, 5, 2, 5, 4, 2, 0, |
52 | 117 | 2, 1, 3, 2, 3, 3, 4, 4, 4, 5, 5, 6, 5, 7, 4, 8, 1, 0, |
53 | 117 | 2, 2, 2, -2, 1, -3, 1, 3, 2, -17, 2, -5, 2, 5, 2, 17, 2, -7, |
54 | 117 | 2, 2, 2, 9, 2, 18, 2, -18, 2, -9, 2, -2, 2, 7, 2, -28, 2, 28, |
55 | 117 | 3, -49, 3, -9, 3, 9, 4, 49, 5, -79, 5, 79, 2, -1, 2, 13, 2, 26, |
56 | 117 | 3, 39, 4, -16, 5, 55, 6, -37, 6, 76, 2, -26, 2, -13, 2, 1, 3, -39, |
57 | 117 | 4, 16, 5, -55, 6, -76, 6, 37}; |
58 | 117 | std::vector<ushort> huff_buffer(19 * 256,0); |
59 | 117 | ushort* huff = &huff_buffer[0]; |
60 | 117 | int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val; |
61 | 117 | short last[3] = {16, 16, 16}, mul[3], buf[3][3][386]; |
62 | 117 | static const ushort pt[] = {0, 0, 1280, 1344, 2320, 3616, |
63 | 117 | 3328, 8000, 4095, 16383, 65535, 16383}; |
64 | | |
65 | 702 | for (i = 2; i < 12; i += 2) |
66 | 7.66M | for (c = pt[i - 2]; c <= pt[i]; c++) |
67 | 7.66M | curve[c] = ushort((float)(c - pt[i - 2]) / (pt[i] - pt[i - 2]) * |
68 | 7.66M | (pt[i + 1] - pt[i - 1]) + |
69 | 7.66M | pt[i - 1] + 0.5f); |
70 | 15.3k | for (s = i = 0; i < int(sizeof src); i += 2) |
71 | 15.2k | FORC(256 >> src[i]) |
72 | 539k | ((ushort *)huff)[s++] = src[i] << 8 | (uchar)src[i + 1]; |
73 | 117 | s = kodak_cbpp == 243 ? 2 : 3; |
74 | 29.9k | FORC(256) huff[18 * 256 + c] = (8 - s) << 8 | c >> s << s | 1 << (s - 1); |
75 | 117 | getbits(-1); |
76 | 406k | for (i = 0; i < int(sizeof(buf) / sizeof(short)); i++) |
77 | 406k | ((short *)buf)[i] = 2048; |
78 | 1.01k | for (row = 0; row < height; row += 4) |
79 | 916 | { |
80 | 916 | checkCancel(); |
81 | 2.74k | FORC3 mul[c] = getbits(6); |
82 | 916 | if (!mul[0] || !mul[1] || !mul[2]) |
83 | 14 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
84 | 902 | FORC3 |
85 | 2.55k | { |
86 | 2.55k | val = ((0x1000000 / last[c] + 0x7ff) >> 12) * mul[c]; |
87 | 2.55k | s = val > 65564 ? 10 : 12; |
88 | 2.55k | x = ~((~0u) << (s - 1)); |
89 | 2.55k | val <<= 12 - s; |
90 | 2.95M | for (i = 0; i < int(sizeof(buf[0]) / sizeof(short)); i++) |
91 | 2.95M | ((short *)buf[c])[i] = |
92 | 2.95M | short((MIN(0x7FFFFFFF, (((short *)buf[c])[i] * static_cast<long long>(val) + x)) >> s) & 0xffff); |
93 | 2.55k | last[c] = mul[c]; |
94 | 5.96k | for (r = 0; r <= int(!c); r++) |
95 | 3.41k | { |
96 | 3.41k | buf[c][1][width / 2] = buf[c][2][width / 2] = mul[c] << 7; |
97 | 219k | for (tree = 1, col = width / 2; col > 0;) |
98 | 215k | { |
99 | 215k | if ((tree = radc_token(tree))) |
100 | 155k | { |
101 | 155k | col -= 2; |
102 | 155k | if (col >= 0) |
103 | 154k | { |
104 | 154k | if (tree == 8) |
105 | 21.6k | FORYX buf[c][y][x] = (uchar)radc_token(18) * mul[c]; |
106 | 148k | else |
107 | 595k | FORYX buf[c][y][x] = radc_token(tree + 10) * 16 + PREDICTOR; |
108 | 154k | } |
109 | 155k | } |
110 | 60.6k | else |
111 | 60.6k | do |
112 | 63.8k | { |
113 | 63.8k | nreps = (col > 2) ? radc_token(9) + 1 : 1; |
114 | 295k | for (rep = 0; rep < 8 && rep < nreps && col > 0; rep++) |
115 | 231k | { |
116 | 231k | col -= 2; |
117 | 231k | if (col >= 0) |
118 | 923k | FORYX buf[c][y][x] = PREDICTOR; |
119 | 231k | if (rep & 1) |
120 | 101k | { |
121 | 101k | step = radc_token(10) << 4; |
122 | 407k | FORYX buf[c][y][x] += step; |
123 | 101k | } |
124 | 231k | } |
125 | 63.8k | } while (nreps == 9); |
126 | 215k | } |
127 | 10.0k | for (y = 0; y < 2; y++) |
128 | 1.53M | for (x = 0; x < width / 2; x++) |
129 | 1.52M | { |
130 | 1.52M | val = (buf[c][y + 1][x] << 4) / mul[c]; |
131 | 1.52M | if (val < 0) |
132 | 129k | val = 0; |
133 | 1.52M | if (c) |
134 | 1.52M | RAW(row + y * 2 + c - 1, x * 2 + 2 - c) = val; |
135 | 782k | else |
136 | 1.52M | RAW(row + r * 2 + y, x * 2 + y) = val; |
137 | 1.52M | } |
138 | 3.41k | memcpy(buf[c][0] + !c, buf[c][2], sizeof buf[c][0] - 2 * !c); |
139 | 3.41k | } |
140 | 2.55k | } |
141 | 4.11k | for (y = row; y < row + 4; y++) |
142 | 1.47M | for (x = 0; x < width; x++) |
143 | 1.47M | if ((x + y) & 1) |
144 | 735k | { |
145 | 735k | r = x ? x - 1 : x + 1; |
146 | 735k | s = x + 1 < width ? x + 1 : x - 1; |
147 | 735k | val = (RAW(y, x) - 2048) * 2 + (RAW(y, r) + RAW(y, s)) / 2; |
148 | 735k | if (val < 0) |
149 | 116k | val = 0; |
150 | 735k | RAW(y, x) = val; |
151 | 735k | } |
152 | 902 | } |
153 | 463k | for (i = 0; i < height * width; i++) |
154 | 462k | raw_image[i] = curve[raw_image[i]]; |
155 | 103 | maximum = 0x3fff; |
156 | 103 | } |
157 | | |
158 | | #undef FORYX |
159 | | #undef PREDICTOR |
160 | | |
161 | | #ifdef NO_JPEG |
162 | 0 | void LibRaw::kodak_jpeg_load_raw() {} |
163 | | #else |
164 | | static void jpegErrorExit_k(j_common_ptr /*cinfo*/) |
165 | | { |
166 | | throw LIBRAW_EXCEPTION_DECODE_JPEG; |
167 | | } |
168 | | |
169 | | // LibRaw's Kodak_jpeg_load_raw |
170 | | void LibRaw::kodak_jpeg_load_raw() |
171 | | { |
172 | | if (data_size < 1) |
173 | | throw LIBRAW_EXCEPTION_DECODE_JPEG; |
174 | | |
175 | | int row, col; |
176 | | struct jpeg_decompress_struct cinfo; |
177 | | struct jpeg_error_mgr pub; |
178 | | cinfo.err = jpeg_std_error(&pub); |
179 | | pub.error_exit = jpegErrorExit_k; |
180 | | |
181 | | if (INT64(data_size) > |
182 | | INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
183 | | throw LIBRAW_EXCEPTION_TOOBIG; |
184 | | |
185 | | unsigned char *jpg_buf = (unsigned char *)calloc(data_size,1); |
186 | | std::vector<uchar> pixel_buf(width * 3, 0); |
187 | | jpeg_create_decompress(&cinfo); |
188 | | |
189 | | fread(jpg_buf, data_size, 1, ifp); |
190 | | libraw_swab(jpg_buf, int(data_size)); |
191 | | try |
192 | | { |
193 | | jpeg_mem_src(&cinfo, jpg_buf, (unsigned long)data_size); |
194 | | int rc = jpeg_read_header(&cinfo, TRUE); |
195 | | if (rc != 1) |
196 | | throw LIBRAW_EXCEPTION_DECODE_JPEG; |
197 | | |
198 | | jpeg_start_decompress(&cinfo); |
199 | | if ((cinfo.output_width != width) || (cinfo.output_height * 2 != height) || |
200 | | (cinfo.output_components != 3)) |
201 | | { |
202 | | throw LIBRAW_EXCEPTION_DECODE_JPEG; |
203 | | } |
204 | | |
205 | | unsigned char *buf[1]; |
206 | | buf[0] = pixel_buf.data(); |
207 | | |
208 | | while (cinfo.output_scanline < cinfo.output_height) |
209 | | { |
210 | | checkCancel(); |
211 | | row = cinfo.output_scanline * 2; |
212 | | jpeg_read_scanlines(&cinfo, buf, 1); |
213 | | unsigned char(*pixel)[3] = (unsigned char(*)[3])buf[0]; |
214 | | for (col = 0; col < width; col += 2) |
215 | | { |
216 | | RAW(row + 0, col + 0) = pixel[col + 0][1] << 1; |
217 | | RAW(row + 1, col + 1) = pixel[col + 1][1] << 1; |
218 | | RAW(row + 0, col + 1) = pixel[col][0] + pixel[col + 1][0]; |
219 | | RAW(row + 1, col + 0) = pixel[col][2] + pixel[col + 1][2]; |
220 | | } |
221 | | } |
222 | | } |
223 | | catch (...) |
224 | | { |
225 | | jpeg_finish_decompress(&cinfo); |
226 | | jpeg_destroy_decompress(&cinfo); |
227 | | free(jpg_buf); |
228 | | throw; |
229 | | } |
230 | | jpeg_finish_decompress(&cinfo); |
231 | | jpeg_destroy_decompress(&cinfo); |
232 | | free(jpg_buf); |
233 | | maximum = 0xff << 1; |
234 | | } |
235 | | #endif |
236 | | |
237 | | void LibRaw::kodak_dc120_load_raw() |
238 | 13 | { |
239 | 13 | static const int mul[4] = {162, 192, 187, 92}; |
240 | 13 | static const int add[4] = {0, 636, 424, 212}; |
241 | 13 | uchar pixel[848]; |
242 | 13 | int row, shift, col; |
243 | | |
244 | 1.27k | for (row = 0; row < height; row++) |
245 | 1.25k | { |
246 | 1.25k | checkCancel(); |
247 | 1.25k | if (fread(pixel, 1, 848, ifp) < 848) |
248 | 12 | derror(); |
249 | 1.25k | shift = row * mul[row & 3] + add[row & 3]; |
250 | 1.05M | for (col = 0; col < width; col++) |
251 | 1.05M | RAW(row, col) = (ushort)pixel[(col + shift) % 848]; |
252 | 1.25k | } |
253 | 13 | maximum = 0xff; |
254 | 13 | } |
255 | | void LibRaw::kodak_c330_load_raw() |
256 | 51 | { |
257 | 51 | if (!image) |
258 | 1 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
259 | 50 | int row, col, y, cb, cr, rgb[3], c; |
260 | | |
261 | 50 | std::vector<uchar> pixel(raw_width*2 + 4); |
262 | | |
263 | 10.8k | for (row = 0; row < height; row++) |
264 | 10.7k | { |
265 | 10.7k | checkCancel(); |
266 | 10.7k | if (fread(pixel.data(), raw_width, 2, ifp) < 2) |
267 | 49 | derror(); |
268 | 10.7k | if (load_flags && (row & 31) == 31) |
269 | 309 | fseek(ifp, raw_width * 32, SEEK_CUR); |
270 | 344k | for (col = 0; col < width; col++) |
271 | 333k | { |
272 | 333k | y = pixel[col * 2]; |
273 | 333k | cb = pixel[(col * 2 & -4) | 1] - 128; |
274 | 333k | cr = pixel[(col * 2 & -4) | 3] - 128; |
275 | 333k | rgb[1] = y - ((cb + cr + 2) >> 2); |
276 | 333k | rgb[2] = rgb[1] + cb; |
277 | 333k | rgb[0] = rgb[1] + cr; |
278 | 1.00M | FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)]; |
279 | 333k | } |
280 | 10.7k | } |
281 | 50 | maximum = curve[0xff]; |
282 | 50 | } |
283 | | |
284 | | void LibRaw::kodak_c603_load_raw() |
285 | 38 | { |
286 | 38 | if (!image) |
287 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
288 | 38 | int row, col, y, cb, cr, rgb[3], c; |
289 | | |
290 | 38 | std::vector<uchar> pixel(raw_width * 3); |
291 | 1.77k | for (row = 0; row < height; row++) |
292 | 1.73k | { |
293 | 1.73k | checkCancel(); |
294 | 1.73k | if (~row & 1) |
295 | 887 | if (fread(pixel.data(), raw_width, 3, ifp) < 3) |
296 | 36 | derror(); |
297 | 337k | for (col = 0; col < width; col++) |
298 | 335k | { |
299 | 335k | y = pixel[width * 2 * (row & 1) + col]; |
300 | 335k | cb = pixel[width + (col & -2)] - 128; |
301 | 335k | cr = pixel[width + (col & -2) + 1] - 128; |
302 | 335k | rgb[1] = y - ((cb + cr + 2) >> 2); |
303 | 335k | rgb[2] = rgb[1] + cb; |
304 | 335k | rgb[0] = rgb[1] + cr; |
305 | 1.00M | FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)]; |
306 | 335k | } |
307 | 1.73k | } |
308 | 38 | maximum = curve[0xff]; |
309 | 38 | } |
310 | | |
311 | | void LibRaw::kodak_262_load_raw() |
312 | 290 | { |
313 | 290 | static const uchar kodak_tree[2][26] = { |
314 | 290 | {0, 1, 5, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, |
315 | 290 | 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, |
316 | 290 | {0, 3, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, |
317 | 290 | 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}; |
318 | 290 | ushort *huff[2]; |
319 | 290 | int *strip, ns, c, row, col, chess, pi = 0, pi1, pi2, pred, val; |
320 | | |
321 | 580 | FORC(2) huff[c] = make_decoder(kodak_tree[c]); |
322 | 290 | ns = (raw_height + 63) >> 5; |
323 | 290 | std::vector<uchar> pixel(raw_width * 32 + ns * 4); |
324 | 290 | strip = (int *)(pixel.data() + raw_width * 32); |
325 | 290 | order = 0x4d4d; |
326 | 4.93k | FORC(ns) strip[c] = get4(); |
327 | 290 | try |
328 | 290 | { |
329 | 108k | for (row = 0; row < raw_height; row++) |
330 | 108k | { |
331 | 108k | checkCancel(); |
332 | 108k | if ((row & 31) == 0) |
333 | 3.53k | { |
334 | 3.53k | fseek(ifp, strip[row >> 5], SEEK_SET); |
335 | 3.53k | getbits(-1); |
336 | 3.53k | pi = 0; |
337 | 3.53k | } |
338 | 45.6M | for (col = 0; col < raw_width; col++) |
339 | 45.5M | { |
340 | 45.5M | chess = (row + col) & 1; |
341 | 45.5M | pi1 = chess ? pi - 2 : pi - raw_width - 1; |
342 | 45.5M | pi2 = chess ? pi - 2 * raw_width : pi - raw_width + 1; |
343 | 45.5M | if (col <= chess) |
344 | 162k | pi1 = -1; |
345 | 45.5M | if (pi1 < 0) |
346 | 967k | pi1 = pi2; |
347 | 45.5M | if (pi2 < 0) |
348 | 2.41M | pi2 = pi1; |
349 | 45.5M | if (pi1 < 0 && col > 1) |
350 | 802k | pi1 = pi2 = pi - 2; |
351 | 45.5M | pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1; |
352 | 45.5M | pixel[pi] = val = pred + ljpeg_diff(huff[chess]); |
353 | 45.5M | if (val >> 8) |
354 | 36.8k | derror(); |
355 | 45.5M | val = curve[pixel[pi++]]; |
356 | 45.5M | RAW(row, col) = val; |
357 | 45.5M | } |
358 | 108k | } |
359 | 290 | } |
360 | 290 | catch (...) |
361 | 290 | { |
362 | 24 | FORC(2) free(huff[c]); |
363 | 12 | throw; |
364 | 12 | } |
365 | 556 | FORC(2) free(huff[c]); |
366 | 278 | } |
367 | | |
368 | | int LibRaw::kodak_65000_decode(short *out, int bsize) |
369 | 250k | { |
370 | 250k | uchar c, blen[768]; |
371 | 250k | ushort raw[6]; |
372 | 250k | INT64 bitbuf = 0; |
373 | 250k | int bits = 0, i, j, len, diff; |
374 | 250k | INT64 save; |
375 | | |
376 | 250k | save = ftell(ifp); |
377 | 250k | bsize = (bsize + 3) & -4; |
378 | 310k | for (i = 0; i < bsize; i += 2) |
379 | 309k | { |
380 | 309k | c = fgetc(ifp); |
381 | 309k | if ((blen[i] = c & 15) > 12 || (blen[i + 1] = c >> 4) > 12) |
382 | 249k | { |
383 | 249k | fseek(ifp, save, SEEK_SET); |
384 | 6.53M | for (i = 0; i < bsize; i += 8) |
385 | 6.28M | { |
386 | 6.28M | read_shorts(raw, 6); |
387 | 6.28M | out[i] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12; |
388 | 6.28M | out[i + 1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12; |
389 | 43.9M | for (j = 0; j < 6; j++) |
390 | 37.7M | out[i + 2 + j] = raw[j] & 0xfff; |
391 | 6.28M | } |
392 | 249k | return 1; |
393 | 249k | } |
394 | 309k | } |
395 | 991 | if ((bsize & 7) == 4) |
396 | 551 | { |
397 | 551 | bitbuf = fgetc(ifp) << 8; |
398 | 551 | bitbuf += fgetc(ifp); |
399 | 551 | bits = 16; |
400 | 551 | } |
401 | 75.7k | for (i = 0; i < bsize; i++) |
402 | 74.7k | { |
403 | 74.7k | len = blen[i]; |
404 | 74.7k | if (bits < len) |
405 | 4.10k | { |
406 | 20.5k | for (j = 0; j < 32; j += 8) |
407 | 16.4k | bitbuf += (INT64)fgetc(ifp) << (bits + (j ^ 8)); |
408 | 4.10k | bits += 32; |
409 | 4.10k | } |
410 | 74.7k | diff = bitbuf & (0xffff >> (16 - len)); |
411 | 74.7k | bitbuf >>= len; |
412 | 74.7k | bits -= len; |
413 | 74.7k | if (len > 0 && (diff & (1 << (len - 1))) == 0) |
414 | 17.1k | diff -= (1 << len) - 1; |
415 | 74.7k | out[i] = diff; |
416 | 74.7k | } |
417 | 991 | return 0; |
418 | 250k | } |
419 | | |
420 | | void LibRaw::kodak_65000_load_raw() |
421 | 33 | { |
422 | 33 | short buf[272]; /* 264 looks enough */ |
423 | 33 | int row, col, len, pred[2], ret, i; |
424 | | |
425 | 12.3k | for (row = 0; row < height; row++) |
426 | 12.3k | { |
427 | 12.3k | checkCancel(); |
428 | 31.8k | for (col = 0; col < width; col += 256) |
429 | 19.4k | { |
430 | 19.4k | pred[0] = pred[1] = 0; |
431 | 19.4k | len = MIN(256, width - col); |
432 | 19.4k | ret = kodak_65000_decode(buf, len); |
433 | 2.89M | for (i = 0; i < len; i++) |
434 | 2.87M | { |
435 | 2.87M | int idx = ret ? buf[i] : (pred[i & 1] += buf[i]); |
436 | 2.87M | if (idx >= 0 && idx < 0xffff) |
437 | 2.87M | { |
438 | 2.87M | if ((RAW(row, col + i) = curve[idx]) >> 12) |
439 | 761k | derror(); |
440 | 2.87M | } |
441 | 4.28k | else |
442 | 4.28k | derror(); |
443 | 2.87M | } |
444 | 19.4k | } |
445 | 12.3k | } |
446 | 33 | } |
447 | | |
448 | | void LibRaw::kodak_ycbcr_load_raw() |
449 | 80 | { |
450 | 80 | if (!image) |
451 | 1 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
452 | 79 | short buf[384], *bp; |
453 | 79 | int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3]; |
454 | 79 | ushort *ip; |
455 | | |
456 | 79 | unsigned int bits = |
457 | 79 | (load_flags && load_flags > 9 && load_flags < 17) ? load_flags : 10; |
458 | 79 | const int pixels = int(width)*int(height); |
459 | 91.4k | for (row = 0; row < height; row += 2) |
460 | 91.3k | { |
461 | 91.3k | checkCancel(); |
462 | 253k | for (col = 0; col < width; col += 128) |
463 | 161k | { |
464 | 161k | len = MIN(128, width - col); |
465 | 161k | kodak_65000_decode(buf, len * 3); |
466 | 161k | y[0][1] = y[1][1] = cb = cr = 0; |
467 | 6.57M | for (bp = buf, i = 0; i < len; i += 2, bp += 2) |
468 | 6.41M | { |
469 | 6.41M | cb += bp[4]; |
470 | 6.41M | cr += bp[5]; |
471 | 6.41M | rgb[1] = -((cb + cr + 2) >> 2); |
472 | 6.41M | rgb[2] = rgb[1] + cb; |
473 | 6.41M | rgb[0] = rgb[1] + cr; |
474 | 19.2M | for (j = 0; j < 2; j++) |
475 | 38.4M | for (k = 0; k < 2; k++) |
476 | 25.6M | { |
477 | 25.6M | if ((y[j][k] = y[j][k ^ 1] + *bp++) >> bits) |
478 | 24.0M | derror(); |
479 | 25.6M | int indx = (row + j) * width + col + i + k; |
480 | 25.6M | if(indx>=0 && indx < pixels) |
481 | 25.6M | { |
482 | 25.6M | ip = image[indx]; |
483 | 76.9M | FORC3 ip[c] = curve[LIM(y[j][k] + rgb[c], 0, 0xfff)]; |
484 | 25.6M | } |
485 | 25.6M | } |
486 | 6.41M | } |
487 | 161k | } |
488 | 91.3k | } |
489 | 79 | } |
490 | | |
491 | | void LibRaw::kodak_rgb_load_raw() |
492 | 58 | { |
493 | 58 | if (!image) |
494 | 1 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
495 | 57 | short buf[768], *bp; |
496 | 57 | int row, col, len, c, i, rgb[3], ret; |
497 | 57 | ushort *ip = image[0]; |
498 | | |
499 | 65.6k | for (row = 0; row < height; row++) |
500 | 65.5k | { |
501 | 65.5k | checkCancel(); |
502 | 134k | for (col = 0; col < width; col += 256) |
503 | 69.3k | { |
504 | 69.3k | len = MIN(256, width - col); |
505 | 69.3k | ret = kodak_65000_decode(buf, len * 3); |
506 | 69.3k | memset(rgb, 0, sizeof rgb); |
507 | 2.84M | for (bp = buf, i = 0; i < len; i++, ip += 4) |
508 | 2.77M | if (load_flags == 12) |
509 | 0 | FORC3 ip[c] = ret ? (*bp++) : (rgb[c] += *bp++); |
510 | 2.77M | else |
511 | 8.33M | FORC3 if ((ip[c] = ret ? (*bp++) : (rgb[c] += *bp++)) >> 12) derror(); |
512 | 69.3k | } |
513 | 65.5k | } |
514 | 57 | } |
515 | | |
516 | | void LibRaw::kodak_thumb_load_raw() |
517 | 0 | { |
518 | 0 | if (!image) |
519 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
520 | 0 | int row, col; |
521 | 0 | colors = thumb_misc >> 5; |
522 | 0 | for (row = 0; row < height; row++) |
523 | 0 | for (col = 0; col < width; col++) |
524 | 0 | read_shorts(image[row * width + col], colors); |
525 | 0 | maximum = (1 << (thumb_misc & 31)) - 1; |
526 | 0 | } |