Coverage Report

Created: 2025-08-12 07:37

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