1 /* -*- C++ -*-
2 * File: libraw_fuji_compressed.cpp
3 * Copyright (C) 2016-2019 Alexey Danilchenko
4 *
5 * Adopted to LibRaw by Alex Tutubalin, lexa@lexa.ru
6 * LibRaw Fujifilm/compressed decoder
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/libraw_cxx_defs.h"
20
21 #ifdef _abs
22 #undef _abs
23 #undef _min
24 #undef _max
25 #endif
26 #define _abs(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
27 #define _min(a, b) ((a) < (b) ? (a) : (b))
28 #define _max(a, b) ((a) > (b) ? (a) : (b))
29
30 struct int_pair
31 {
32 int value1;
33 int value2;
34 };
35
36 enum _xt_lines
37 {
38 _R0 = 0,
39 _R1,
40 _R2,
41 _R3,
42 _R4,
43 _G0,
44 _G1,
45 _G2,
46 _G3,
47 _G4,
48 _G5,
49 _G6,
50 _G7,
51 _B0,
52 _B1,
53 _B2,
54 _B3,
55 _B4,
56 _ltotal
57 };
58
59 struct fuji_compressed_block
60 {
61 int cur_bit; // current bit being read (from left to right)
62 int cur_pos; // current position in a buffer
63 INT64 cur_buf_offset; // offset of this buffer in a file
64 unsigned max_read_size; // Amount of data to be read
65 int cur_buf_size; // buffer size
66 uchar *cur_buf; // currently read block
67 int fillbytes; // Counter to add extra byte for block size N*16
68 LibRaw_abstract_datastream *input;
69 struct int_pair grad_even[3][41]; // tables of gradients
70 struct int_pair grad_odd[3][41];
71 ushort *linealloc;
72 ushort *linebuf[_ltotal];
73 };
74
init_fuji_compr(struct fuji_compressed_params * info)75 void LibRaw::init_fuji_compr(struct fuji_compressed_params *info)
76 {
77 int cur_val;
78 int8_t *qt;
79
80 if ((libraw_internal_data.unpacker_data.fuji_block_width % 3 &&
81 libraw_internal_data.unpacker_data.fuji_raw_type == 16) ||
82 (libraw_internal_data.unpacker_data.fuji_block_width & 1 &&
83 libraw_internal_data.unpacker_data.fuji_raw_type == 0))
84 derror();
85
86 info->q_table =
87 (int8_t *)malloc(2 << libraw_internal_data.unpacker_data.fuji_bits);
88 merror(info->q_table, "init_fuji_compr()");
89
90 if (libraw_internal_data.unpacker_data.fuji_raw_type == 16)
91 info->line_width =
92 (libraw_internal_data.unpacker_data.fuji_block_width * 2) / 3;
93 else
94 info->line_width = libraw_internal_data.unpacker_data.fuji_block_width >> 1;
95
96 info->q_point[0] = 0;
97 info->q_point[1] = 0x12;
98 info->q_point[2] = 0x43;
99 info->q_point[3] = 0x114;
100 info->q_point[4] = (1 << libraw_internal_data.unpacker_data.fuji_bits) - 1;
101 info->min_value = 0x40;
102
103 cur_val = -info->q_point[4];
104 for (qt = info->q_table; cur_val <= info->q_point[4]; ++qt, ++cur_val)
105 {
106 if (cur_val <= -info->q_point[3])
107 *qt = -4;
108 else if (cur_val <= -info->q_point[2])
109 *qt = -3;
110 else if (cur_val <= -info->q_point[1])
111 *qt = -2;
112 else if (cur_val < 0)
113 *qt = -1;
114 else if (cur_val == 0)
115 *qt = 0;
116 else if (cur_val < info->q_point[1])
117 *qt = 1;
118 else if (cur_val < info->q_point[2])
119 *qt = 2;
120 else if (cur_val < info->q_point[3])
121 *qt = 3;
122 else
123 *qt = 4;
124 }
125
126 // populting gradients
127 info->total_values = (1 << libraw_internal_data.unpacker_data.fuji_bits);
128 info->raw_bits = libraw_internal_data.unpacker_data.fuji_bits;
129 info->max_bits = 4 * info->raw_bits;
130 info->maxDiff = info->total_values >> 6;
131 }
132
133 #define XTRANS_BUF_SIZE 0x10000
134
fuji_fill_buffer(struct fuji_compressed_block * info)135 static inline void fuji_fill_buffer(struct fuji_compressed_block *info)
136 {
137 if (info->cur_pos >= info->cur_buf_size)
138 {
139 info->cur_pos = 0;
140 info->cur_buf_offset += info->cur_buf_size;
141 #ifdef LIBRAW_USE_OPENMP
142 #pragma omp critical
143 #endif
144 {
145 #ifndef LIBRAW_USE_OPENMP
146 info->input->lock();
147 #endif
148 info->input->seek(info->cur_buf_offset, SEEK_SET);
149 info->cur_buf_size = info->input->read(
150 info->cur_buf, 1, _min(info->max_read_size, XTRANS_BUF_SIZE));
151 #ifndef LIBRAW_USE_OPENMP
152 info->input->unlock();
153 #endif
154 if (info->cur_buf_size < 1) // nothing read
155 {
156 if (info->fillbytes > 0)
157 {
158 int ls = _max(1, _min(info->fillbytes, XTRANS_BUF_SIZE));
159 memset(info->cur_buf, 0, ls);
160 info->fillbytes -= ls;
161 }
162 else
163 throw LIBRAW_EXCEPTION_IO_EOF;
164 }
165 info->max_read_size -= info->cur_buf_size;
166 }
167 }
168 }
169
init_fuji_block(struct fuji_compressed_block * info,const struct fuji_compressed_params * params,INT64 raw_offset,unsigned dsize)170 void LibRaw::init_fuji_block(struct fuji_compressed_block *info,
171 const struct fuji_compressed_params *params,
172 INT64 raw_offset, unsigned dsize)
173 {
174 info->linealloc =
175 (ushort *)calloc(sizeof(ushort), _ltotal * (params->line_width + 2));
176 merror(info->linealloc, "init_fuji_block()");
177
178 INT64 fsize = libraw_internal_data.internal_data.input->size();
179 info->max_read_size =
180 _min(unsigned(fsize - raw_offset), dsize); // Data size may be incorrect?
181 info->fillbytes = 1;
182
183 info->input = libraw_internal_data.internal_data.input;
184 info->linebuf[_R0] = info->linealloc;
185 for (int i = _R1; i <= _B4; i++)
186 info->linebuf[i] = info->linebuf[i - 1] + params->line_width + 2;
187
188 // init buffer
189 info->cur_buf = (uchar *)malloc(XTRANS_BUF_SIZE);
190 merror(info->cur_buf, "init_fuji_block()");
191 info->cur_bit = 0;
192 info->cur_pos = 0;
193 info->cur_buf_offset = raw_offset;
194 for (int j = 0; j < 3; j++)
195 for (int i = 0; i < 41; i++)
196 {
197 info->grad_even[j][i].value1 = params->maxDiff;
198 info->grad_even[j][i].value2 = 1;
199 info->grad_odd[j][i].value1 = params->maxDiff;
200 info->grad_odd[j][i].value2 = 1;
201 }
202
203 info->cur_buf_size = 0;
204 fuji_fill_buffer(info);
205 }
206
copy_line_to_xtrans(struct fuji_compressed_block * info,int cur_line,int cur_block,int cur_block_width)207 void LibRaw::copy_line_to_xtrans(struct fuji_compressed_block *info,
208 int cur_line, int cur_block,
209 int cur_block_width)
210 {
211 ushort *lineBufB[3];
212 ushort *lineBufG[6];
213 ushort *lineBufR[3];
214 unsigned pixel_count;
215 ushort *line_buf;
216 int index;
217
218 int offset = libraw_internal_data.unpacker_data.fuji_block_width * cur_block +
219 6 * imgdata.sizes.raw_width * cur_line;
220 ushort *raw_block_data = imgdata.rawdata.raw_image + offset;
221 int row_count = 0;
222
223 for (int i = 0; i < 3; i++)
224 {
225 lineBufR[i] = info->linebuf[_R2 + i] + 1;
226 lineBufB[i] = info->linebuf[_B2 + i] + 1;
227 }
228 for (int i = 0; i < 6; i++)
229 lineBufG[i] = info->linebuf[_G2 + i] + 1;
230
231 while (row_count < 6)
232 {
233 pixel_count = 0;
234 while (pixel_count < (unsigned)cur_block_width)
235 {
236 switch (imgdata.idata.xtrans_abs[row_count][(pixel_count % 6)])
237 {
238 case 0: // red
239 line_buf = lineBufR[row_count >> 1];
240 break;
241 case 1: // green
242 default: // to make static analyzer happy
243 line_buf = lineBufG[row_count];
244 break;
245 case 2: // blue
246 line_buf = lineBufB[row_count >> 1];
247 break;
248 }
249
250 index = (((pixel_count * 2 / 3) & 0x7FFFFFFE) | ((pixel_count % 3) & 1)) +
251 ((pixel_count % 3) >> 1);
252 raw_block_data[pixel_count] = line_buf[index];
253
254 ++pixel_count;
255 }
256 ++row_count;
257 raw_block_data += imgdata.sizes.raw_width;
258 }
259 }
260
copy_line_to_bayer(struct fuji_compressed_block * info,int cur_line,int cur_block,int cur_block_width)261 void LibRaw::copy_line_to_bayer(struct fuji_compressed_block *info,
262 int cur_line, int cur_block,
263 int cur_block_width)
264 {
265 ushort *lineBufB[3];
266 ushort *lineBufG[6];
267 ushort *lineBufR[3];
268 unsigned pixel_count;
269 ushort *line_buf;
270
271 int fuji_bayer[2][2];
272 for (int r = 0; r < 2; r++)
273 for (int c = 0; c < 2; c++)
274 fuji_bayer[r][c] = FC(r, c); // We'll downgrade G2 to G below
275
276 int offset = libraw_internal_data.unpacker_data.fuji_block_width * cur_block +
277 6 * imgdata.sizes.raw_width * cur_line;
278 ushort *raw_block_data = imgdata.rawdata.raw_image + offset;
279 int row_count = 0;
280
281 for (int i = 0; i < 3; i++)
282 {
283 lineBufR[i] = info->linebuf[_R2 + i] + 1;
284 lineBufB[i] = info->linebuf[_B2 + i] + 1;
285 }
286 for (int i = 0; i < 6; i++)
287 lineBufG[i] = info->linebuf[_G2 + i] + 1;
288
289 while (row_count < 6)
290 {
291 pixel_count = 0;
292 while (pixel_count < (unsigned)cur_block_width)
293 {
294 switch (fuji_bayer[row_count & 1][pixel_count & 1])
295 {
296 case 0: // red
297 line_buf = lineBufR[row_count >> 1];
298 break;
299 case 1: // green
300 case 3: // second green
301 default: // to make static analyzer happy
302 line_buf = lineBufG[row_count];
303 break;
304 case 2: // blue
305 line_buf = lineBufB[row_count >> 1];
306 break;
307 }
308
309 raw_block_data[pixel_count] = line_buf[pixel_count >> 1];
310 ++pixel_count;
311 }
312 ++row_count;
313 raw_block_data += imgdata.sizes.raw_width;
314 }
315 }
316
317 #define fuji_quant_gradient(i, v1, v2) \
318 (9 * i->q_table[i->q_point[4] + (v1)] + i->q_table[i->q_point[4] + (v2)])
319
fuji_zerobits(struct fuji_compressed_block * info,int * count)320 static inline void fuji_zerobits(struct fuji_compressed_block *info, int *count)
321 {
322 uchar zero = 0;
323 *count = 0;
324 while (zero == 0)
325 {
326 zero = (info->cur_buf[info->cur_pos] >> (7 - info->cur_bit)) & 1;
327 info->cur_bit++;
328 info->cur_bit &= 7;
329 if (!info->cur_bit)
330 {
331 ++info->cur_pos;
332 fuji_fill_buffer(info);
333 }
334 if (zero)
335 break;
336 ++*count;
337 }
338 }
339
fuji_read_code(struct fuji_compressed_block * info,int * data,int bits_to_read)340 static inline void fuji_read_code(struct fuji_compressed_block *info, int *data,
341 int bits_to_read)
342 {
343 uchar bits_left = bits_to_read;
344 uchar bits_left_in_byte = 8 - (info->cur_bit & 7);
345 *data = 0;
346 if (!bits_to_read)
347 return;
348 if (bits_to_read >= bits_left_in_byte)
349 {
350 do
351 {
352 *data <<= bits_left_in_byte;
353 bits_left -= bits_left_in_byte;
354 *data |= info->cur_buf[info->cur_pos] & ((1 << bits_left_in_byte) - 1);
355 ++info->cur_pos;
356 fuji_fill_buffer(info);
357 bits_left_in_byte = 8;
358 } while (bits_left >= 8);
359 }
360 if (!bits_left)
361 {
362 info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7;
363 return;
364 }
365 *data <<= bits_left;
366 bits_left_in_byte -= bits_left;
367 *data |= ((1 << bits_left) - 1) &
368 ((unsigned)info->cur_buf[info->cur_pos] >> bits_left_in_byte);
369 info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7;
370 }
371
bitDiff(int value1,int value2)372 static inline int bitDiff(int value1, int value2)
373 {
374 int decBits = 0;
375 if (value2 < value1)
376 while (decBits <= 14 && (value2 << ++decBits) < value1)
377 ;
378 return decBits;
379 }
380
381 static inline int
fuji_decode_sample_even(struct fuji_compressed_block * info,const struct fuji_compressed_params * params,ushort * line_buf,int pos,struct int_pair * grads)382 fuji_decode_sample_even(struct fuji_compressed_block *info,
383 const struct fuji_compressed_params *params,
384 ushort *line_buf, int pos, struct int_pair *grads)
385 {
386 int interp_val = 0;
387 // ushort decBits;
388 int errcnt = 0;
389
390 int sample = 0, code = 0;
391 ushort *line_buf_cur = line_buf + pos;
392 int Rb = line_buf_cur[-2 - params->line_width];
393 int Rc = line_buf_cur[-3 - params->line_width];
394 int Rd = line_buf_cur[-1 - params->line_width];
395 int Rf = line_buf_cur[-4 - 2 * params->line_width];
396
397 int grad, gradient, diffRcRb, diffRfRb, diffRdRb;
398
399 grad = fuji_quant_gradient(params, Rb - Rf, Rc - Rb);
400 gradient = _abs(grad);
401 diffRcRb = _abs(Rc - Rb);
402 diffRfRb = _abs(Rf - Rb);
403 diffRdRb = _abs(Rd - Rb);
404
405 if (diffRcRb > diffRfRb && diffRcRb > diffRdRb)
406 interp_val = Rf + Rd + 2 * Rb;
407 else if (diffRdRb > diffRcRb && diffRdRb > diffRfRb)
408 interp_val = Rf + Rc + 2 * Rb;
409 else
410 interp_val = Rd + Rc + 2 * Rb;
411
412 fuji_zerobits(info, &sample);
413
414 if (sample < params->max_bits - params->raw_bits - 1)
415 {
416 int decBits = bitDiff(grads[gradient].value1, grads[gradient].value2);
417 fuji_read_code(info, &code, decBits);
418 code += sample << decBits;
419 }
420 else
421 {
422 fuji_read_code(info, &code, params->raw_bits);
423 code++;
424 }
425
426 if (code < 0 || code >= params->total_values)
427 errcnt++;
428
429 if (code & 1)
430 code = -1 - code / 2;
431 else
432 code /= 2;
433
434 grads[gradient].value1 += _abs(code);
435 if (grads[gradient].value2 == params->min_value)
436 {
437 grads[gradient].value1 >>= 1;
438 grads[gradient].value2 >>= 1;
439 }
440 grads[gradient].value2++;
441 if (grad < 0)
442 interp_val = (interp_val >> 2) - code;
443 else
444 interp_val = (interp_val >> 2) + code;
445 if (interp_val < 0)
446 interp_val += params->total_values;
447 else if (interp_val > params->q_point[4])
448 interp_val -= params->total_values;
449
450 if (interp_val >= 0)
451 line_buf_cur[0] = _min(interp_val, params->q_point[4]);
452 else
453 line_buf_cur[0] = 0;
454 return errcnt;
455 }
456
457 static inline int
fuji_decode_sample_odd(struct fuji_compressed_block * info,const struct fuji_compressed_params * params,ushort * line_buf,int pos,struct int_pair * grads)458 fuji_decode_sample_odd(struct fuji_compressed_block *info,
459 const struct fuji_compressed_params *params,
460 ushort *line_buf, int pos, struct int_pair *grads)
461 {
462 int interp_val = 0;
463 int errcnt = 0;
464
465 int sample = 0, code = 0;
466 ushort *line_buf_cur = line_buf + pos;
467 int Ra = line_buf_cur[-1];
468 int Rb = line_buf_cur[-2 - params->line_width];
469 int Rc = line_buf_cur[-3 - params->line_width];
470 int Rd = line_buf_cur[-1 - params->line_width];
471 int Rg = line_buf_cur[1];
472
473 int grad, gradient;
474
475 grad = fuji_quant_gradient(params, Rb - Rc, Rc - Ra);
476 gradient = _abs(grad);
477
478 if ((Rb > Rc && Rb > Rd) || (Rb < Rc && Rb < Rd))
479 interp_val = (Rg + Ra + 2 * Rb) >> 2;
480 else
481 interp_val = (Ra + Rg) >> 1;
482
483 fuji_zerobits(info, &sample);
484
485 if (sample < params->max_bits - params->raw_bits - 1)
486 {
487 int decBits = bitDiff(grads[gradient].value1, grads[gradient].value2);
488 fuji_read_code(info, &code, decBits);
489 code += sample << decBits;
490 }
491 else
492 {
493 fuji_read_code(info, &code, params->raw_bits);
494 code++;
495 }
496
497 if (code < 0 || code >= params->total_values)
498 errcnt++;
499
500 if (code & 1)
501 code = -1 - code / 2;
502 else
503 code /= 2;
504
505 grads[gradient].value1 += _abs(code);
506 if (grads[gradient].value2 == params->min_value)
507 {
508 grads[gradient].value1 >>= 1;
509 grads[gradient].value2 >>= 1;
510 }
511 grads[gradient].value2++;
512 if (grad < 0)
513 interp_val -= code;
514 else
515 interp_val += code;
516 if (interp_val < 0)
517 interp_val += params->total_values;
518 else if (interp_val > params->q_point[4])
519 interp_val -= params->total_values;
520
521 if (interp_val >= 0)
522 line_buf_cur[0] = _min(interp_val, params->q_point[4]);
523 else
524 line_buf_cur[0] = 0;
525 return errcnt;
526 }
527
fuji_decode_interpolation_even(int line_width,ushort * line_buf,int pos)528 static void fuji_decode_interpolation_even(int line_width, ushort *line_buf,
529 int pos)
530 {
531 ushort *line_buf_cur = line_buf + pos;
532 int Rb = line_buf_cur[-2 - line_width];
533 int Rc = line_buf_cur[-3 - line_width];
534 int Rd = line_buf_cur[-1 - line_width];
535 int Rf = line_buf_cur[-4 - 2 * line_width];
536 int diffRcRb = _abs(Rc - Rb);
537 int diffRfRb = _abs(Rf - Rb);
538 int diffRdRb = _abs(Rd - Rb);
539 if (diffRcRb > diffRfRb && diffRcRb > diffRdRb)
540 *line_buf_cur = (Rf + Rd + 2 * Rb) >> 2;
541 else if (diffRdRb > diffRcRb && diffRdRb > diffRfRb)
542 *line_buf_cur = (Rf + Rc + 2 * Rb) >> 2;
543 else
544 *line_buf_cur = (Rd + Rc + 2 * Rb) >> 2;
545 }
546
fuji_extend_generic(ushort * linebuf[_ltotal],int line_width,int start,int end)547 static void fuji_extend_generic(ushort *linebuf[_ltotal], int line_width,
548 int start, int end)
549 {
550 for (int i = start; i <= end; i++)
551 {
552 linebuf[i][0] = linebuf[i - 1][1];
553 linebuf[i][line_width + 1] = linebuf[i - 1][line_width];
554 }
555 }
556
fuji_extend_red(ushort * linebuf[_ltotal],int line_width)557 static void fuji_extend_red(ushort *linebuf[_ltotal], int line_width)
558 {
559 fuji_extend_generic(linebuf, line_width, _R2, _R4);
560 }
561
fuji_extend_green(ushort * linebuf[_ltotal],int line_width)562 static void fuji_extend_green(ushort *linebuf[_ltotal], int line_width)
563 {
564 fuji_extend_generic(linebuf, line_width, _G2, _G7);
565 }
566
fuji_extend_blue(ushort * linebuf[_ltotal],int line_width)567 static void fuji_extend_blue(ushort *linebuf[_ltotal], int line_width)
568 {
569 fuji_extend_generic(linebuf, line_width, _B2, _B4);
570 }
571
xtrans_decode_block(struct fuji_compressed_block * info,const struct fuji_compressed_params * params,int cur_line)572 void LibRaw::xtrans_decode_block(struct fuji_compressed_block *info,
573 const struct fuji_compressed_params *params,
574 int cur_line)
575 {
576 int r_even_pos = 0, r_odd_pos = 1;
577 int g_even_pos = 0, g_odd_pos = 1;
578 int b_even_pos = 0, b_odd_pos = 1;
579
580 int errcnt = 0;
581
582 const int line_width = params->line_width;
583
584 while (g_even_pos < line_width || g_odd_pos < line_width)
585 {
586 if (g_even_pos < line_width)
587 {
588 fuji_decode_interpolation_even(line_width, info->linebuf[_R2] + 1,
589 r_even_pos);
590 r_even_pos += 2;
591 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G2] + 1,
592 g_even_pos, info->grad_even[0]);
593 g_even_pos += 2;
594 }
595 if (g_even_pos > 8)
596 {
597 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R2] + 1,
598 r_odd_pos, info->grad_odd[0]);
599 r_odd_pos += 2;
600 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G2] + 1,
601 g_odd_pos, info->grad_odd[0]);
602 g_odd_pos += 2;
603 }
604 }
605
606 fuji_extend_red(info->linebuf, line_width);
607 fuji_extend_green(info->linebuf, line_width);
608
609 g_even_pos = 0, g_odd_pos = 1;
610
611 while (g_even_pos < line_width || g_odd_pos < line_width)
612 {
613 if (g_even_pos < line_width)
614 {
615 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G3] + 1,
616 g_even_pos, info->grad_even[1]);
617 g_even_pos += 2;
618 fuji_decode_interpolation_even(line_width, info->linebuf[_B2] + 1,
619 b_even_pos);
620 b_even_pos += 2;
621 }
622 if (g_even_pos > 8)
623 {
624 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G3] + 1,
625 g_odd_pos, info->grad_odd[1]);
626 g_odd_pos += 2;
627 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B2] + 1,
628 b_odd_pos, info->grad_odd[1]);
629 b_odd_pos += 2;
630 }
631 }
632
633 fuji_extend_green(info->linebuf, line_width);
634 fuji_extend_blue(info->linebuf, line_width);
635
636 r_even_pos = 0, r_odd_pos = 1;
637 g_even_pos = 0, g_odd_pos = 1;
638
639 while (g_even_pos < line_width || g_odd_pos < line_width)
640 {
641 if (g_even_pos < line_width)
642 {
643 if (r_even_pos & 3)
644 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R3] + 1,
645 r_even_pos, info->grad_even[2]);
646 else
647 fuji_decode_interpolation_even(line_width, info->linebuf[_R3] + 1,
648 r_even_pos);
649 r_even_pos += 2;
650 fuji_decode_interpolation_even(line_width, info->linebuf[_G4] + 1,
651 g_even_pos);
652 g_even_pos += 2;
653 }
654 if (g_even_pos > 8)
655 {
656 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R3] + 1,
657 r_odd_pos, info->grad_odd[2]);
658 r_odd_pos += 2;
659 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G4] + 1,
660 g_odd_pos, info->grad_odd[2]);
661 g_odd_pos += 2;
662 }
663 }
664
665 fuji_extend_red(info->linebuf, line_width);
666 fuji_extend_green(info->linebuf, line_width);
667
668 g_even_pos = 0, g_odd_pos = 1;
669 b_even_pos = 0, b_odd_pos = 1;
670
671 while (g_even_pos < line_width || g_odd_pos < line_width)
672 {
673 if (g_even_pos < line_width)
674 {
675 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G5] + 1,
676 g_even_pos, info->grad_even[0]);
677 g_even_pos += 2;
678 if ((b_even_pos & 3) == 2)
679 fuji_decode_interpolation_even(line_width, info->linebuf[_B3] + 1,
680 b_even_pos);
681 else
682 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B3] + 1,
683 b_even_pos, info->grad_even[0]);
684 b_even_pos += 2;
685 }
686 if (g_even_pos > 8)
687 {
688 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G5] + 1,
689 g_odd_pos, info->grad_odd[0]);
690 g_odd_pos += 2;
691 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B3] + 1,
692 b_odd_pos, info->grad_odd[0]);
693 b_odd_pos += 2;
694 }
695 }
696
697 fuji_extend_green(info->linebuf, line_width);
698 fuji_extend_blue(info->linebuf, line_width);
699
700 r_even_pos = 0, r_odd_pos = 1;
701 g_even_pos = 0, g_odd_pos = 1;
702
703 while (g_even_pos < line_width || g_odd_pos < line_width)
704 {
705 if (g_even_pos < line_width)
706 {
707 if ((r_even_pos & 3) == 2)
708 fuji_decode_interpolation_even(line_width, info->linebuf[_R4] + 1,
709 r_even_pos);
710 else
711 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R4] + 1,
712 r_even_pos, info->grad_even[1]);
713 r_even_pos += 2;
714 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G6] + 1,
715 g_even_pos, info->grad_even[1]);
716 g_even_pos += 2;
717 }
718 if (g_even_pos > 8)
719 {
720 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R4] + 1,
721 r_odd_pos, info->grad_odd[1]);
722 r_odd_pos += 2;
723 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G6] + 1,
724 g_odd_pos, info->grad_odd[1]);
725 g_odd_pos += 2;
726 }
727 }
728
729 fuji_extend_red(info->linebuf, line_width);
730 fuji_extend_green(info->linebuf, line_width);
731
732 g_even_pos = 0, g_odd_pos = 1;
733 b_even_pos = 0, b_odd_pos = 1;
734
735 while (g_even_pos < line_width || g_odd_pos < line_width)
736 {
737 if (g_even_pos < line_width)
738 {
739 fuji_decode_interpolation_even(line_width, info->linebuf[_G7] + 1,
740 g_even_pos);
741 g_even_pos += 2;
742 if (b_even_pos & 3)
743 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B4] + 1,
744 b_even_pos, info->grad_even[2]);
745 else
746 fuji_decode_interpolation_even(line_width, info->linebuf[_B4] + 1,
747 b_even_pos);
748 b_even_pos += 2;
749 }
750 if (g_even_pos > 8)
751 {
752 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G7] + 1,
753 g_odd_pos, info->grad_odd[2]);
754 g_odd_pos += 2;
755 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B4] + 1,
756 b_odd_pos, info->grad_odd[2]);
757 b_odd_pos += 2;
758 }
759 }
760
761 fuji_extend_green(info->linebuf, line_width);
762 fuji_extend_blue(info->linebuf, line_width);
763
764 if (errcnt)
765 derror();
766 }
767
fuji_bayer_decode_block(struct fuji_compressed_block * info,const struct fuji_compressed_params * params,int cur_line)768 void LibRaw::fuji_bayer_decode_block(
769 struct fuji_compressed_block *info,
770 const struct fuji_compressed_params *params, int cur_line)
771 {
772 int r_even_pos = 0, r_odd_pos = 1;
773 int g_even_pos = 0, g_odd_pos = 1;
774 int b_even_pos = 0, b_odd_pos = 1;
775
776 int errcnt = 0;
777
778 const int line_width = params->line_width;
779
780 while (g_even_pos < line_width || g_odd_pos < line_width)
781 {
782 if (g_even_pos < line_width)
783 {
784 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R2] + 1,
785 r_even_pos, info->grad_even[0]);
786 r_even_pos += 2;
787 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G2] + 1,
788 g_even_pos, info->grad_even[0]);
789 g_even_pos += 2;
790 }
791 if (g_even_pos > 8)
792 {
793 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R2] + 1,
794 r_odd_pos, info->grad_odd[0]);
795 r_odd_pos += 2;
796 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G2] + 1,
797 g_odd_pos, info->grad_odd[0]);
798 g_odd_pos += 2;
799 }
800 }
801
802 fuji_extend_red(info->linebuf, line_width);
803 fuji_extend_green(info->linebuf, line_width);
804
805 g_even_pos = 0, g_odd_pos = 1;
806
807 while (g_even_pos < line_width || g_odd_pos < line_width)
808 {
809 if (g_even_pos < line_width)
810 {
811 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G3] + 1,
812 g_even_pos, info->grad_even[1]);
813 g_even_pos += 2;
814 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B2] + 1,
815 b_even_pos, info->grad_even[1]);
816 b_even_pos += 2;
817 }
818 if (g_even_pos > 8)
819 {
820 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G3] + 1,
821 g_odd_pos, info->grad_odd[1]);
822 g_odd_pos += 2;
823 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B2] + 1,
824 b_odd_pos, info->grad_odd[1]);
825 b_odd_pos += 2;
826 }
827 }
828
829 fuji_extend_green(info->linebuf, line_width);
830 fuji_extend_blue(info->linebuf, line_width);
831
832 r_even_pos = 0, r_odd_pos = 1;
833 g_even_pos = 0, g_odd_pos = 1;
834
835 while (g_even_pos < line_width || g_odd_pos < line_width)
836 {
837 if (g_even_pos < line_width)
838 {
839 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R3] + 1,
840 r_even_pos, info->grad_even[2]);
841 r_even_pos += 2;
842 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G4] + 1,
843 g_even_pos, info->grad_even[2]);
844 g_even_pos += 2;
845 }
846 if (g_even_pos > 8)
847 {
848 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R3] + 1,
849 r_odd_pos, info->grad_odd[2]);
850 r_odd_pos += 2;
851 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G4] + 1,
852 g_odd_pos, info->grad_odd[2]);
853 g_odd_pos += 2;
854 }
855 }
856
857 fuji_extend_red(info->linebuf, line_width);
858 fuji_extend_green(info->linebuf, line_width);
859
860 g_even_pos = 0, g_odd_pos = 1;
861 b_even_pos = 0, b_odd_pos = 1;
862
863 while (g_even_pos < line_width || g_odd_pos < line_width)
864 {
865 if (g_even_pos < line_width)
866 {
867 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G5] + 1,
868 g_even_pos, info->grad_even[0]);
869 g_even_pos += 2;
870 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B3] + 1,
871 b_even_pos, info->grad_even[0]);
872 b_even_pos += 2;
873 }
874 if (g_even_pos > 8)
875 {
876 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G5] + 1,
877 g_odd_pos, info->grad_odd[0]);
878 g_odd_pos += 2;
879 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B3] + 1,
880 b_odd_pos, info->grad_odd[0]);
881 b_odd_pos += 2;
882 }
883 }
884
885 fuji_extend_green(info->linebuf, line_width);
886 fuji_extend_blue(info->linebuf, line_width);
887
888 r_even_pos = 0, r_odd_pos = 1;
889 g_even_pos = 0, g_odd_pos = 1;
890
891 while (g_even_pos < line_width || g_odd_pos < line_width)
892 {
893 if (g_even_pos < line_width)
894 {
895 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R4] + 1,
896 r_even_pos, info->grad_even[1]);
897 r_even_pos += 2;
898 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G6] + 1,
899 g_even_pos, info->grad_even[1]);
900 g_even_pos += 2;
901 }
902 if (g_even_pos > 8)
903 {
904 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R4] + 1,
905 r_odd_pos, info->grad_odd[1]);
906 r_odd_pos += 2;
907 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G6] + 1,
908 g_odd_pos, info->grad_odd[1]);
909 g_odd_pos += 2;
910 }
911 }
912
913 fuji_extend_red(info->linebuf, line_width);
914 fuji_extend_green(info->linebuf, line_width);
915
916 g_even_pos = 0, g_odd_pos = 1;
917 b_even_pos = 0, b_odd_pos = 1;
918
919 while (g_even_pos < line_width || g_odd_pos < line_width)
920 {
921 if (g_even_pos < line_width)
922 {
923 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G7] + 1,
924 g_even_pos, info->grad_even[2]);
925 g_even_pos += 2;
926 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B4] + 1,
927 b_even_pos, info->grad_even[2]);
928 b_even_pos += 2;
929 }
930 if (g_even_pos > 8)
931 {
932 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G7] + 1,
933 g_odd_pos, info->grad_odd[2]);
934 g_odd_pos += 2;
935 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B4] + 1,
936 b_odd_pos, info->grad_odd[2]);
937 b_odd_pos += 2;
938 }
939 }
940
941 fuji_extend_green(info->linebuf, line_width);
942 fuji_extend_blue(info->linebuf, line_width);
943
944 if (errcnt)
945 derror();
946 }
947
fuji_decode_strip(const struct fuji_compressed_params * info_common,int cur_block,INT64 raw_offset,unsigned dsize)948 void LibRaw::fuji_decode_strip(const struct fuji_compressed_params *info_common,
949 int cur_block, INT64 raw_offset, unsigned dsize)
950 {
951 int cur_block_width, cur_line;
952 unsigned line_size;
953 struct fuji_compressed_block info;
954
955 init_fuji_block(&info, info_common, raw_offset, dsize);
956 line_size = sizeof(ushort) * (info_common->line_width + 2);
957
958 cur_block_width = libraw_internal_data.unpacker_data.fuji_block_width;
959 if (cur_block + 1 == libraw_internal_data.unpacker_data.fuji_total_blocks)
960 {
961 cur_block_width =
962 imgdata.sizes.raw_width -
963 (libraw_internal_data.unpacker_data.fuji_block_width * cur_block);
964 /* Old code, may get incorrect results on GFX50, but luckily large optical
965 black cur_block_width = imgdata.sizes.raw_width %
966 libraw_internal_data.unpacker_data.fuji_block_width;
967 */
968 }
969
970 struct i_pair
971 {
972 int a, b;
973 };
974 const i_pair mtable[6] = {{_R0, _R3}, {_R1, _R4}, {_G0, _G6},
975 {_G1, _G7}, {_B0, _B3}, {_B1, _B4}},
976 ztable[3] = {{_R2, 3}, {_G2, 6}, {_B2, 3}};
977 for (cur_line = 0;
978 cur_line < libraw_internal_data.unpacker_data.fuji_total_lines;
979 cur_line++)
980 {
981 if (libraw_internal_data.unpacker_data.fuji_raw_type == 16)
982 xtrans_decode_block(&info, info_common, cur_line);
983 else
984 fuji_bayer_decode_block(&info, info_common, cur_line);
985
986 // copy data from line buffers and advance
987 for (int i = 0; i < 6; i++)
988 memcpy(info.linebuf[mtable[i].a], info.linebuf[mtable[i].b], line_size);
989
990 if (libraw_internal_data.unpacker_data.fuji_raw_type == 16)
991 copy_line_to_xtrans(&info, cur_line, cur_block, cur_block_width);
992 else
993 copy_line_to_bayer(&info, cur_line, cur_block, cur_block_width);
994
995 for (int i = 0; i < 3; i++)
996 {
997 memset(info.linebuf[ztable[i].a], 0, ztable[i].b * line_size);
998 info.linebuf[ztable[i].a][0] = info.linebuf[ztable[i].a - 1][1];
999 info.linebuf[ztable[i].a][info_common->line_width + 1] =
1000 info.linebuf[ztable[i].a - 1][info_common->line_width];
1001 }
1002 }
1003
1004 // release data
1005 free(info.linealloc);
1006 free(info.cur_buf);
1007 }
1008
fuji_compressed_load_raw()1009 void LibRaw::fuji_compressed_load_raw()
1010 {
1011 struct fuji_compressed_params common_info;
1012 int cur_block;
1013 unsigned *block_sizes;
1014 INT64 raw_offset, *raw_block_offsets;
1015 // struct fuji_compressed_block info;
1016
1017 init_fuji_compr(&common_info);
1018
1019 // read block sizes
1020 block_sizes = (unsigned *)malloc(
1021 sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks);
1022 merror(block_sizes, "fuji_compressed_load_raw()");
1023 raw_block_offsets = (INT64 *)malloc(
1024 sizeof(INT64) * libraw_internal_data.unpacker_data.fuji_total_blocks);
1025 merror(raw_block_offsets, "fuji_compressed_load_raw()");
1026
1027 raw_offset =
1028 sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks;
1029 if (raw_offset & 0xC)
1030 raw_offset += 0x10 - (raw_offset & 0xC);
1031
1032 raw_offset += libraw_internal_data.unpacker_data.data_offset;
1033
1034 libraw_internal_data.internal_data.input->seek(
1035 libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
1036 libraw_internal_data.internal_data.input->read(
1037 block_sizes, 1,
1038 sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks);
1039
1040 raw_block_offsets[0] = raw_offset;
1041 // calculating raw block offsets
1042 for (cur_block = 0;
1043 cur_block < libraw_internal_data.unpacker_data.fuji_total_blocks;
1044 cur_block++)
1045 {
1046 unsigned bsize = sgetn(4, (uchar *)(block_sizes + cur_block));
1047 block_sizes[cur_block] = bsize;
1048 }
1049
1050 for (cur_block = 1;
1051 cur_block < libraw_internal_data.unpacker_data.fuji_total_blocks;
1052 cur_block++)
1053 raw_block_offsets[cur_block] =
1054 raw_block_offsets[cur_block - 1] + block_sizes[cur_block - 1];
1055
1056 fuji_decode_loop(&common_info,
1057 libraw_internal_data.unpacker_data.fuji_total_blocks,
1058 raw_block_offsets, block_sizes);
1059
1060 free(block_sizes);
1061 free(raw_block_offsets);
1062 free(common_info.q_table);
1063 }
1064
fuji_decode_loop(const struct fuji_compressed_params * common_info,int count,INT64 * raw_block_offsets,unsigned * block_sizes)1065 void LibRaw::fuji_decode_loop(const struct fuji_compressed_params *common_info,
1066 int count, INT64 *raw_block_offsets,
1067 unsigned *block_sizes)
1068 {
1069 int cur_block;
1070 #ifdef LIBRAW_USE_OPENMP
1071 #pragma omp parallel for private(cur_block)
1072 #endif
1073 for (cur_block = 0; cur_block < count; cur_block++)
1074 {
1075 fuji_decode_strip(common_info, cur_block, raw_block_offsets[cur_block],
1076 block_sizes[cur_block]);
1077 }
1078 }
1079
parse_fuji_compressed_header()1080 void LibRaw::parse_fuji_compressed_header()
1081 {
1082 unsigned signature, version, h_raw_type, h_raw_bits, h_raw_height,
1083 h_raw_rounded_width, h_raw_width, h_block_size, h_blocks_in_row,
1084 h_total_lines;
1085
1086 uchar header[16];
1087
1088 libraw_internal_data.internal_data.input->seek(
1089 libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
1090 libraw_internal_data.internal_data.input->read(header, 1, sizeof(header));
1091
1092 // read all header
1093 signature = sgetn(2, header);
1094 version = header[2];
1095 h_raw_type = header[3];
1096 h_raw_bits = header[4];
1097 h_raw_height = sgetn(2, header + 5);
1098 h_raw_rounded_width = sgetn(2, header + 7);
1099 h_raw_width = sgetn(2, header + 9);
1100 h_block_size = sgetn(2, header + 11);
1101 h_blocks_in_row = header[13];
1102 h_total_lines = sgetn(2, header + 14);
1103
1104 // general validation
1105 if (signature != 0x4953 || version != 1 || h_raw_height > 0x3000 ||
1106 h_raw_height < 6 || h_raw_height % 6 || h_block_size < 1 ||
1107 h_raw_width > 0x3000 || h_raw_width < 0x300 || h_raw_width % 24 ||
1108 h_raw_rounded_width > 0x3000 || h_raw_rounded_width < h_block_size ||
1109 h_raw_rounded_width % h_block_size ||
1110 h_raw_rounded_width - h_raw_width >= h_block_size ||
1111 h_block_size != 0x300 || h_blocks_in_row > 0x10 || h_blocks_in_row == 0 ||
1112 h_blocks_in_row != h_raw_rounded_width / h_block_size ||
1113 h_total_lines > 0x800 || h_total_lines == 0 ||
1114 h_total_lines != h_raw_height / 6 ||
1115 (h_raw_bits != 12 && h_raw_bits != 14 && h_raw_bits != 16) ||
1116 (h_raw_type != 16 && h_raw_type != 0))
1117 return;
1118
1119 // modify data
1120 libraw_internal_data.unpacker_data.fuji_total_lines = h_total_lines;
1121 libraw_internal_data.unpacker_data.fuji_total_blocks = h_blocks_in_row;
1122 libraw_internal_data.unpacker_data.fuji_block_width = h_block_size;
1123 libraw_internal_data.unpacker_data.fuji_bits = h_raw_bits;
1124 libraw_internal_data.unpacker_data.fuji_raw_type = h_raw_type;
1125 imgdata.sizes.raw_width = h_raw_width;
1126 imgdata.sizes.raw_height = h_raw_height;
1127 libraw_internal_data.unpacker_data.data_offset += 16;
1128 load_raw = &LibRaw::fuji_compressed_load_raw;
1129 }
1130
1131 #undef _abs
1132 #undef _min
1133