/src/LibRaw/src/decoders/decoders_libraw.cpp
Line | Count | Source |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2022 LibRaw LLC (info@libraw.org) |
3 | | * |
4 | | * PhaseOne IIQ-Sv2 decoder is inspired by code provided by Daniel Vogelbacher <daniel@chaospixel.com> |
5 | | * |
6 | | |
7 | | LibRaw is free software; you can redistribute it and/or modify |
8 | | it under the terms of the one of two licenses as you choose: |
9 | | |
10 | | 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
11 | | (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
12 | | |
13 | | 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
14 | | (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
15 | | |
16 | | */ |
17 | | |
18 | | #include "../../internal/libraw_cxx_defs.h" |
19 | | #include <vector> |
20 | | #include <algorithm> // for std::sort |
21 | | |
22 | | void LibRaw::sony_arq_load_raw() |
23 | 0 | { |
24 | 0 | int row, col; |
25 | 0 | if (imgdata.idata.filters || imgdata.idata.colors < 3) |
26 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
27 | | |
28 | 0 | read_shorts(imgdata.rawdata.raw_image, |
29 | 0 | imgdata.sizes.raw_width * imgdata.sizes.raw_height * 4); |
30 | 0 | libraw_internal_data.internal_data.input->seek( |
31 | 0 | -2, SEEK_CUR); // avoid wrong eof error |
32 | |
|
33 | 0 | if(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_ARQ_SKIP_CHANNEL_SWAP) |
34 | 0 | return; |
35 | | |
36 | 0 | for (row = 0; row < imgdata.sizes.raw_height; row++) |
37 | 0 | { |
38 | 0 | unsigned short(*rowp)[4] = |
39 | 0 | (unsigned short(*)[4]) & |
40 | 0 | imgdata.rawdata.raw_image[row * imgdata.sizes.raw_width * 4]; |
41 | 0 | for (col = 0; col < imgdata.sizes.raw_width; col++) |
42 | 0 | { |
43 | 0 | unsigned short g2 = rowp[col][2]; |
44 | 0 | rowp[col][2] = rowp[col][3]; |
45 | 0 | rowp[col][3] = g2; |
46 | 0 | if (((unsigned)(row - imgdata.sizes.top_margin) < imgdata.sizes.height) && |
47 | 0 | ((unsigned)(col - imgdata.sizes.left_margin) < imgdata.sizes.width) && |
48 | 0 | (MAX(MAX(rowp[col][0], rowp[col][1]), |
49 | 0 | MAX(rowp[col][2], rowp[col][3])) > imgdata.color.maximum)) |
50 | 0 | derror(); |
51 | 0 | } |
52 | 0 | } |
53 | 0 | } |
54 | | |
55 | | void LibRaw::pentax_4shot_load_raw() |
56 | 0 | { |
57 | 0 | size_t alloc_sz = size_t(imgdata.sizes.raw_width) * (size_t(imgdata.sizes.raw_height) + 16) * 4 * sizeof(ushort); |
58 | 0 | if (INT64(alloc_sz) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
59 | 0 | throw LIBRAW_EXCEPTION_TOOBIG; |
60 | | |
61 | | #ifdef LIBRAW_CALLOC_RAWSTORE |
62 | | ushort *plane = (ushort *)calloc(size_t(imgdata.sizes.raw_width) * size_t(imgdata.sizes.raw_height), sizeof(ushort)); |
63 | | #else |
64 | 0 | ushort *plane = (ushort *)malloc(size_t(imgdata.sizes.raw_width) * |
65 | 0 | size_t(imgdata.sizes.raw_height) * sizeof(ushort)); |
66 | 0 | #endif |
67 | |
|
68 | 0 | if (!plane) |
69 | 0 | throw LIBRAW_EXCEPTION_ALLOC; |
70 | | |
71 | | #ifdef LIBRAW_CALLOC_RAWSTORE |
72 | | ushort(*result)[4] = (ushort(*)[4])calloc(alloc_sz,1); |
73 | | #else |
74 | 0 | ushort(*result)[4] = (ushort(*)[4])malloc(alloc_sz); |
75 | 0 | #endif |
76 | 0 | if(!result) |
77 | 0 | throw LIBRAW_EXCEPTION_ALLOC; |
78 | | |
79 | 0 | struct movement_t |
80 | 0 | { |
81 | 0 | int row, col; |
82 | 0 | } _move[4] = { |
83 | 0 | {1, 1}, |
84 | 0 | {0, 1}, |
85 | 0 | {0, 0}, |
86 | 0 | {1, 0}, |
87 | 0 | }; |
88 | |
|
89 | 0 | int tidx = 0; |
90 | 0 | for (int i = 0; i < 4; i++) |
91 | 0 | { |
92 | 0 | int move_row, move_col; |
93 | 0 | if (imgdata.rawparams.p4shot_order[i] >= '0' && |
94 | 0 | imgdata.rawparams.p4shot_order[i] <= '3') |
95 | 0 | { |
96 | 0 | move_row = ((imgdata.rawparams.p4shot_order[i] - '0') & 2) ? 1 : 0; |
97 | 0 | move_col = ((imgdata.rawparams.p4shot_order[i] - '0') & 1) ? 1 : 0; |
98 | 0 | } |
99 | 0 | else |
100 | 0 | { |
101 | 0 | move_row = _move[i].row; |
102 | 0 | move_col = _move[i].col; |
103 | 0 | } |
104 | 0 | for (; tidx < 16; tidx++) |
105 | 0 | if (tiff_ifd[tidx].t_width == imgdata.sizes.raw_width && |
106 | 0 | tiff_ifd[tidx].t_height == imgdata.sizes.raw_height && |
107 | 0 | tiff_ifd[tidx].bps > 8 && tiff_ifd[tidx].samples == 1) |
108 | 0 | break; |
109 | 0 | if (tidx >= 16) |
110 | 0 | break; |
111 | 0 | imgdata.rawdata.raw_image = plane; |
112 | 0 | ID.input->seek(tiff_ifd[tidx].offset, SEEK_SET); |
113 | 0 | imgdata.idata.filters = 0xb4b4b4b4; |
114 | 0 | libraw_internal_data.unpacker_data.data_offset = tiff_ifd[tidx].offset; |
115 | 0 | (this->*pentax_component_load_raw)(); |
116 | 0 | for (int row = 0; row < imgdata.sizes.raw_height - move_row; row++) |
117 | 0 | { |
118 | 0 | int colors[2]; |
119 | 0 | for (int c = 0; c < 2; c++) |
120 | 0 | colors[c] = COLOR(row, c); |
121 | 0 | ushort *srcrow = &plane[imgdata.sizes.raw_width * row]; |
122 | 0 | ushort(*dstrow)[4] = |
123 | 0 | &result[(imgdata.sizes.raw_width) * (row + move_row) + move_col]; |
124 | 0 | for (int col = 0; col < imgdata.sizes.raw_width - move_col; col++) |
125 | 0 | dstrow[col][colors[col % 2]] = srcrow[col]; |
126 | 0 | } |
127 | 0 | tidx++; |
128 | 0 | } |
129 | |
|
130 | 0 | if (imgdata.color.cblack[4] == 2 && imgdata.color.cblack[5] == 2) |
131 | 0 | for (int c = 0; c < 4; c++) |
132 | 0 | imgdata.color.cblack[FC(c / 2, c % 2)] += |
133 | 0 | imgdata.color.cblack[6 + |
134 | 0 | c / 2 % imgdata.color.cblack[4] * |
135 | 0 | imgdata.color.cblack[5] + |
136 | 0 | c % 2 % imgdata.color.cblack[5]]; |
137 | 0 | imgdata.color.cblack[4] = imgdata.color.cblack[5] = 0; |
138 | | |
139 | | // assign things back: |
140 | 0 | imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 8; |
141 | 0 | imgdata.idata.filters = 0; |
142 | 0 | imgdata.rawdata.raw_alloc = imgdata.rawdata.color4_image = result; |
143 | 0 | free(plane); |
144 | 0 | imgdata.rawdata.raw_image = 0; |
145 | 0 | } |
146 | | |
147 | | void LibRaw::hasselblad_full_load_raw() |
148 | 0 | { |
149 | 0 | int row, col; |
150 | |
|
151 | 0 | for (row = 0; row < S.height; row++) |
152 | 0 | for (col = 0; col < S.width; col++) |
153 | 0 | { |
154 | 0 | read_shorts(&imgdata.image[row * S.width + col][2], 1); // B |
155 | 0 | read_shorts(&imgdata.image[row * S.width + col][1], 1); // G |
156 | 0 | read_shorts(&imgdata.image[row * S.width + col][0], 1); // R |
157 | 0 | } |
158 | 0 | } |
159 | | |
160 | | static inline void unpack7bytesto4x16(unsigned char *src, unsigned short *dest) |
161 | 0 | { |
162 | 0 | dest[0] = (src[0] << 6) | (src[1] >> 2); |
163 | 0 | dest[1] = ((src[1] & 0x3) << 12) | (src[2] << 4) | (src[3] >> 4); |
164 | 0 | dest[2] = (src[3] & 0xf) << 10 | (src[4] << 2) | (src[5] >> 6); |
165 | 0 | dest[3] = ((src[5] & 0x3f) << 8) | src[6]; |
166 | 0 | } |
167 | | |
168 | | static inline void unpack28bytesto16x16ns(unsigned char *src, |
169 | | unsigned short *dest) |
170 | 0 | { |
171 | 0 | dest[0] = (src[3] << 6) | (src[2] >> 2); |
172 | 0 | dest[1] = ((src[2] & 0x3) << 12) | (src[1] << 4) | (src[0] >> 4); |
173 | 0 | dest[2] = (src[0] & 0xf) << 10 | (src[7] << 2) | (src[6] >> 6); |
174 | 0 | dest[3] = ((src[6] & 0x3f) << 8) | src[5]; |
175 | 0 | dest[4] = (src[4] << 6) | (src[11] >> 2); |
176 | 0 | dest[5] = ((src[11] & 0x3) << 12) | (src[10] << 4) | (src[9] >> 4); |
177 | 0 | dest[6] = (src[9] & 0xf) << 10 | (src[8] << 2) | (src[15] >> 6); |
178 | 0 | dest[7] = ((src[15] & 0x3f) << 8) | src[14]; |
179 | 0 | dest[8] = (src[13] << 6) | (src[12] >> 2); |
180 | 0 | dest[9] = ((src[12] & 0x3) << 12) | (src[19] << 4) | (src[18] >> 4); |
181 | 0 | dest[10] = (src[18] & 0xf) << 10 | (src[17] << 2) | (src[16] >> 6); |
182 | 0 | dest[11] = ((src[16] & 0x3f) << 8) | src[23]; |
183 | 0 | dest[12] = (src[22] << 6) | (src[21] >> 2); |
184 | 0 | dest[13] = ((src[21] & 0x3) << 12) | (src[20] << 4) | (src[27] >> 4); |
185 | 0 | dest[14] = (src[27] & 0xf) << 10 | (src[26] << 2) | (src[25] >> 6); |
186 | 0 | dest[15] = ((src[25] & 0x3f) << 8) | src[24]; |
187 | 0 | } |
188 | | |
189 | | #define swab32(x) \ |
190 | 0 | ((unsigned int)((((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \ |
191 | 0 | (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \ |
192 | 0 | (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \ |
193 | 0 | (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24))) |
194 | | |
195 | | static inline void swab32arr(unsigned *arr, unsigned len) |
196 | 0 | { |
197 | 0 | for (unsigned i = 0; i < len; i++) |
198 | 0 | arr[i] = swab32(arr[i]); |
199 | 0 | } |
200 | | #undef swab32 |
201 | | |
202 | | static inline void unpack7bytesto4x16_nikon(unsigned char *src, |
203 | | unsigned short *dest) |
204 | 0 | { |
205 | 0 | dest[3] = (src[6] << 6) | (src[5] >> 2); |
206 | 0 | dest[2] = ((src[5] & 0x3) << 12) | (src[4] << 4) | (src[3] >> 4); |
207 | 0 | dest[1] = (src[3] & 0xf) << 10 | (src[2] << 2) | (src[1] >> 6); |
208 | 0 | dest[0] = ((src[1] & 0x3f) << 8) | src[0]; |
209 | 0 | } |
210 | | |
211 | | static inline void unpack21bytesto12x16_nikon(unsigned char *src, unsigned short (*dest)[4]) |
212 | 0 | { |
213 | | // bytes 0-6 |
214 | 0 | dest[0][0] = ((src[1] & 0x3f) << 8) | src[0]; |
215 | 0 | dest[0][1] = (src[3] & 0xf) << 10 | (src[2] << 2) | (src[1] >> 6); |
216 | 0 | dest[0][2] = ((src[5] & 0x3) << 12) | (src[4] << 4) | (src[3] >> 4); |
217 | 0 | dest[1][0] = (src[6] << 6) | (src[5] >> 2); |
218 | | // bytes 7-13 |
219 | 0 | dest[1][1] = ((src[8] & 0x3f) << 8) | src[7]; |
220 | 0 | dest[1][2] = (src[10] & 0xf) << 10 | (src[9] << 2) | (src[8] >> 6); |
221 | 0 | dest[2][0] = ((src[12] & 0x3) << 12) | (src[11] << 4) | (src[10] >> 4); |
222 | 0 | dest[2][1] = (src[13] << 6) | (src[12] >> 2); |
223 | | // bytes 14-20 |
224 | 0 | dest[2][2] = ((src[15] & 0x3f) << 8) | src[14]; |
225 | 0 | dest[3][0] = (src[17] & 0xf) << 10 | (src[16] << 2) | (src[15] >> 6); |
226 | 0 | dest[3][1] = ((src[19] & 0x3) << 12) | (src[18] << 4) | (src[17] >> 4); |
227 | 0 | dest[3][2] = (src[20] << 6) | (src[19] >> 2); |
228 | 0 | } |
229 | | |
230 | | |
231 | | void LibRaw::nikon_14bit_load_raw() |
232 | 0 | { |
233 | 0 | int cps = (imgdata.idata.filters == 0 && imgdata.idata.colors == 3) ? 3 : 1; |
234 | |
|
235 | 0 | if (cps == 1 && !imgdata.rawdata.raw_image) |
236 | 0 | throw LIBRAW_EXCEPTION_DECODE_RAW; |
237 | 0 | if(cps == 3 && !imgdata.image) |
238 | 0 | throw LIBRAW_EXCEPTION_DECODE_RAW; |
239 | | |
240 | 0 | const unsigned linelen = |
241 | 0 | (unsigned)(ceilf((float)(S.raw_width * cps * 7 / 4) / 16.0f)) * |
242 | 0 | 16; // 14512; // S.raw_width * 7 / 4; |
243 | 0 | const unsigned pitch = S.raw_pitch ? S.raw_pitch /( (cps>=3)? 8 : 2) : S.raw_width; |
244 | 0 | unsigned char *buf = (unsigned char *)calloc(linelen,1); |
245 | 0 | for (int row = 0; row < S.raw_height; row++) |
246 | 0 | { |
247 | 0 | unsigned bytesread = |
248 | 0 | libraw_internal_data.internal_data.input->read(buf, 1, linelen); |
249 | 0 | if (cps == 1) |
250 | 0 | { |
251 | 0 | unsigned short *dest = &imgdata.rawdata.raw_image[pitch * row]; |
252 | | // swab32arr((unsigned *)buf, bytesread / 4); |
253 | 0 | for (unsigned int sp = 0, dp = 0; |
254 | 0 | dp < pitch - 3 && sp < linelen - 6 && sp < bytesread - 6; |
255 | 0 | sp += 7, dp += 4) |
256 | 0 | unpack7bytesto4x16_nikon(buf + sp, dest + dp); |
257 | 0 | } |
258 | 0 | else if (cps == 3) |
259 | 0 | { |
260 | 0 | unsigned short (*dest)[4] = &imgdata.image[pitch * row]; |
261 | | // swab32arr((unsigned *)buf, bytesread / 4); |
262 | 0 | for (unsigned int sp = 0, dp = 0; |
263 | 0 | dp < pitch - 3 && sp < linelen - 20 && sp < bytesread - 20; |
264 | 0 | sp += 21, dp += 4) |
265 | 0 | unpack21bytesto12x16_nikon(buf + sp, dest + dp); |
266 | 0 | } |
267 | 0 | } |
268 | 0 | free(buf); |
269 | 0 | } |
270 | | |
271 | | void LibRaw::fuji_14bit_load_raw() |
272 | 0 | { |
273 | 0 | const unsigned linelen = S.raw_width * 7 / 4; |
274 | 0 | const unsigned pitch = S.raw_pitch ? S.raw_pitch / 2 : S.raw_width; |
275 | 0 | unsigned char *buf = (unsigned char *)calloc(linelen,1); |
276 | |
|
277 | 0 | for (int row = 0; row < S.raw_height; row++) |
278 | 0 | { |
279 | 0 | unsigned bytesread = |
280 | 0 | libraw_internal_data.internal_data.input->read(buf, 1, linelen); |
281 | 0 | unsigned short *dest = &imgdata.rawdata.raw_image[pitch * row]; |
282 | 0 | if (bytesread % 28) |
283 | 0 | { |
284 | 0 | swab32arr((unsigned *)buf, bytesread / 4); |
285 | 0 | for (unsigned int sp = 0, dp = 0; |
286 | 0 | dp < pitch - 3 && sp < linelen - 6 && sp < bytesread - 6; |
287 | 0 | sp += 7, dp += 4) |
288 | 0 | unpack7bytesto4x16(buf + sp, dest + dp); |
289 | 0 | } |
290 | 0 | else |
291 | 0 | for (unsigned int sp = 0, dp = 0; |
292 | 0 | dp < pitch - 15 && sp < linelen - 27 && sp < bytesread - 27; |
293 | 0 | sp += 28, dp += 16) |
294 | 0 | unpack28bytesto16x16ns(buf + sp, dest + dp); |
295 | 0 | } |
296 | 0 | free(buf); |
297 | 0 | } |
298 | | void LibRaw::nikon_load_padded_packed_raw() // 12 bit per pixel, padded to 16 |
299 | | // bytes |
300 | 1 | { |
301 | 1 | unsigned bytesperrow = (((unsigned(S.raw_width) * 3u / 2u) + 15u) / 16u) * 16u; // bytes per row |
302 | | |
303 | | // libraw_internal_data.unpacker_data.load_flags -> row byte count |
304 | 1 | if (bytesperrow < 2000 || bytesperrow > 64000) |
305 | 1 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
306 | | |
307 | 0 | unsigned char *buf = |
308 | 0 | (unsigned char *)calloc(bytesperrow,1); |
309 | 0 | for (int row = 0; row < S.raw_height; row++) |
310 | 0 | { |
311 | 0 | checkCancel(); |
312 | 0 | int readed = libraw_internal_data.internal_data.input->read( |
313 | 0 | buf, 1, bytesperrow); |
314 | |
|
315 | 0 | if (readed < (int)bytesperrow) |
316 | 0 | derror(); |
317 | |
|
318 | 0 | for (int icol = 0; icol < S.raw_width / 2; icol++) |
319 | 0 | { |
320 | 0 | imgdata.rawdata.raw_image[(row)*S.raw_width + (icol * 2)] = |
321 | 0 | ((buf[icol * 3 + 1] & 0xf) << 8) | buf[icol * 3]; |
322 | 0 | imgdata.rawdata.raw_image[(row)*S.raw_width + (icol * 2 + 1)] = |
323 | 0 | buf[icol * 3 + 2] << 4 | ((buf[icol * 3 + 1] & 0xf0) >> 4); |
324 | 0 | } |
325 | 0 | } |
326 | 0 | free(buf); |
327 | 0 | } |
328 | | |
329 | | void LibRaw::nikon_load_striped_packed_raw() |
330 | 0 | { |
331 | 0 | int vbits = 0, bwide, rbits, bite, row, col, i; |
332 | |
|
333 | 0 | UINT64 bitbuf = 0; |
334 | 0 | unsigned load_flags = 24; // libraw_internal_data.unpacker_data.load_flags; |
335 | 0 | unsigned tiff_bps = libraw_internal_data.unpacker_data.tiff_bps; |
336 | |
|
337 | 0 | struct tiff_ifd_t *ifd = &tiff_ifd[0]; |
338 | 0 | while (ifd < &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds] && |
339 | 0 | ifd->offset != libraw_internal_data.unpacker_data.data_offset) |
340 | 0 | ++ifd; |
341 | 0 | if (ifd == &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds]) |
342 | 0 | throw LIBRAW_EXCEPTION_DECODE_RAW; |
343 | | |
344 | 0 | if (!ifd->rows_per_strip || !ifd->strip_offsets_count) |
345 | 0 | return; // not unpacked |
346 | 0 | int stripcnt = 0; |
347 | |
|
348 | 0 | bwide = S.raw_width * tiff_bps / 8; |
349 | 0 | bwide += bwide & load_flags >> 7; |
350 | 0 | rbits = bwide * 8 - S.raw_width * tiff_bps; |
351 | 0 | if (load_flags & 1) |
352 | 0 | bwide = bwide * 16 / 15; |
353 | 0 | bite = 8 + (load_flags & 24); |
354 | 0 | for (row = 0; row < S.raw_height; row++) |
355 | 0 | { |
356 | 0 | checkCancel(); |
357 | 0 | if (!(row % ifd->rows_per_strip)) |
358 | 0 | { |
359 | 0 | if (stripcnt >= ifd->strip_offsets_count) |
360 | 0 | return; // run out of data |
361 | 0 | libraw_internal_data.internal_data.input->seek( |
362 | 0 | ifd->strip_offsets[stripcnt], SEEK_SET); |
363 | 0 | stripcnt++; |
364 | 0 | } |
365 | 0 | for (col = 0; col < S.raw_width; col++) |
366 | 0 | { |
367 | 0 | for (vbits -= tiff_bps; vbits < 0; vbits += bite) |
368 | 0 | { |
369 | 0 | bitbuf <<= bite; |
370 | 0 | for (i = 0; i < bite; i += 8) |
371 | 0 | bitbuf |= |
372 | 0 | (unsigned)(libraw_internal_data.internal_data.input->get_char() |
373 | 0 | << i); |
374 | 0 | } |
375 | 0 | imgdata.rawdata.raw_image[(row)*S.raw_width + (col)] = |
376 | 0 | ushort((bitbuf << (64 - tiff_bps - vbits) >> (64 - tiff_bps)) & 0xffff); |
377 | 0 | } |
378 | 0 | vbits -= rbits; |
379 | 0 | } |
380 | 0 | } |
381 | | |
382 | | struct pana_cs6_page_decoder |
383 | | { |
384 | | unsigned int pixelbuffer[18], lastoffset, maxoffset; |
385 | | unsigned char current, *buffer; |
386 | | pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize) |
387 | 0 | : lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer) |
388 | 0 | { |
389 | 0 | } |
390 | | void read_page(); // will throw IO error if not enough space in buffer |
391 | | void read_page12(); // 12-bit variant |
392 | 0 | unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; } |
393 | 0 | unsigned int nextpixel12() { return current < 18 ? pixelbuffer[current++] : 0; } |
394 | | }; |
395 | | |
396 | | void pana_cs6_page_decoder::read_page() |
397 | 0 | { |
398 | 0 | if (!buffer || (maxoffset - lastoffset < 16)) |
399 | 0 | throw LIBRAW_EXCEPTION_IO_EOF; |
400 | 0 | #define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i]) |
401 | 0 | pixelbuffer[0] = (wbuffer(0) << 6) | (wbuffer(1) >> 2); // 14 bit |
402 | 0 | pixelbuffer[1] = (((wbuffer(1) & 0x3) << 12) | (wbuffer(2) << 4) | (wbuffer(3) >> 4)) & 0x3fff; // 14 bit |
403 | 0 | pixelbuffer[2] = (wbuffer(3) >> 2) & 0x3; // 2 |
404 | 0 | pixelbuffer[3] = ((wbuffer(3) & 0x3) << 8) | wbuffer(4); // 10 |
405 | 0 | pixelbuffer[4] = (wbuffer(5) << 2) | (wbuffer(6) >> 6); // 10 |
406 | 0 | pixelbuffer[5] = ((wbuffer(6) & 0x3f) << 4) | (wbuffer(7) >> 4); // 10 |
407 | 0 | pixelbuffer[6] = (wbuffer(7) >> 2) & 0x3; |
408 | 0 | pixelbuffer[7] = ((wbuffer(7) & 0x3) << 8) | wbuffer(8); |
409 | 0 | pixelbuffer[8] = ((wbuffer(9) << 2) & 0x3fc) | (wbuffer(10) >> 6); |
410 | 0 | pixelbuffer[9] = ((wbuffer(10) << 4) | (wbuffer(11) >> 4)) & 0x3ff; |
411 | 0 | pixelbuffer[10] = (wbuffer(11) >> 2) & 0x3; |
412 | 0 | pixelbuffer[11] = ((wbuffer(11) & 0x3) << 8) | wbuffer(12); |
413 | 0 | pixelbuffer[12] = (((wbuffer(13) << 2) & 0x3fc) | wbuffer(14) >> 6) & 0x3ff; |
414 | 0 | pixelbuffer[13] = ((wbuffer(14) << 4) | (wbuffer(15) >> 4)) & 0x3ff; |
415 | 0 | #undef wbuffer |
416 | 0 | current = 0; |
417 | 0 | lastoffset += 16; |
418 | 0 | } |
419 | | |
420 | | void pana_cs6_page_decoder::read_page12() |
421 | 0 | { |
422 | 0 | if (!buffer || (maxoffset - lastoffset < 16)) |
423 | 0 | throw LIBRAW_EXCEPTION_IO_EOF; |
424 | 0 | #define wb(i) ((unsigned short)buffer[lastoffset + 15 - i]) |
425 | 0 | pixelbuffer[0] = (wb(0) << 4) | (wb(1) >> 4); // 12 bit: 8/0 + 4 upper bits of /1 |
426 | 0 | pixelbuffer[1] = (((wb(1) & 0xf) << 8) | (wb(2))) & 0xfff; // 12 bit: 4l/1 + 8/2 |
427 | | |
428 | 0 | pixelbuffer[2] = (wb(3) >> 6) & 0x3; // 2; 2u/3, 6 low bits remains in wb(3) |
429 | 0 | pixelbuffer[3] = ((wb(3) & 0x3f) << 2) | (wb(4) >> 6); // 8; 6l/3 + 2u/4; 6 low bits remains in wb(4) |
430 | 0 | pixelbuffer[4] = ((wb(4) & 0x3f) << 2) | (wb(5) >> 6); // 8: 6l/4 + 2u/5; 6 low bits remains in wb(5) |
431 | 0 | pixelbuffer[5] = ((wb(5) & 0x3f) << 2) | (wb(6) >> 6); // 8: 6l/5 + 2u/6, 6 low bits remains in wb(6) |
432 | |
|
433 | 0 | pixelbuffer[6] = (wb(6) >> 4) & 0x3; // 2, 4 low bits remains in wb(6) |
434 | 0 | pixelbuffer[7] = ((wb(6) & 0xf) << 4) | (wb(7) >> 4); // 8: 4 low bits from wb(6), 4 upper bits from wb(7) |
435 | 0 | pixelbuffer[8] = ((wb(7) & 0xf) << 4) | (wb(8) >> 4); // 8: 4 low bits from wb7, 4 upper bits from wb8 |
436 | 0 | pixelbuffer[9] = ((wb(8) & 0xf) << 4) | (wb(9) >> 4); // 8: 4 low bits from wb8, 4 upper bits from wb9 |
437 | |
|
438 | 0 | pixelbuffer[10] = (wb(9) >> 2) & 0x3; // 2: bits 2-3 from wb9, two low bits remain in wb9 |
439 | 0 | pixelbuffer[11] = ((wb(9) & 0x3) << 6) | (wb(10) >> 2); // 8: 2 bits from wb9, 6 bits from wb10 |
440 | 0 | pixelbuffer[12] = ((wb(10) & 0x3) << 6) | (wb(11) >> 2); // 8: 2 bits from wb10, 6 bits from wb11 |
441 | 0 | pixelbuffer[13] = ((wb(11) & 0x3) << 6) | (wb(12) >> 2); // 8: 2 bits from wb11, 6 bits from wb12 |
442 | |
|
443 | 0 | pixelbuffer[14] = wb(12) & 0x3; // 2: low bits from wb12 |
444 | 0 | pixelbuffer[15] = wb(13); |
445 | 0 | pixelbuffer[16] = wb(14); |
446 | 0 | pixelbuffer[17] = wb(15); |
447 | 0 | #undef wb |
448 | 0 | current = 0; |
449 | 0 | lastoffset += 16; |
450 | 0 | } |
451 | | |
452 | | void LibRaw::panasonicC6_load_raw() |
453 | 0 | { |
454 | 0 | const int rowstep = 16; |
455 | 0 | const bool _12bit = libraw_internal_data.unpacker_data.pana_bpp == 12; |
456 | 0 | const int pixperblock = _12bit ? 14 : 11; |
457 | 0 | const int blocksperrow = imgdata.sizes.raw_width / pixperblock; |
458 | 0 | const int rowbytes = blocksperrow * 16; |
459 | 0 | const unsigned pixelbase0 = _12bit ? 0x80 : 0x200; |
460 | 0 | const unsigned pixelbase_compare = _12bit ? 0x800 : 0x2000; |
461 | 0 | const unsigned spix_compare = _12bit ? 0x3fff : 0xffff; |
462 | 0 | const unsigned pixel_mask = _12bit ? 0xfff : 0x3fff; |
463 | 0 | std::vector<unsigned char> iobuf; |
464 | 0 | try |
465 | 0 | { |
466 | 0 | iobuf.resize(rowbytes * rowstep); |
467 | 0 | } |
468 | 0 | catch (...) |
469 | 0 | { |
470 | 0 | throw LIBRAW_EXCEPTION_ALLOC; |
471 | 0 | } |
472 | | |
473 | 0 | for (int row = 0; row < imgdata.sizes.raw_height - rowstep + 1; |
474 | 0 | row += rowstep) |
475 | 0 | { |
476 | 0 | int rowstoread = MIN(rowstep, imgdata.sizes.raw_height - row); |
477 | 0 | if (libraw_internal_data.internal_data.input->read( |
478 | 0 | iobuf.data(), rowbytes, rowstoread) != rowstoread) |
479 | 0 | throw LIBRAW_EXCEPTION_IO_EOF; |
480 | 0 | pana_cs6_page_decoder page(iobuf.data(), rowbytes * rowstoread); |
481 | 0 | for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0) |
482 | 0 | { |
483 | 0 | unsigned short *rowptr = |
484 | 0 | &imgdata.rawdata |
485 | 0 | .raw_image[(row + crow) * imgdata.sizes.raw_pitch / 2]; |
486 | 0 | for (int rblock = 0; rblock < blocksperrow; rblock++) |
487 | 0 | { |
488 | 0 | if (_12bit) |
489 | 0 | page.read_page12(); |
490 | 0 | else |
491 | 0 | page.read_page(); |
492 | 0 | unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0}; |
493 | 0 | unsigned pmul = 0, pixel_base = 0; |
494 | 0 | for (int pix = 0; pix < pixperblock; pix++) |
495 | 0 | { |
496 | 0 | if (pix % 3 == 2) |
497 | 0 | { |
498 | 0 | unsigned base = _12bit ? page.nextpixel12(): page.nextpixel(); |
499 | 0 | if (base > 3) |
500 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; // not possible b/c of 2-bit |
501 | | // field, but.... |
502 | 0 | if (base == 3) |
503 | 0 | base = 4; |
504 | 0 | pixel_base = pixelbase0 << base; |
505 | 0 | pmul = 1 << base; |
506 | 0 | } |
507 | 0 | unsigned epixel = _12bit ? page.nextpixel12() : page.nextpixel(); |
508 | 0 | if (oddeven[pix % 2]) |
509 | 0 | { |
510 | 0 | epixel *= pmul; |
511 | 0 | if (pixel_base < pixelbase_compare && nonzero[pix % 2] > pixel_base) |
512 | 0 | epixel += nonzero[pix % 2] - pixel_base; |
513 | 0 | nonzero[pix % 2] = epixel; |
514 | 0 | } |
515 | 0 | else |
516 | 0 | { |
517 | 0 | oddeven[pix % 2] = epixel; |
518 | 0 | if (epixel) |
519 | 0 | nonzero[pix % 2] = epixel; |
520 | 0 | else |
521 | 0 | epixel = nonzero[pix % 2]; |
522 | 0 | } |
523 | 0 | unsigned spix = epixel - 0xf; |
524 | 0 | if (spix <= spix_compare) |
525 | 0 | rowptr[col++] = spix & spix_compare; |
526 | 0 | else |
527 | 0 | { |
528 | 0 | epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f); |
529 | 0 | rowptr[col++] = epixel & pixel_mask; |
530 | 0 | } |
531 | 0 | } |
532 | 0 | } |
533 | 0 | } |
534 | 0 | } |
535 | 0 | } |
536 | | |
537 | | |
538 | | void LibRaw::panasonicC7_load_raw() |
539 | 0 | { |
540 | 0 | const int rowstep = 16; |
541 | 0 | int pixperblock = libraw_internal_data.unpacker_data.pana_bpp == 14 ? 9 : 10; |
542 | 0 | int rowbytes = imgdata.sizes.raw_width / pixperblock * 16; |
543 | 0 | unsigned char *iobuf = (unsigned char *)calloc(rowbytes * rowstep,1); |
544 | 0 | for (int row = 0; row < imgdata.sizes.raw_height - rowstep + 1; |
545 | 0 | row += rowstep) |
546 | 0 | { |
547 | 0 | int rowstoread = MIN(rowstep, imgdata.sizes.raw_height - row); |
548 | 0 | if (libraw_internal_data.internal_data.input->read( |
549 | 0 | iobuf, rowbytes, rowstoread) != rowstoread) |
550 | 0 | throw LIBRAW_EXCEPTION_IO_EOF; |
551 | 0 | unsigned char *bytes = iobuf; |
552 | 0 | for (int crow = 0; crow < rowstoread; crow++) |
553 | 0 | { |
554 | 0 | unsigned short *rowptr = |
555 | 0 | &imgdata.rawdata |
556 | 0 | .raw_image[(row + crow) * imgdata.sizes.raw_pitch / 2]; |
557 | 0 | for (int col = 0; col < imgdata.sizes.raw_width - pixperblock + 1; |
558 | 0 | col += pixperblock, bytes += 16) |
559 | 0 | { |
560 | 0 | if (libraw_internal_data.unpacker_data.pana_bpp == 14) |
561 | 0 | { |
562 | 0 | rowptr[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); |
563 | 0 | rowptr[col + 1] = |
564 | 0 | (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); |
565 | 0 | rowptr[col + 2] = |
566 | 0 | (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); |
567 | 0 | rowptr[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); |
568 | 0 | rowptr[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); |
569 | 0 | rowptr[col + 5] = |
570 | 0 | (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); |
571 | 0 | rowptr[col + 6] = |
572 | 0 | (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); |
573 | 0 | rowptr[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); |
574 | 0 | rowptr[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); |
575 | 0 | } |
576 | 0 | else if (libraw_internal_data.unpacker_data.pana_bpp == |
577 | 0 | 12) // have not seen in the wild yet |
578 | 0 | { |
579 | 0 | rowptr[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; |
580 | 0 | rowptr[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); |
581 | 0 | rowptr[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; |
582 | 0 | rowptr[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); |
583 | 0 | rowptr[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; |
584 | 0 | rowptr[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); |
585 | 0 | rowptr[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; |
586 | 0 | rowptr[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); |
587 | 0 | rowptr[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; |
588 | 0 | rowptr[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); |
589 | 0 | } |
590 | 0 | } |
591 | 0 | } |
592 | 0 | } |
593 | 0 | free(iobuf); |
594 | 0 | } |
595 | | |
596 | | void LibRaw::unpacked_load_raw_fuji_f700s20() |
597 | 22 | { |
598 | 22 | int base_offset = 0; |
599 | 22 | int row_size = imgdata.sizes.raw_width * 2; // in bytes |
600 | 22 | if (imgdata.idata.raw_count == 2 && imgdata.rawparams.shot_select) |
601 | 0 | { |
602 | 0 | libraw_internal_data.internal_data.input->seek(-row_size, SEEK_CUR); |
603 | 0 | base_offset = row_size; // in bytes |
604 | 0 | } |
605 | 22 | unsigned char *buffer = (unsigned char *)calloc(row_size,2); |
606 | 488 | for (int row = 0; row < imgdata.sizes.raw_height; row++) |
607 | 466 | { |
608 | 466 | read_shorts((ushort *)buffer, imgdata.sizes.raw_width * 2); |
609 | 466 | memmove(&imgdata.rawdata.raw_image[row * imgdata.sizes.raw_pitch / 2], |
610 | 466 | buffer + base_offset, row_size); |
611 | 466 | } |
612 | 22 | free(buffer); |
613 | 22 | } |
614 | | |
615 | | void LibRaw::nikon_load_sraw() |
616 | 76 | { |
617 | | // We're already seeked to data! |
618 | 76 | unsigned char *rd = |
619 | 76 | (unsigned char *)calloc(3 * (imgdata.sizes.raw_width + 2),1); |
620 | 76 | if (!rd) |
621 | 0 | throw LIBRAW_EXCEPTION_ALLOC; |
622 | 76 | try |
623 | 76 | { |
624 | 76 | int row, col; |
625 | 11.5k | for (row = 0; row < imgdata.sizes.raw_height; row++) |
626 | 11.4k | { |
627 | 11.4k | checkCancel(); |
628 | 11.4k | libraw_internal_data.internal_data.input->read(rd, 3, |
629 | 11.4k | imgdata.sizes.raw_width); |
630 | 1.01M | for (col = 0; col < imgdata.sizes.raw_width - 1; col += 2) |
631 | 1.00M | { |
632 | 1.00M | int bi = col * 3; |
633 | 1.00M | ushort bits1 = (rd[bi + 1] & 0xf) << 8 | rd[bi]; // 3,0,1 |
634 | 1.00M | ushort bits2 = rd[bi + 2] << 4 | ((rd[bi + 1] >> 4) & 0xf); // 452 |
635 | 1.00M | ushort bits3 = ((rd[bi + 4] & 0xf) << 8) | rd[bi + 3]; // 967 |
636 | 1.00M | ushort bits4 = rd[bi + 5] << 4 | ((rd[bi + 4] >> 4) & 0xf); // ab8 |
637 | 1.00M | imgdata.image[row * imgdata.sizes.raw_width + col][0] = bits1; |
638 | 1.00M | imgdata.image[row * imgdata.sizes.raw_width + col][1] = bits3; |
639 | 1.00M | imgdata.image[row * imgdata.sizes.raw_width + col][2] = bits4; |
640 | 1.00M | imgdata.image[row * imgdata.sizes.raw_width + col + 1][0] = bits2; |
641 | 1.00M | imgdata.image[row * imgdata.sizes.raw_width + col + 1][1] = 2048; |
642 | 1.00M | imgdata.image[row * imgdata.sizes.raw_width + col + 1][2] = 2048; |
643 | 1.00M | } |
644 | 11.4k | } |
645 | 76 | } |
646 | 76 | catch (...) |
647 | 76 | { |
648 | 0 | free(rd); |
649 | 0 | throw; |
650 | 0 | } |
651 | 76 | free(rd); |
652 | 76 | C.maximum = 0xfff; // 12 bit? |
653 | 76 | if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE) |
654 | 0 | { |
655 | 0 | return; // no CbCr interpolation |
656 | 0 | } |
657 | | // Interpolate CC channels |
658 | 76 | int row, col; |
659 | 11.5k | for (row = 0; row < imgdata.sizes.raw_height; row++) |
660 | 11.4k | { |
661 | 11.4k | checkCancel(); // will throw out |
662 | 1.01M | for (col = 0; col < imgdata.sizes.raw_width; col += 2) |
663 | 1.00M | { |
664 | 1.00M | int col2 = col < imgdata.sizes.raw_width - 2 ? col + 2 : col; |
665 | 1.00M | imgdata.image[row * imgdata.sizes.raw_width + col + 1][1] = |
666 | 1.00M | (unsigned short)(int(imgdata.image[row * imgdata.sizes.raw_width + |
667 | 1.00M | col][1] + |
668 | 1.00M | imgdata.image[row * imgdata.sizes.raw_width + |
669 | 1.00M | col2][1]) / |
670 | 1.00M | 2); |
671 | 1.00M | imgdata.image[row * imgdata.sizes.raw_width + col + 1][2] = |
672 | 1.00M | (unsigned short)(int(imgdata.image[row * imgdata.sizes.raw_width + |
673 | 1.00M | col][2] + |
674 | 1.00M | imgdata.image[row * imgdata.sizes.raw_width + |
675 | 1.00M | col2][2]) / |
676 | 1.00M | 2); |
677 | 1.00M | } |
678 | 11.4k | } |
679 | 76 | if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_RGB) |
680 | 0 | return; |
681 | | |
682 | 11.5k | for (row = 0; row < imgdata.sizes.raw_height; row++) |
683 | 11.4k | { |
684 | 11.4k | checkCancel(); // will throw out |
685 | 2.01M | for (col = 0; col < imgdata.sizes.raw_width; col++) |
686 | 2.00M | { |
687 | 2.00M | float Y = |
688 | 2.00M | float(imgdata.image[row * imgdata.sizes.raw_width + col][0]) / 2549.f; |
689 | 2.00M | float Ch2 = |
690 | 2.00M | float(imgdata.image[row * imgdata.sizes.raw_width + col][1] - 1280) / |
691 | 2.00M | 1536.f; |
692 | 2.00M | float Ch3 = |
693 | 2.00M | float(imgdata.image[row * imgdata.sizes.raw_width + col][2] - 1280) / |
694 | 2.00M | 1536.f; |
695 | 2.00M | if (Y > 1.f) |
696 | 377k | Y = 1.f; |
697 | 2.00M | if (Y > 0.803f) |
698 | 459k | Ch2 = Ch3 = 0.5f; |
699 | 2.00M | float r = Y + 1.40200f * (Ch3 - 0.5f); |
700 | 2.00M | if (r < 0.f) |
701 | 1.22M | r = 0.f; |
702 | 2.00M | if (r > 1.f) |
703 | 188k | r = 1.f; |
704 | 2.00M | float g = Y - 0.34414f * (Ch2 - 0.5f) - 0.71414f * (Ch3 - 0.5f); |
705 | 2.00M | if (g > 1.f) |
706 | 832k | g = 1.f; |
707 | 2.00M | if (g < 0.f) |
708 | 223k | g = 0.f; |
709 | 2.00M | float b = Y + 1.77200f * (Ch2 - 0.5f); |
710 | 2.00M | if (b > 1.f) |
711 | 182k | b = 1.f; |
712 | 2.00M | if (b < 0.f) |
713 | 1.14M | b = 0.f; |
714 | 2.00M | imgdata.image[row * imgdata.sizes.raw_width + col][0] = |
715 | 2.00M | imgdata.color.curve[int(r * 3072.f)]; |
716 | 2.00M | imgdata.image[row * imgdata.sizes.raw_width + col][1] = |
717 | 2.00M | imgdata.color.curve[int(g * 3072.f)]; |
718 | 2.00M | imgdata.image[row * imgdata.sizes.raw_width + col][2] = |
719 | 2.00M | imgdata.color.curve[int(b * 3072.f)]; |
720 | 2.00M | } |
721 | 11.4k | } |
722 | 76 | C.maximum = 16383; |
723 | 76 | } |
724 | | |
725 | | /* |
726 | | Each row is decoded independently. Each row starts with a 16 bit prefix. |
727 | | The hi byte is zero, the lo byte (first 3 bits) indicates a bit_base. |
728 | | Other bits remain unused. |
729 | | |
730 | | |0000 0000|0000 0XXX| => XXX is bit_base |
731 | | |
732 | | After the prefix the pixel data starts. Pixels are grouped into clusters |
733 | | forming 8 output pixel. Each cluster starts with a variable length of |
734 | | bits, indicating decompression flags. |
735 | | |
736 | | |
737 | | */ |
738 | | |
739 | | #undef MIN |
740 | | #undef MAX |
741 | | #undef LIM |
742 | | |
743 | | #define MIN(a, b) ((a) < (b) ? (a) : (b)) |
744 | 1.21k | #define MAX(a, b) ((a) > (b) ? (a) : (b)) |
745 | 606 | #define LIM(x, min, max) MAX(min, MIN(x, max)) |
746 | | |
747 | | struct iiq_bitstream_t |
748 | | { |
749 | | uint64_t curr; |
750 | | uint32_t *input; |
751 | | uint8_t used; |
752 | | size_t pos, maxpos; |
753 | 420 | iiq_bitstream_t(uint32_t *img_input, size_t inpsz): curr(0),input(img_input),used(0),pos(0),maxpos(inpsz){} |
754 | | |
755 | | void fill() |
756 | 595 | { |
757 | 595 | if (used <= 32) |
758 | 595 | { |
759 | 595 | uint64_t bitpump_next = *input++; |
760 | 595 | pos++; |
761 | 595 | if (pos > maxpos) throw LIBRAW_EXCEPTION_IO_EOF; |
762 | 184 | curr = (curr << 32) | bitpump_next; |
763 | 184 | used += 32; |
764 | 184 | } |
765 | 595 | } |
766 | | uint64_t peek(uint8_t len) |
767 | 2.25k | { |
768 | 2.25k | if (len >= used) |
769 | 595 | fill(); |
770 | | |
771 | 2.25k | uint64_t res = curr >> (used - len); |
772 | 2.25k | return res & ((1 << (uint8_t)len) - 1); |
773 | 2.25k | } |
774 | | |
775 | | void consume(uint8_t len) |
776 | 971 | { |
777 | 971 | peek(len); // fill buffer if needed |
778 | 971 | used -= len; |
779 | 971 | } |
780 | | |
781 | | uint64_t get(char len) |
782 | 1.02k | { |
783 | 1.02k | uint64_t val = peek(len); |
784 | 1.02k | consume(len); |
785 | 1.02k | return val; |
786 | 1.02k | } |
787 | | |
788 | | }; |
789 | | |
790 | | void decode_S_type(int32_t out_width, uint32_t *img_input, ushort *outbuf, size_t datalen /*, int bit_depth*/) |
791 | 420 | { |
792 | | #if 0 |
793 | | if (((bit_depth - 12) & 0xFFFFFFFD) != 0) |
794 | | return 0; |
795 | | #endif |
796 | 420 | iiq_bitstream_t stream(img_input,datalen); |
797 | | |
798 | 420 | const int pix_corr_shift = 2; // 16 - bit_depth; |
799 | 420 | unsigned int bit_check[2] = { 0, 0 }; |
800 | | |
801 | 420 | const uint8_t used_corr[8] = { |
802 | 420 | 3, 3, 3, 3, 1, 1, 1, 1, |
803 | 420 | }; |
804 | | |
805 | 420 | const uint8_t extra_bits[8] = { |
806 | 420 | 1, 2, 3, 4, 0, 0, 0, 0, |
807 | 420 | }; |
808 | | |
809 | 420 | const uint8_t bit_indicator[8 * 4] = { |
810 | 420 | 9, 8, 0, 7, 6, 6, 5, 5, 1, 1, 1, 1, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, |
811 | 420 | }; |
812 | | |
813 | 420 | const uint8_t skip_bits[8 * 4] = {5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, |
814 | 420 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; |
815 | | |
816 | 420 | int block_count = ((out_width - 8) >> 3) + 1; |
817 | 420 | int block_total_bytes = 8 * block_count; |
818 | | |
819 | 420 | int32_t prev_pix_value[2] = { 0, 0 }; |
820 | | |
821 | 420 | uint8_t init_bits = stream.get(16) & 7; |
822 | | |
823 | 420 | if (out_width - 7 > 0) |
824 | 27 | { |
825 | 27 | uint8_t pix_sub_init = 17 - init_bits; |
826 | | |
827 | 114 | for (int blk_id = 0; blk_id < block_count; ++blk_id) |
828 | 87 | { |
829 | 87 | int8_t idx_even = int8_t(stream.peek(7)); |
830 | 87 | stream.consume(2); |
831 | | |
832 | 87 | if ((unsigned int)idx_even >= 32) |
833 | 31 | bit_check[0] = ((unsigned int)idx_even >> 5) + bit_check[0] - 2; |
834 | 56 | else |
835 | 56 | { |
836 | 56 | bit_check[0] = bit_indicator[idx_even]; |
837 | 56 | stream.consume(skip_bits[idx_even]); |
838 | 56 | } |
839 | | |
840 | 87 | int8_t idx_odd = int8_t(stream.peek(7)); |
841 | 87 | stream.consume(2); |
842 | | |
843 | 87 | if ((unsigned int)idx_odd >= 32) |
844 | 42 | bit_check[1] = ((unsigned int)idx_odd >> 5) + bit_check[1] - 2; |
845 | 45 | else |
846 | 45 | { |
847 | 45 | bit_check[1] = bit_indicator[idx_odd]; |
848 | 45 | stream.consume(skip_bits[idx_odd]); |
849 | 45 | } |
850 | | |
851 | 87 | uint8_t bidx = uint8_t(stream.peek(3)); |
852 | 87 | stream.consume(used_corr[bidx]); |
853 | | |
854 | 87 | uint8_t take_bits = init_bits + extra_bits[bidx]; // 11 or less |
855 | | |
856 | 87 | uint32_t bp_shift[2] = {bit_check[0] - extra_bits[bidx], bit_check[1] - extra_bits[bidx]}; |
857 | | |
858 | 87 | int pix_sub[2] = {0xFFFF >> (pix_sub_init - bit_check[0]), 0xFFFF >> (pix_sub_init - bit_check[1])}; |
859 | | |
860 | 693 | for (int i = 0; i < 8; i++) // MAIN LOOP for pixel decoding |
861 | 606 | { |
862 | 606 | int32_t value = 0; |
863 | 606 | if (bit_check[i & 1] == 9) |
864 | 266 | value = int32_t(stream.get(14)); |
865 | 340 | else |
866 | 340 | value = prev_pix_value[i & 1] + ((uint32_t)stream.get(take_bits) << bp_shift[i & 1]) - pix_sub[i & 1]; |
867 | | |
868 | 606 | outbuf[i] = LIM(value << pix_corr_shift, 0, 0xffff); |
869 | 606 | prev_pix_value[i & 1] = value; |
870 | 606 | } |
871 | 87 | outbuf += 8; // always produce 8 pixels from this cluster |
872 | 87 | } |
873 | 27 | } // if width > 7 // End main if |
874 | | |
875 | | // Final block |
876 | | // maybe fill/unpack extra bytes if width % 8 <> 0? |
877 | 420 | if (block_total_bytes < out_width) |
878 | 0 | { |
879 | 0 | do |
880 | 0 | { |
881 | 0 | stream.fill(); |
882 | 0 | uint32_t pix_value = uint32_t(stream.get(14)); |
883 | 0 | ++block_total_bytes; |
884 | 0 | *outbuf++ = pix_value << pix_corr_shift; |
885 | 0 | } while (block_total_bytes < out_width); |
886 | 0 | } |
887 | 420 | } |
888 | | |
889 | | struct p1_row_info_t |
890 | | { |
891 | | unsigned row; |
892 | | INT64 offset; |
893 | 6.72M | p1_row_info_t(): row(0),offset(0){} |
894 | 8.62M | p1_row_info_t(const p1_row_info_t& q): row(q.row),offset(q.offset){} |
895 | 57.6M | bool operator < (const p1_row_info_t & rhs) const { return offset < rhs.offset; } |
896 | | }; |
897 | | |
898 | | void LibRaw::phase_one_load_raw_s() |
899 | 422 | { |
900 | 422 | if(!libraw_internal_data.unpacker_data.strip_offset || !imgdata.rawdata.raw_image || !libraw_internal_data.unpacker_data.data_offset) |
901 | 2 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
902 | 420 | std::vector<p1_row_info_t> stripes(imgdata.sizes.raw_height+1); |
903 | 420 | libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.strip_offset, SEEK_SET); |
904 | 6.72M | for (unsigned row = 0; row < imgdata.sizes.raw_height; row++) |
905 | 6.72M | { |
906 | 6.72M | stripes[row].row = row; |
907 | 6.72M | stripes[row].offset = INT64(get4()) + libraw_internal_data.unpacker_data.data_offset; |
908 | 6.72M | } |
909 | 420 | stripes[imgdata.sizes.raw_height].row = imgdata.sizes.raw_height; |
910 | 420 | stripes[imgdata.sizes.raw_height].offset = libraw_internal_data.unpacker_data.data_offset + INT64(libraw_internal_data.unpacker_data.data_size); |
911 | 420 | std::sort(stripes.begin(), stripes.end()); |
912 | 420 | INT64 maxsz = imgdata.sizes.raw_width * 3 + 2; // theor max: 17 bytes per 8 pix + row header |
913 | 420 | std::vector<uint8_t> datavec(maxsz+4); |
914 | | |
915 | 872 | for (unsigned row = 0; row < imgdata.sizes.raw_height; row++) |
916 | 460 | { |
917 | 460 | if (stripes[row].row >= imgdata.sizes.raw_height) continue; |
918 | 429 | ushort *datap = imgdata.rawdata.raw_image + stripes[row].row * imgdata.sizes.raw_width; |
919 | 429 | libraw_internal_data.internal_data.input->seek(stripes[row].offset, SEEK_SET); |
920 | 429 | INT64 readsz = stripes[row + 1].offset - stripes[row].offset; |
921 | 429 | if (readsz > maxsz) |
922 | 8 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
923 | | |
924 | 421 | if(libraw_internal_data.internal_data.input->read(datavec.data(), 1, readsz) != readsz) |
925 | 1 | derror(); // TODO: check read state |
926 | | |
927 | 421 | decode_S_type(imgdata.sizes.raw_width, (uint32_t *)datavec.data(), datap, readsz /*, 14 */); |
928 | 421 | } |
929 | 420 | } |
930 | | |
931 | 16.6M | #define ph1_bits(n) ph1_bithuff(n, 0) |
932 | | #if defined (RAW) |
933 | | #undef RAW |
934 | | #endif |
935 | 57.5M | #define RAW(row, col) imgdata.rawdata.raw_image[(row)*imgdata.sizes.raw_width + (col)] |
936 | | |
937 | | void LibRaw::samsung3_load_raw() |
938 | 79 | { |
939 | 79 | if(imgdata.sizes.raw_height < 436 || imgdata.sizes.raw_width < 646) |
940 | 2 | throw LIBRAW_EXCEPTION_IO_CORRUPT; // From Samsung opensource decoder: too small image |
941 | | |
942 | 77 | libraw_internal_data.unpacker_data.order = 0x4949; |
943 | 77 | const INT64 maxpixidx = (INT64)imgdata.sizes.raw_width * (INT64)(int)imgdata.sizes.raw_height; |
944 | | |
945 | 77 | ph1_bits(-1); |
946 | 77 | ph1_bits(16); |
947 | 77 | ph1_bits(4); |
948 | 77 | unsigned bit_depth = ph1_bits(4) + 1; |
949 | 77 | int datamax = (1 << bit_depth) - 1; |
950 | 77 | ph1_bits(8); |
951 | 77 | ph1_bits(16); |
952 | 77 | ph1_bits(16); |
953 | 77 | ph1_bits(16); |
954 | 77 | ph1_bits(4); |
955 | 77 | unsigned optflags = ph1_bits(4); |
956 | 77 | ph1_bits(16); |
957 | 77 | ph1_bits(8); |
958 | 77 | ph1_bits(2); |
959 | 77 | ushort init_val = ph1_bits(14); |
960 | | |
961 | 16.3k | for (int row = 0; row < (int)imgdata.sizes.raw_height; row++) |
962 | 16.3k | { |
963 | 16.3k | libraw_internal_data.internal_data.input->seek( |
964 | 16.3k | (libraw_internal_data.unpacker_data.data_offset - libraw_internal_data.internal_data.input->tell()) & 15, |
965 | 16.3k | SEEK_CUR); |
966 | 16.3k | ph1_bits(-1); |
967 | | |
968 | 16.3k | INT64 rowstart = (INT64)row * (INT64)imgdata.sizes.raw_width; |
969 | | |
970 | 16.3k | unsigned motion = 7; |
971 | 16.3k | int scale = 0; |
972 | 16.3k | unsigned diff_bits_mode[3][2]; |
973 | | |
974 | 65.4k | for (int i = 0; i < 3; i++) |
975 | 49.0k | diff_bits_mode[i][0] = diff_bits_mode[i][1] = (row < 2) ? 7 : 4; |
976 | | |
977 | 842k | for (int col = 0; col < (int)imgdata.sizes.raw_width - 15; col += 16) |
978 | 825k | { |
979 | 825k | if ((optflags & 4) == 0 && (col & 63) == 0) |
980 | 85.7k | { |
981 | 85.7k | const int scalevals[3] = {0, -2, 2}; |
982 | 85.7k | int i = ph1_bits(2); |
983 | 85.7k | if (i < 3) |
984 | 891 | scale += scalevals[i]; |
985 | 84.8k | else |
986 | 84.8k | scale = ph1_bits(12); |
987 | 85.7k | } |
988 | | |
989 | 825k | if (optflags & 2) |
990 | 306k | motion = ph1_bits(1) ? 3 : 7; |
991 | 519k | else if (ph1_bits(1) == 0) |
992 | 623 | motion = ph1_bits(3); |
993 | | // else => unchanged |
994 | | |
995 | 825k | if (motion == 7) |
996 | 8.89M | for (int i = 0; i < 16; i++) |
997 | 8.37M | RAW(row, col + i) = (col == 0) ? init_val : RAW(row, col + i - 2); |
998 | 302k | else |
999 | 302k | { |
1000 | 302k | if (row < 2) |
1001 | 26 | throw LIBRAW_EXCEPTION_IO_CORRUPT; // wrong motion mode: previous line lookup on first two lines |
1002 | | |
1003 | 302k | const int motion_offset[7] = {-4, -2, -2, 0, 0, 2, 4}; |
1004 | 302k | const int motion_average[7] = {0, 0, 1, 0, 1, 0, 0}; |
1005 | | |
1006 | 5.14M | for (int i = 0; i < 16; i++) |
1007 | 4.83M | { |
1008 | 4.83M | int refrow = ((row + i) & 1) ? row - 2 : row - 1; |
1009 | 4.83M | int refcol = col + i + motion_offset[motion] + (1 - ((row + i) & 1)) * (1 - 2 * (i & 1)); |
1010 | 4.83M | INT64 refidx = (INT64)refrow * (INT64)imgdata.sizes.raw_width + (INT64)refcol; |
1011 | 4.83M | if(refidx < 0) // no need to check for >= because refrow is 1-2 rows up and col diffrence is ~+4 pix max |
1012 | 2 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
1013 | 4.83M | RAW(row, col + i) = |
1014 | 4.83M | motion_average[motion] ? (RAW(refrow, refcol) + RAW(refrow, refcol + 2) + 1) >> 1 : RAW(refrow, refcol); |
1015 | 4.83M | } |
1016 | 302k | } |
1017 | | |
1018 | 825k | unsigned diff_bits[4] = {0, 0, 0, 0}; |
1019 | 825k | if ((optflags & 1) || ph1_bits(1) == 0) |
1020 | 233k | { |
1021 | 233k | unsigned flags[4]; |
1022 | 1.16M | for (int i = 0; i < 4; i++) |
1023 | 934k | flags[i] = ph1_bits(2); |
1024 | 1.16M | for (int i = 0; i < 4; i++) |
1025 | 934k | { |
1026 | 934k | unsigned colornum = (row % 2) ? (i >> 1) : ((i >> 1) + 2) % 3; |
1027 | 934k | switch (flags[i]) |
1028 | 934k | { |
1029 | 23.2k | case 0: |
1030 | 23.2k | diff_bits[i] = diff_bits_mode[colornum][0]; |
1031 | 23.2k | break; |
1032 | 406 | case 1: |
1033 | 406 | diff_bits[i] = diff_bits_mode[colornum][0] + 1; |
1034 | 406 | break; |
1035 | 451 | case 2: |
1036 | 451 | diff_bits[i] = diff_bits_mode[colornum][0] - 1; |
1037 | 451 | break; |
1038 | 910k | case 3: |
1039 | 910k | diff_bits[i] = ph1_bits(4); |
1040 | 910k | break; |
1041 | 934k | } |
1042 | 934k | diff_bits_mode[colornum][0] = diff_bits_mode[colornum][1]; |
1043 | 934k | diff_bits_mode[colornum][1] = diff_bits[i]; |
1044 | 934k | if (diff_bits[i] > bit_depth + 1) |
1045 | 29 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
1046 | 934k | } |
1047 | 233k | } |
1048 | | |
1049 | 14.0M | for (int i = 0; i < 16; i++) |
1050 | 13.2M | { |
1051 | 13.2M | unsigned len = diff_bits[i >> 2]; |
1052 | 13.2M | int sign_mask = 1 << (len - 1); |
1053 | 13.2M | int diff = ((ph1_bits(len) ^ sign_mask) - sign_mask) * (scale * 2 + 1) + scale; |
1054 | 13.2M | int rcol = (row % 2) ? col + ((i & 0x7) << 1) + 1 - (i >> 3) : col + ((i & 0x7) << 1) + (i >> 3); |
1055 | 13.2M | INT64 bidx = rowstart + (INT64)rcol; |
1056 | 13.2M | if(bidx <0 || bidx>=maxpixidx) |
1057 | 0 | throw LIBRAW_EXCEPTION_IO_CORRUPT; |
1058 | 13.2M | int val = RAW(row, rcol) + diff; |
1059 | 13.2M | RAW(row, rcol) = val < 0 ? 0 : (val > datamax ? datamax : val); |
1060 | 13.2M | } |
1061 | 825k | } |
1062 | 16.3k | } |
1063 | 77 | } |