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