Coverage Report

Created: 2025-09-08 07:52

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