/src/libraw/src/decoders/kodak_decoders.cpp
Line | Count | Source |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2024 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 | 126k | #define radc_token(tree) ((signed char)getbithuff(8, huff + (tree) * 256)) |
22 | | |
23 | | #define FORYX \ |
24 | 395k | for (y = 1; y < 3; y++) \ |
25 | 790k | for (x = col + 1; x >= col; x--) |
26 | | |
27 | | #define PREDICTOR \ |
28 | 369k | (c ? (buf[c][y - 1][x] + buf[c][y][x + 1]) / 2 \ |
29 | 369k | : (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 | 123 | { |
39 | | // All kodak radc images are 768x512 |
40 | 123 | if (width > 768 || raw_width > 768 || height > 512 || raw_height > 512) |
41 | 7 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
42 | 116 | static const signed char src[] = { |
43 | 116 | 1, 1, 2, 3, 3, 4, 4, 2, 5, 7, 6, 5, 7, 6, 7, 8, 1, 0, |
44 | 116 | 2, 1, 3, 3, 4, 4, 5, 2, 6, 7, 7, 6, 8, 5, 8, 8, 2, 1, |
45 | 116 | 2, 3, 3, 0, 3, 2, 3, 4, 4, 6, 5, 5, 6, 7, 6, 8, 2, 0, |
46 | 116 | 2, 1, 2, 3, 3, 2, 4, 4, 5, 6, 6, 7, 7, 5, 7, 8, 2, 1, |
47 | 116 | 2, 4, 3, 0, 3, 2, 3, 3, 4, 7, 5, 5, 6, 6, 6, 8, 2, 3, |
48 | 116 | 3, 1, 3, 2, 3, 4, 3, 5, 3, 6, 4, 7, 5, 0, 5, 8, 2, 3, |
49 | 116 | 2, 6, 3, 0, 3, 1, 4, 4, 4, 5, 4, 7, 5, 2, 5, 8, 2, 4, |
50 | 116 | 2, 7, 3, 3, 3, 6, 4, 1, 4, 2, 4, 5, 5, 0, 5, 8, 2, 6, |
51 | 116 | 3, 1, 3, 3, 3, 5, 3, 7, 3, 8, 4, 0, 5, 2, 5, 4, 2, 0, |
52 | 116 | 2, 1, 3, 2, 3, 3, 4, 4, 4, 5, 5, 6, 5, 7, 4, 8, 1, 0, |
53 | 116 | 2, 2, 2, -2, 1, -3, 1, 3, 2, -17, 2, -5, 2, 5, 2, 17, 2, -7, |
54 | 116 | 2, 2, 2, 9, 2, 18, 2, -18, 2, -9, 2, -2, 2, 7, 2, -28, 2, 28, |
55 | 116 | 3, -49, 3, -9, 3, 9, 4, 49, 5, -79, 5, 79, 2, -1, 2, 13, 2, 26, |
56 | 116 | 3, 39, 4, -16, 5, 55, 6, -37, 6, 76, 2, -26, 2, -13, 2, 1, 3, -39, |
57 | 116 | 4, 16, 5, -55, 6, -76, 6, 37}; |
58 | 116 | std::vector<ushort> huff_buffer(19 * 256,0); |
59 | 116 | ushort* huff = &huff_buffer[0]; |
60 | 116 | int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val; |
61 | 116 | short last[3] = {16, 16, 16}, mul[3], buf[3][3][386]; |
62 | 116 | static const ushort pt[] = {0, 0, 1280, 1344, 2320, 3616, |
63 | 116 | 3328, 8000, 4095, 16383, 65535, 16383}; |
64 | | |
65 | 696 | for (i = 2; i < 12; i += 2) |
66 | 7.60M | for (c = pt[i - 2]; c <= pt[i]; c++) |
67 | 7.60M | curve[c] = ushort((float)(c - pt[i - 2]) / (pt[i] - pt[i - 2]) * |
68 | 7.60M | (pt[i + 1] - pt[i - 1]) + |
69 | 7.60M | pt[i - 1] + 0.5f); |
70 | 15.1k | for (s = i = 0; i < int(sizeof src); i += 2) |
71 | 15.0k | FORC(256 >> src[i]) |
72 | 534k | ((ushort *)huff)[s++] = src[i] << 8 | (uchar)src[i + 1]; |
73 | 116 | s = kodak_cbpp == 243 ? 2 : 3; |
74 | 29.6k | FORC(256) huff[18 * 256 + c] = (8 - s) << 8 | c >> s << s | 1 << (s - 1); |
75 | 116 | getbits(-1); |
76 | 403k | for (i = 0; i < int(sizeof(buf) / sizeof(short)); i++) |
77 | 402k | ((short *)buf)[i] = 2048; |
78 | 650 | for (row = 0; row < height; row += 4) |
79 | 547 | { |
80 | 547 | checkCancel(); |
81 | 1.62k | FORC3 mul[c] = getbits(6); |
82 | 547 | if (!mul[0] || !mul[1] || !mul[2]) |
83 | 13 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
84 | 534 | FORC3 |
85 | 1.44k | { |
86 | 1.44k | val = ((0x1000000 / last[c] + 0x7ff) >> 12) * mul[c]; |
87 | 1.44k | s = val > 65564 ? 10 : 12; |
88 | 1.44k | x = ~((~0u) << (s - 1)); |
89 | 1.44k | val <<= 12 - s; |
90 | 1.67M | for (i = 0; i < int(sizeof(buf[0]) / sizeof(short)); i++) |
91 | 1.67M | ((short *)buf[c])[i] = |
92 | 1.67M | short((MIN(0x7FFFFFFF, (((short *)buf[c])[i] * static_cast<long long>(val) + x)) >> s) & 0xffff); |
93 | 1.44k | last[c] = mul[c]; |
94 | 3.38k | for (r = 0; r <= int(!c); r++) |
95 | 1.94k | { |
96 | 1.94k | buf[c][1][width / 2] = buf[c][2][width / 2] = mul[c] << 7; |
97 | 24.4k | for (tree = 1, col = width / 2; col > 0;) |
98 | 22.4k | { |
99 | 22.4k | if ((tree = radc_token(tree))) |
100 | 12.9k | { |
101 | 12.9k | col -= 2; |
102 | 12.9k | if (col >= 0) |
103 | 12.7k | { |
104 | 12.7k | if (tree == 8) |
105 | 2.08k | FORYX buf[c][y][x] = (uchar)radc_token(18) * mul[c]; |
106 | 12.2k | else |
107 | 49.0k | FORYX buf[c][y][x] = radc_token(tree + 10) * 16 + PREDICTOR; |
108 | 12.7k | } |
109 | 12.9k | } |
110 | 9.54k | else |
111 | 9.54k | do |
112 | 15.7k | { |
113 | 15.7k | nreps = (col > 2) ? radc_token(9) + 1 : 1; |
114 | 97.1k | for (rep = 0; rep < 8 && rep < nreps && col > 0; rep++) |
115 | 81.4k | { |
116 | 81.4k | col -= 2; |
117 | 81.4k | if (col >= 0) |
118 | 320k | FORYX buf[c][y][x] = PREDICTOR; |
119 | 81.4k | if (rep & 1) |
120 | 38.9k | { |
121 | 38.9k | step = radc_token(10) << 4; |
122 | 155k | FORYX buf[c][y][x] += step; |
123 | 38.9k | } |
124 | 81.4k | } |
125 | 15.7k | } while (nreps == 9); |
126 | 22.4k | } |
127 | 5.64k | for (y = 0; y < 2; y++) |
128 | 371k | for (x = 0; x < width / 2; x++) |
129 | 367k | { |
130 | 367k | val = (buf[c][y + 1][x] << 4) / mul[c]; |
131 | 367k | if (val < 0) |
132 | 2.64k | val = 0; |
133 | 367k | if (c) |
134 | 367k | RAW(row + y * 2 + c - 1, x * 2 + 2 - c) = val; |
135 | 190k | else |
136 | 367k | RAW(row + r * 2 + y, x * 2 + y) = val; |
137 | 367k | } |
138 | 1.94k | memcpy(buf[c][0] + !c, buf[c][2], sizeof buf[c][0] - 2 * !c); |
139 | 1.94k | } |
140 | 1.44k | } |
141 | 2.27k | for (y = row; y < row + 4; y++) |
142 | 352k | for (x = 0; x < width; x++) |
143 | 350k | if ((x + y) & 1) |
144 | 175k | { |
145 | 175k | r = x ? x - 1 : x + 1; |
146 | 175k | s = x + 1 < width ? x + 1 : x - 1; |
147 | 175k | val = (RAW(y, x) - 2048) * 2 + (RAW(y, r) + RAW(y, s)) / 2; |
148 | 175k | if (val < 0) |
149 | 3.39k | val = 0; |
150 | 175k | RAW(y, x) = val; |
151 | 175k | } |
152 | 534 | } |
153 | 5.64k | for (i = 0; i < height * width; i++) |
154 | 5.54k | 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 | 4 | { |
239 | 4 | static const int mul[4] = {162, 192, 187, 92}; |
240 | 4 | static const int add[4] = {0, 636, 424, 212}; |
241 | 4 | uchar pixel[848]; |
242 | 4 | int row, shift, col; |
243 | | |
244 | 18 | for (row = 0; row < height; row++) |
245 | 14 | { |
246 | 14 | checkCancel(); |
247 | 14 | if (fread(pixel, 1, 848, ifp) < 848) |
248 | 4 | derror(); |
249 | 14 | shift = row * mul[row & 3] + add[row & 3]; |
250 | 8.49k | for (col = 0; col < width; col++) |
251 | 8.48k | RAW(row, col) = (ushort)pixel[(col + shift) % 848]; |
252 | 14 | } |
253 | 4 | maximum = 0xff; |
254 | 4 | } |
255 | | void LibRaw::kodak_c330_load_raw() |
256 | 26 | { |
257 | 26 | if (!image) |
258 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
259 | 26 | int row, col, y, cb, cr, rgb[3], c; |
260 | | |
261 | 26 | std::vector<uchar> pixel(raw_width*2 + 4); |
262 | | |
263 | 663 | for (row = 0; row < height; row++) |
264 | 637 | { |
265 | 637 | checkCancel(); |
266 | 637 | if (fread(pixel.data(), raw_width, 2, ifp) < 2) |
267 | 26 | derror(); |
268 | 637 | if (load_flags && (row & 31) == 31) |
269 | 2 | fseek(ifp, raw_width * 32, SEEK_CUR); |
270 | 34.8k | for (col = 0; col < width; col++) |
271 | 34.2k | { |
272 | 34.2k | y = pixel[col * 2]; |
273 | 34.2k | cb = pixel[(col * 2 & -4) | 1] - 128; |
274 | 34.2k | cr = pixel[(col * 2 & -4) | 3] - 128; |
275 | 34.2k | rgb[1] = y - ((cb + cr + 2) >> 2); |
276 | 34.2k | rgb[2] = rgb[1] + cb; |
277 | 34.2k | rgb[0] = rgb[1] + cr; |
278 | 102k | FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)]; |
279 | 34.2k | } |
280 | 637 | } |
281 | 26 | maximum = curve[0xff]; |
282 | 26 | } |
283 | | |
284 | | void LibRaw::kodak_c603_load_raw() |
285 | 34 | { |
286 | 34 | if (!image) |
287 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
288 | 34 | int row, col, y, cb, cr, rgb[3], c; |
289 | | |
290 | 34 | std::vector<uchar> pixel(raw_width * 3); |
291 | 586 | for (row = 0; row < height; row++) |
292 | 552 | { |
293 | 552 | checkCancel(); |
294 | 552 | if (~row & 1) |
295 | 293 | if (fread(pixel.data(), raw_width, 3, ifp) < 3) |
296 | 34 | derror(); |
297 | 14.1k | for (col = 0; col < width; col++) |
298 | 13.6k | { |
299 | 13.6k | y = pixel[width * 2 * (row & 1) + col]; |
300 | 13.6k | cb = pixel[width + (col & -2)] - 128; |
301 | 13.6k | cr = pixel[width + (col & -2) + 1] - 128; |
302 | 13.6k | rgb[1] = y - ((cb + cr + 2) >> 2); |
303 | 13.6k | rgb[2] = rgb[1] + cb; |
304 | 13.6k | rgb[0] = rgb[1] + cr; |
305 | 40.9k | FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)]; |
306 | 13.6k | } |
307 | 552 | } |
308 | 34 | maximum = curve[0xff]; |
309 | 34 | } |
310 | | |
311 | | void LibRaw::kodak_262_load_raw() |
312 | 185 | { |
313 | 185 | static const uchar kodak_tree[2][26] = { |
314 | 185 | {0, 1, 5, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, |
315 | 185 | 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, |
316 | 185 | {0, 3, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, |
317 | 185 | 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}; |
318 | 185 | ushort *huff[2]; |
319 | 185 | int *strip, ns, c, row, col, chess, pi = 0, pi1, pi2, pred, val; |
320 | | |
321 | 370 | FORC(2) huff[c] = make_decoder(kodak_tree[c]); |
322 | 185 | ns = (raw_height + 63) >> 5; |
323 | 185 | std::vector<uchar> pixel(raw_width * 32 + ns * 4); |
324 | 185 | strip = (int *)(pixel.data() + raw_width * 32); |
325 | 185 | order = 0x4d4d; |
326 | 3.96k | FORC(ns) strip[c] = get4(); |
327 | 185 | try |
328 | 185 | { |
329 | 118k | for (row = 0; row < raw_height; row++) |
330 | 117k | { |
331 | 117k | checkCancel(); |
332 | 117k | if ((row & 31) == 0) |
333 | 3.75k | { |
334 | 3.75k | fseek(ifp, strip[row >> 5], SEEK_SET); |
335 | 3.75k | getbits(-1); |
336 | 3.75k | pi = 0; |
337 | 3.75k | } |
338 | 85.0M | for (col = 0; col < raw_width; col++) |
339 | 84.9M | { |
340 | 84.9M | chess = (row + col) & 1; |
341 | 84.9M | pi1 = chess ? pi - 2 : pi - raw_width - 1; |
342 | 84.9M | pi2 = chess ? pi - 2 * raw_width : pi - raw_width + 1; |
343 | 84.9M | if (col <= chess) |
344 | 176k | pi1 = -1; |
345 | 84.9M | if (pi1 < 0) |
346 | 1.52M | pi1 = pi2; |
347 | 84.9M | if (pi2 < 0) |
348 | 4.05M | pi2 = pi1; |
349 | 84.9M | if (pi1 < 0 && col > 1) |
350 | 1.34M | pi1 = pi2 = pi - 2; |
351 | 84.9M | pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1; |
352 | 84.9M | pixel[pi] = val = pred + ljpeg_diff(huff[chess]); |
353 | 84.9M | if (val >> 8) |
354 | 48.5k | derror(); |
355 | 84.9M | val = curve[pixel[pi++]]; |
356 | 84.9M | RAW(row, col) = val; |
357 | 84.9M | } |
358 | 117k | } |
359 | 185 | } |
360 | 185 | catch (...) |
361 | 185 | { |
362 | 8 | FORC(2) free(huff[c]); |
363 | 4 | throw; |
364 | 4 | } |
365 | 362 | FORC(2) free(huff[c]); |
366 | 181 | } |
367 | | |
368 | | int LibRaw::kodak_65000_decode(short *out, int bsize) |
369 | 25.4k | { |
370 | 25.4k | uchar c, blen[768]; |
371 | 25.4k | ushort raw[6]; |
372 | 25.4k | INT64 bitbuf = 0; |
373 | 25.4k | int bits = 0, i, j, len, diff; |
374 | 25.4k | INT64 save; |
375 | | |
376 | 25.4k | save = ftell(ifp); |
377 | 25.4k | bsize = (bsize + 3) & -4; |
378 | 39.9k | for (i = 0; i < bsize; i += 2) |
379 | 39.6k | { |
380 | 39.6k | c = fgetc(ifp); |
381 | 39.6k | if ((blen[i] = c & 15) > 12 || (blen[i + 1] = c >> 4) > 12) |
382 | 25.0k | { |
383 | 25.0k | fseek(ifp, save, SEEK_SET); |
384 | 583k | for (i = 0; i < bsize; i += 8) |
385 | 557k | { |
386 | 557k | read_shorts(raw, 6); |
387 | 557k | out[i] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12; |
388 | 557k | out[i + 1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12; |
389 | 3.90M | for (j = 0; j < 6; j++) |
390 | 3.34M | out[i + 2 + j] = raw[j] & 0xfff; |
391 | 557k | } |
392 | 25.0k | return 1; |
393 | 25.0k | } |
394 | 39.6k | } |
395 | 378 | if ((bsize & 7) == 4) |
396 | 125 | { |
397 | 125 | bitbuf = fgetc(ifp) << 8; |
398 | 125 | bitbuf += fgetc(ifp); |
399 | 125 | bits = 16; |
400 | 125 | } |
401 | 19.0k | for (i = 0; i < bsize; i++) |
402 | 18.6k | { |
403 | 18.6k | len = blen[i]; |
404 | 18.6k | if (bits < len) |
405 | 1.81k | { |
406 | 9.09k | for (j = 0; j < 32; j += 8) |
407 | 7.27k | bitbuf += (INT64)fgetc(ifp) << (bits + (j ^ 8)); |
408 | 1.81k | bits += 32; |
409 | 1.81k | } |
410 | 18.6k | diff = bitbuf & (0xffff >> (16 - len)); |
411 | 18.6k | bitbuf >>= len; |
412 | 18.6k | bits -= len; |
413 | 18.6k | if (len > 0 && (diff & (1 << (len - 1))) == 0) |
414 | 4.23k | diff -= (1 << len) - 1; |
415 | 18.6k | out[i] = diff; |
416 | 18.6k | } |
417 | 378 | return 0; |
418 | 25.4k | } |
419 | | |
420 | | void LibRaw::kodak_65000_load_raw() |
421 | 60 | { |
422 | 60 | short buf[272]; /* 264 looks enough */ |
423 | 60 | int row, col, len, pred[2], ret, i; |
424 | | |
425 | 6.45k | for (row = 0; row < height; row++) |
426 | 6.39k | { |
427 | 6.39k | checkCancel(); |
428 | 14.5k | for (col = 0; col < width; col += 256) |
429 | 8.18k | { |
430 | 8.18k | pred[0] = pred[1] = 0; |
431 | 8.18k | len = MIN(256, width - col); |
432 | 8.18k | ret = kodak_65000_decode(buf, len); |
433 | 695k | for (i = 0; i < len; i++) |
434 | 686k | { |
435 | 686k | int idx = ret ? buf[i] : (pred[i & 1] += buf[i]); |
436 | 686k | if (idx >= 0 && idx < 0xffff) |
437 | 683k | { |
438 | 683k | if ((RAW(row, col + i) = curve[idx]) >> 12) |
439 | 694 | derror(); |
440 | 683k | } |
441 | 3.83k | else |
442 | 3.83k | derror(); |
443 | 686k | } |
444 | 8.18k | } |
445 | 6.39k | } |
446 | 60 | } |
447 | | |
448 | | void LibRaw::kodak_ycbcr_load_raw() |
449 | 46 | { |
450 | 46 | if (!image) |
451 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
452 | 46 | short buf[384], *bp; |
453 | 46 | int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3]; |
454 | 46 | ushort *ip; |
455 | | |
456 | 46 | unsigned int bits = |
457 | 46 | (load_flags && load_flags > 9 && load_flags < 17) ? load_flags : 10; |
458 | 46 | const int pixels = int(width)*int(height); |
459 | 7.80k | for (row = 0; row < height; row += 2) |
460 | 7.76k | { |
461 | 7.76k | checkCancel(); |
462 | 18.2k | for (col = 0; col < width; col += 128) |
463 | 10.5k | { |
464 | 10.5k | len = MIN(128, width - col); |
465 | 10.5k | kodak_65000_decode(buf, len * 3); |
466 | 10.5k | y[0][1] = y[1][1] = cb = cr = 0; |
467 | 343k | for (bp = buf, i = 0; i < len; i += 2, bp += 2) |
468 | 333k | { |
469 | 333k | cb += bp[4]; |
470 | 333k | cr += bp[5]; |
471 | 333k | rgb[1] = -((cb + cr + 2) >> 2); |
472 | 333k | rgb[2] = rgb[1] + cb; |
473 | 333k | rgb[0] = rgb[1] + cr; |
474 | 1.00M | for (j = 0; j < 2; j++) |
475 | 2.00M | for (k = 0; k < 2; k++) |
476 | 1.33M | { |
477 | 1.33M | if ((y[j][k] = y[j][k ^ 1] + *bp++) >> bits) |
478 | 1.23M | derror(); |
479 | 1.33M | int indx = (row + j) * width + col + i + k; |
480 | 1.33M | if(indx>=0 && indx < pixels) |
481 | 1.33M | { |
482 | 1.33M | ip = image[indx]; |
483 | 4.00M | FORC3 ip[c] = curve[LIM(y[j][k] + rgb[c], 0, 0xfff)]; |
484 | 1.33M | } |
485 | 1.33M | } |
486 | 333k | } |
487 | 10.5k | } |
488 | 7.76k | } |
489 | 46 | } |
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 | 5.13k | for (row = 0; row < height; row++) |
500 | 5.07k | { |
501 | 5.07k | checkCancel(); |
502 | 11.8k | for (col = 0; col < width; col += 256) |
503 | 6.77k | { |
504 | 6.77k | len = MIN(256, width - col); |
505 | 6.77k | ret = kodak_65000_decode(buf, len * 3); |
506 | 6.77k | memset(rgb, 0, sizeof rgb); |
507 | 584k | for (bp = buf, i = 0; i < len; i++, ip += 4) |
508 | 577k | if (load_flags == 12) |
509 | 0 | FORC3 ip[c] = ret ? (*bp++) : (rgb[c] += *bp++); |
510 | 577k | else |
511 | 1.73M | FORC3 if ((ip[c] = ret ? (*bp++) : (rgb[c] += *bp++)) >> 12) derror(); |
512 | 6.77k | } |
513 | 5.07k | } |
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 | } |