Coverage Report

Created: 2026-06-30 07:12

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