Coverage Report

Created: 2026-05-16 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/decoders/crx.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * File: crx.cpp
3
 * Copyright (C) 2018-2019 Alexey Danilchenko
4
 * Copyright (C) 2019 Alex Tutubalin, LibRaw LLC
5
 *
6
   Canon CR3 file 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 _constrain
25
#endif
26
0
#define _abs(x) (((x) ^ ((int32_t)(x) >> 31)) - ((int32_t)(x) >> 31))
27
0
#define _min(a, b) ((a) < (b) ? (a) : (b))
28
0
#define _constrain(x, l, u) ((x) < (l) ? (l) : ((x) > (u) ? (u) : (x)))
29
30
#if defined(__clang__) || defined(__GNUG__)
31
#define libraw_inline inline __attribute__((always_inline))
32
#elif defined(_MSC_VER) && _MSC_VER > 1400
33
#define libraw_inline __forceinline
34
#else
35
#define libraw_inline inline
36
#endif
37
38
// this should be divisible by 4
39
#define CRX_BUF_SIZE 0x10000
40
#if !defined(_WIN32) || (defined(__GNUC__) && !defined(__INTRINSIC_SPECIAL__BitScanReverse))
41
/* __INTRINSIC_SPECIAL__BitScanReverse found in MinGW32-W64 v7.30 headers, may be there is a better solution? */
42
typedef uint32_t DWORD;
43
libraw_inline void _BitScanReverse(DWORD *Index, unsigned long Mask)
44
0
{
45
0
  *Index = sizeof(unsigned long) * 8 - 1 - __builtin_clzl(Mask);
46
0
}
47
#if LibRawBigEndian
48
#define _byteswap_ulong(x) (x)
49
#else
50
0
#define _byteswap_ulong(x) __builtin_bswap32(x)
51
#endif
52
#endif
53
54
struct CrxBitstream
55
{
56
  uint8_t mdatBuf[CRX_BUF_SIZE];
57
  INT64 mdatSize;
58
  INT64 curBufOffset;
59
  uint32_t curPos;
60
  uint32_t curBufSize;
61
  uint32_t bitData;
62
  int32_t bitsLeft;
63
  LibRaw_abstract_datastream *input;
64
};
65
66
struct CrxBandParam
67
{
68
  CrxBitstream bitStream;
69
  int16_t subbandWidth;
70
  int16_t subbandHeight;
71
  int32_t roundedBitsMask;
72
  int32_t roundedBits;
73
  int16_t curLine;
74
  int32_t *lineBuf0;
75
  int32_t *lineBuf1;
76
  int32_t *lineBuf2;
77
  int32_t sParam;
78
  int32_t kParam;
79
  int32_t *paramData;
80
  int32_t *nonProgrData;
81
  bool supportsPartial;
82
};
83
84
struct CrxWaveletTransform
85
{
86
  int32_t *subband0Buf;
87
  int32_t *subband1Buf;
88
  int32_t *subband2Buf;
89
  int32_t *subband3Buf;
90
  int32_t *lineBuf[8];
91
  int16_t curLine;
92
  int16_t curH;
93
  int8_t fltTapH;
94
  int16_t height;
95
  int16_t width;
96
};
97
98
struct CrxSubband
99
{
100
  CrxBandParam *bandParam;
101
  INT64 mdatOffset;
102
  uint8_t *bandBuf;
103
  uint16_t width;
104
  uint16_t height;
105
  int32_t qParam;
106
  int32_t kParam;
107
  int32_t qStepBase;
108
  uint32_t qStepMult;
109
  bool supportsPartial;
110
  int32_t bandSize;
111
  INT64 dataSize;
112
  INT64 dataOffset;
113
  short rowStartAddOn;
114
  short rowEndAddOn;
115
  short colStartAddOn;
116
  short colEndAddOn;
117
  short levelShift;
118
};
119
120
struct CrxPlaneComp
121
{
122
  uint8_t *compBuf;
123
  CrxSubband *subBands;
124
  CrxWaveletTransform *wvltTransform;
125
  int8_t compNumber;
126
  INT64 dataOffset;
127
  int32_t compSize;
128
  bool supportsPartial;
129
  int32_t roundedBitsMask;
130
  int8_t tileFlag;
131
};
132
133
struct CrxQStep
134
{
135
  uint32_t *qStepTbl;
136
  int width;
137
  int height;
138
};
139
140
struct CrxTile
141
{
142
  CrxPlaneComp *comps;
143
  int8_t tileFlag;
144
  int8_t tileNumber;
145
  int64_t dataOffset;
146
  int32_t tileSize;
147
  uint16_t width;
148
  uint16_t height;
149
  bool hasQPData;
150
  CrxQStep *qStep;
151
  uint32_t mdatQPDataSize;
152
  uint16_t mdatExtraSize;
153
};
154
155
struct CrxImage
156
{
157
  uint8_t nPlanes;
158
  uint16_t planeWidth;
159
  uint16_t planeHeight;
160
  uint8_t samplePrecision;
161
  uint8_t medianBits;
162
  uint8_t subbandCount;
163
  uint8_t levels;
164
  uint8_t nBits;
165
  uint8_t encType;
166
  uint8_t tileCols;
167
  uint8_t tileRows;
168
  CrxTile *tiles;
169
  uint64_t mdatOffset;
170
  uint64_t mdatSize;
171
  int16_t *outBufs[4]; // one per plane
172
  int16_t *planeBuf;
173
  LibRaw_abstract_datastream *input;
174
#ifdef LIBRAW_CR3_MEMPOOL
175
  libraw_memmgr memmgr;
176
0
  CrxImage() : memmgr(0) {}
177
#endif
178
};
179
180
enum TileFlags
181
{
182
  E_HAS_TILES_ON_THE_RIGHT = 1,
183
  E_HAS_TILES_ON_THE_LEFT = 2,
184
  E_HAS_TILES_ON_THE_BOTTOM = 4,
185
  E_HAS_TILES_ON_THE_TOP = 8
186
};
187
188
int32_t exCoefNumTbl[144] = {1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
189
                             0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0,
190
                             0, 0, 1, 2, 2, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 2,
191
                             1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 1, 1, 1,
192
                             1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1};
193
194
int32_t q_step_tbl[8] = {0x28, 0x2D, 0x33, 0x39, 0x40, 0x48};
195
196
uint32_t JS[32] = {1,    1,    1,     1,     2,     2,     2,      2,      4,      4,     4,
197
                   4,    8,    8,     8,     8,     0x10,  0x10,   0x20,   0x20,   0x40,  0x40,
198
                   0x80, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000};
199
200
uint32_t J[32] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,    2,    3,    3,    3,    3,
201
                  4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
202
203
static inline void crxFillBuffer(CrxBitstream *bitStrm)
204
0
{
205
0
  if (bitStrm->curPos >= bitStrm->curBufSize && bitStrm->mdatSize)
206
0
  {
207
0
    bitStrm->curPos = 0;
208
0
    bitStrm->curBufOffset += bitStrm->curBufSize;
209
#ifdef LIBRAW_USE_OPENMP
210
#pragma omp critical
211
#endif
212
0
    {
213
0
#ifndef LIBRAW_USE_OPENMP
214
0
      bitStrm->input->lock();
215
0
#endif
216
0
      bitStrm->input->seek(bitStrm->curBufOffset, SEEK_SET);
217
0
      bitStrm->curBufSize = bitStrm->input->read(bitStrm->mdatBuf, 1, _min(bitStrm->mdatSize, CRX_BUF_SIZE));
218
0
#ifndef LIBRAW_USE_OPENMP
219
0
      bitStrm->input->unlock();
220
0
#endif
221
0
    }
222
0
    if (bitStrm->curBufSize < 1) // nothing read
223
0
      throw LIBRAW_EXCEPTION_IO_EOF;
224
0
    bitStrm->mdatSize -= bitStrm->curBufSize;
225
0
  }
226
0
}
227
228
libraw_inline int crxBitstreamGetZeros(CrxBitstream *bitStrm)
229
0
{
230
0
  uint32_t nonZeroBit = 0;
231
0
  uint64_t nextData = 0;
232
0
  int32_t result = 0;
233
234
0
  if (bitStrm->bitData)
235
0
  {
236
0
    _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)bitStrm->bitData);
237
0
    result = 31 - nonZeroBit;
238
0
    bitStrm->bitData <<= 32 - nonZeroBit;
239
0
    bitStrm->bitsLeft -= 32 - nonZeroBit;
240
0
  }
241
0
  else
242
0
  {
243
0
    uint32_t bitsLeft = bitStrm->bitsLeft;
244
0
    while (1)
245
0
    {
246
0
      while (bitStrm->curPos + 4 <= bitStrm->curBufSize)
247
0
      {
248
0
        nextData = _byteswap_ulong(*(uint32_t *)(bitStrm->mdatBuf + bitStrm->curPos));
249
0
        bitStrm->curPos += 4;
250
0
        crxFillBuffer(bitStrm);
251
0
        if (nextData)
252
0
        {
253
0
          _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)nextData);
254
0
          result = bitsLeft + 31 - nonZeroBit;
255
0
          bitStrm->bitData = uint32_t((nextData << (32 - nonZeroBit))&0xffffffffu);
256
0
          bitStrm->bitsLeft = nonZeroBit;
257
0
          return result;
258
0
        }
259
0
        bitsLeft += 32;
260
0
      }
261
0
      if (bitStrm->curBufSize < bitStrm->curPos + 1)
262
0
        break; // error
263
0
      nextData = bitStrm->mdatBuf[bitStrm->curPos++];
264
0
      crxFillBuffer(bitStrm);
265
0
      if (nextData)
266
0
        break;
267
0
      bitsLeft += 8;
268
0
    }
269
0
    _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)nextData);
270
0
    result = (uint32_t)(bitsLeft + 7 - nonZeroBit);
271
0
    bitStrm->bitData = uint32_t((nextData << (32 - nonZeroBit)) & 0xffffffffu);
272
0
    bitStrm->bitsLeft = nonZeroBit;
273
0
  }
274
0
  return result;
275
0
}
276
277
libraw_inline uint32_t crxBitstreamGetBits(CrxBitstream *bitStrm, int bits)
278
0
{
279
0
  int bitsLeft = bitStrm->bitsLeft;
280
0
  uint32_t bitData = bitStrm->bitData;
281
0
  uint32_t nextWord;
282
0
  uint8_t nextByte;
283
0
  uint32_t result;
284
285
0
  if (bitsLeft < bits)
286
0
  {
287
    // get them from stream
288
0
    if (bitStrm->curPos + 4 <= bitStrm->curBufSize)
289
0
    {
290
0
      nextWord = _byteswap_ulong(*(uint32_t *)(bitStrm->mdatBuf + bitStrm->curPos));
291
0
      bitStrm->curPos += 4;
292
0
      crxFillBuffer(bitStrm);
293
0
      bitStrm->bitsLeft = 32 - (bits - bitsLeft);
294
0
      result = ((nextWord >> bitsLeft) | bitData) >> (32 - bits);
295
0
      bitStrm->bitData = nextWord << (bits - bitsLeft);
296
0
      return result;
297
0
    }
298
    // less than a word left - read byte at a time
299
0
    do
300
0
    {
301
0
      if (bitStrm->curPos >= bitStrm->curBufSize)
302
0
        break; // error
303
0
      bitsLeft += 8;
304
0
      nextByte = bitStrm->mdatBuf[bitStrm->curPos++];
305
0
      crxFillBuffer(bitStrm);
306
0
      bitData |= nextByte << (32 - bitsLeft);
307
0
    } while (bitsLeft < bits);
308
0
  }
309
0
  result = bitData >> (32 - bits); // 32-bits
310
0
  bitStrm->bitData = bitData << bits;
311
0
  bitStrm->bitsLeft = bitsLeft - bits;
312
0
  return result;
313
0
}
314
315
libraw_inline int32_t crxPrediction(int32_t left, int32_t top, int32_t deltaH, int32_t deltaV)
316
0
{
317
0
  int32_t symb[4] = {left + deltaH, left + deltaH, left, top};
318
319
0
  return symb[(((deltaV < 0) ^ (deltaH < 0)) << 1) + ((left < top) ^ (deltaH < 0))];
320
0
}
321
322
libraw_inline int32_t crxPredictKParameter(int32_t prevK, int32_t bitCode, int32_t maxVal = 0)
323
0
{
324
0
  int32_t newKParam = prevK - (bitCode < (1 << prevK >> 1)) + ((bitCode >> prevK) > 2) + ((bitCode >> prevK) > 5);
325
326
0
  return !maxVal || newKParam < maxVal ? newKParam : maxVal;
327
0
}
328
329
libraw_inline void crxDecodeSymbolL1(CrxBandParam *param, int32_t doMedianPrediction, int32_t notEOL = 0)
330
0
{
331
0
  if (doMedianPrediction)
332
0
  {
333
0
    int32_t symb[4];
334
335
0
    int32_t delta = param->lineBuf0[1] - param->lineBuf0[0];
336
0
    symb[2] = param->lineBuf1[0];
337
0
    symb[0] = symb[1] = delta + symb[2];
338
0
    symb[3] = param->lineBuf0[1];
339
340
0
    param->lineBuf1[1] = symb[(((param->lineBuf0[0] < param->lineBuf1[0]) ^ (delta < 0)) << 1) +
341
0
                              ((param->lineBuf1[0] < param->lineBuf0[1]) ^ (delta < 0))];
342
0
  }
343
0
  else
344
0
    param->lineBuf1[1] = param->lineBuf0[1];
345
346
  // get next error symbol
347
0
  uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
348
0
  if (bitCode >= 41)
349
0
    bitCode = crxBitstreamGetBits(&param->bitStream, 21);
350
0
  else if (param->kParam)
351
0
    bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
352
353
  // add converted (+/-) error code to predicted value
354
0
  param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
355
356
  // for not end of the line - use one symbol ahead to estimate next K
357
0
  if (notEOL)
358
0
  {
359
0
    int32_t nextDelta = (param->lineBuf0[2] - param->lineBuf0[1]) << 1;
360
0
    bitCode = (bitCode + _abs(nextDelta)) >> 1;
361
0
    ++param->lineBuf0;
362
0
  }
363
364
  // update K parameter
365
0
  param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
366
367
0
  ++param->lineBuf1;
368
0
}
369
370
int crxDecodeLine(CrxBandParam *param)
371
0
{
372
0
  int length = param->subbandWidth;
373
374
0
  param->lineBuf1[0] = param->lineBuf0[1];
375
0
  for (; length > 1; --length)
376
0
  {
377
0
    if (param->lineBuf1[0] != param->lineBuf0[1] || param->lineBuf1[0] != param->lineBuf0[2])
378
0
    {
379
0
      crxDecodeSymbolL1(param, 1, 1);
380
0
    }
381
0
    else
382
0
    {
383
0
      int nSyms = 0;
384
0
      if (crxBitstreamGetBits(&param->bitStream, 1))
385
0
      {
386
0
        nSyms = 1;
387
0
        while (crxBitstreamGetBits(&param->bitStream, 1))
388
0
        {
389
0
          nSyms += JS[param->sParam];
390
0
          if (nSyms > length)
391
0
          {
392
0
            nSyms = length;
393
0
            break;
394
0
          }
395
0
          if (param->sParam < 31)
396
0
            ++param->sParam;
397
0
          if (nSyms == length)
398
0
            break;
399
0
        }
400
401
0
        if (nSyms < length)
402
0
        {
403
0
          if (J[param->sParam])
404
0
            nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
405
0
          if (param->sParam > 0)
406
0
            --param->sParam;
407
0
          if (nSyms > length)
408
0
            return -1;
409
0
        }
410
411
0
        length -= nSyms;
412
413
        // copy symbol nSyms times
414
0
        param->lineBuf0 += nSyms;
415
416
        // copy symbol nSyms times
417
0
        while (nSyms-- > 0)
418
0
        {
419
0
          param->lineBuf1[1] = param->lineBuf1[0];
420
0
          ++param->lineBuf1;
421
0
        }
422
0
      }
423
424
0
      if (length > 0)
425
0
        crxDecodeSymbolL1(param, 0, (length > 1));
426
0
    }
427
0
  }
428
429
0
  if (length == 1)
430
0
    crxDecodeSymbolL1(param, 1, 0);
431
432
0
  param->lineBuf1[1] = param->lineBuf1[0] + 1;
433
434
0
  return 0;
435
0
}
436
437
libraw_inline void crxDecodeSymbolL1Rounded(CrxBandParam *param, int32_t doSym = 1, int32_t doCode = 1)
438
0
{
439
0
  int32_t sym = param->lineBuf0[1];
440
441
0
  if (doSym)
442
0
  {
443
    // calculate the next symbol gradient
444
0
    int32_t symb[4];
445
0
    int32_t deltaH = param->lineBuf0[1] - param->lineBuf0[0];
446
0
    symb[2] = param->lineBuf1[0];
447
0
    symb[0] = symb[1] = deltaH + symb[2];
448
0
    symb[3] = param->lineBuf0[1];
449
0
    sym = symb[(((param->lineBuf0[0] < param->lineBuf1[0]) ^ (deltaH < 0)) << 1) +
450
0
               ((param->lineBuf1[0] < param->lineBuf0[1]) ^ (deltaH < 0))];
451
0
  }
452
453
0
  uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
454
0
  if (bitCode >= 41)
455
0
    bitCode = crxBitstreamGetBits(&param->bitStream, 21);
456
0
  else if (param->kParam)
457
0
    bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
458
0
  int32_t code = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
459
0
  param->lineBuf1[1] = param->roundedBitsMask * 2 * code + (code >> 31) + sym;
460
461
0
  if (doCode)
462
0
  {
463
0
    if (param->lineBuf0[2] > param->lineBuf0[1])
464
0
      code = (param->lineBuf0[2] - param->lineBuf0[1] + param->roundedBitsMask - 1) >> param->roundedBits;
465
0
    else
466
0
      code = -((param->lineBuf0[1] - param->lineBuf0[2] + param->roundedBitsMask) >> param->roundedBits);
467
468
0
    param->kParam = crxPredictKParameter(param->kParam, (bitCode + 2 * _abs(code)) >> 1, 15);
469
0
  }
470
0
  else
471
0
    param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
472
473
0
  ++param->lineBuf1;
474
0
}
475
476
int crxDecodeLineRounded(CrxBandParam *param)
477
0
{
478
0
  int32_t valueReached = 0;
479
480
0
  param->lineBuf0[0] = param->lineBuf0[1];
481
0
  param->lineBuf1[0] = param->lineBuf0[1];
482
0
  int32_t length = param->subbandWidth;
483
484
0
  for (; length > 1; --length)
485
0
  {
486
0
    if (_abs(param->lineBuf0[2] - param->lineBuf0[1]) > param->roundedBitsMask)
487
0
    {
488
0
      crxDecodeSymbolL1Rounded(param);
489
0
      ++param->lineBuf0;
490
0
      valueReached = 1;
491
0
    }
492
0
    else if (valueReached || _abs(param->lineBuf0[0] - param->lineBuf1[0]) > param->roundedBitsMask)
493
0
    {
494
0
      crxDecodeSymbolL1Rounded(param);
495
0
      ++param->lineBuf0;
496
0
      valueReached = 0;
497
0
    }
498
0
    else
499
0
    {
500
0
      int nSyms = 0;
501
0
      if (crxBitstreamGetBits(&param->bitStream, 1))
502
0
      {
503
0
        nSyms = 1;
504
0
        while (crxBitstreamGetBits(&param->bitStream, 1))
505
0
        {
506
0
          nSyms += JS[param->sParam];
507
0
          if (nSyms > length)
508
0
          {
509
0
            nSyms = length;
510
0
            break;
511
0
          }
512
0
          if (param->sParam < 31)
513
0
            ++param->sParam;
514
0
          if (nSyms == length)
515
0
            break;
516
0
        }
517
0
        if (nSyms < length)
518
0
        {
519
0
          if (J[param->sParam])
520
0
            nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
521
0
          if (param->sParam > 0)
522
0
            --param->sParam;
523
0
        }
524
0
        if (nSyms > length)
525
0
          return -1;
526
0
      }
527
0
      length -= nSyms;
528
529
      // copy symbol nSyms times
530
0
      param->lineBuf0 += nSyms;
531
532
      // copy symbol nSyms times
533
0
      while (nSyms-- > 0)
534
0
      {
535
0
        param->lineBuf1[1] = param->lineBuf1[0];
536
0
        ++param->lineBuf1;
537
0
      }
538
539
0
      if (length > 1)
540
0
      {
541
0
        crxDecodeSymbolL1Rounded(param, 0);
542
0
        ++param->lineBuf0;
543
0
        valueReached = _abs(param->lineBuf0[1] - param->lineBuf0[0]) > param->roundedBitsMask;
544
0
      }
545
0
      else if (length == 1)
546
0
        crxDecodeSymbolL1Rounded(param, 0, 0);
547
0
    }
548
0
  }
549
0
  if (length == 1)
550
0
    crxDecodeSymbolL1Rounded(param, 1, 0);
551
552
0
  param->lineBuf1[1] = param->lineBuf1[0] + 1;
553
554
0
  return 0;
555
0
}
556
557
int crxDecodeLineNoRefPrevLine(CrxBandParam *param)
558
0
{
559
0
  int32_t i = 0;
560
561
0
  for (; i < param->subbandWidth - 1; i++)
562
0
  {
563
0
    if (param->lineBuf0[i + 2] | param->lineBuf0[i + 1] | param->lineBuf1[i])
564
0
    {
565
0
      uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
566
0
      if (bitCode >= 41)
567
0
        bitCode = crxBitstreamGetBits(&param->bitStream, 21);
568
0
      else if (param->kParam)
569
0
        bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
570
0
      param->lineBuf1[i + 1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
571
0
      param->kParam = crxPredictKParameter(param->kParam, bitCode);
572
0
      if (param->lineBuf2[i + 1] - param->kParam <= 1)
573
0
      {
574
0
        if (param->kParam >= 15)
575
0
          param->kParam = 15;
576
0
      }
577
0
      else
578
0
        ++param->kParam;
579
0
    }
580
0
    else
581
0
    {
582
0
      int nSyms = 0;
583
0
      if (crxBitstreamGetBits(&param->bitStream, 1))
584
0
      {
585
0
        nSyms = 1;
586
0
        if (i != param->subbandWidth - 1)
587
0
        {
588
0
          while (crxBitstreamGetBits(&param->bitStream, 1))
589
0
          {
590
0
            nSyms += JS[param->sParam];
591
0
            if (i + nSyms > param->subbandWidth)
592
0
            {
593
0
              nSyms = param->subbandWidth - i;
594
0
              break;
595
0
            }
596
0
            if (param->sParam < 31)
597
0
              ++param->sParam;
598
0
            if (i + nSyms == param->subbandWidth)
599
0
              break;
600
0
          }
601
0
          if (i + nSyms < param->subbandWidth)
602
0
          {
603
0
            if (J[param->sParam])
604
0
              nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
605
0
            if (param->sParam > 0)
606
0
              --param->sParam;
607
0
          }
608
0
          if (i + nSyms > param->subbandWidth)
609
0
            return -1;
610
0
        }
611
0
      }
612
0
      else if (i > param->subbandWidth)
613
0
        return -1;
614
615
0
      if (nSyms > 0)
616
0
      {
617
0
        memset(param->lineBuf1 + i + 1, 0, nSyms * sizeof(int32_t));
618
0
        memset(param->lineBuf2 + i, 0, nSyms * sizeof(int32_t));
619
0
        i += nSyms;
620
0
      }
621
622
0
      if (i >= param->subbandWidth - 1)
623
0
      {
624
0
        if (i == param->subbandWidth - 1)
625
0
        {
626
0
          uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
627
0
          if (bitCode >= 41)
628
0
            bitCode = crxBitstreamGetBits(&param->bitStream, 21);
629
0
          else if (param->kParam)
630
0
            bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
631
0
          param->lineBuf1[i + 1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1);
632
0
          param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
633
0
          param->lineBuf2[i] = param->kParam;
634
0
        }
635
0
        continue;
636
0
      }
637
0
      else
638
0
      {
639
0
        uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
640
0
        if (bitCode >= 41)
641
0
          bitCode = crxBitstreamGetBits(&param->bitStream, 21);
642
0
        else if (param->kParam)
643
0
          bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
644
0
        param->lineBuf1[i + 1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1);
645
0
        param->kParam = crxPredictKParameter(param->kParam, bitCode);
646
0
        if (param->lineBuf2[i + 1] - param->kParam <= 1)
647
0
        {
648
0
          if (param->kParam >= 15)
649
0
            param->kParam = 15;
650
0
        }
651
0
        else
652
0
          ++param->kParam;
653
0
      }
654
0
    }
655
0
    param->lineBuf2[i] = param->kParam;
656
0
  }
657
0
  if (i == param->subbandWidth - 1)
658
0
  {
659
0
    int32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
660
0
    if (bitCode >= 41)
661
0
      bitCode = crxBitstreamGetBits(&param->bitStream, 21);
662
0
    else if (param->kParam)
663
0
      bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
664
0
    param->lineBuf1[i + 1] = -(bitCode & 1) ^ (bitCode >> 1);
665
0
    param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
666
0
    param->lineBuf2[i] = param->kParam;
667
0
  }
668
669
0
  return 0;
670
0
}
671
672
int crxDecodeTopLine(CrxBandParam *param)
673
0
{
674
0
  param->lineBuf1[0] = 0;
675
676
0
  int32_t length = param->subbandWidth;
677
678
  // read the line from bitstream
679
0
  for (; length > 1; --length)
680
0
  {
681
0
    if (param->lineBuf1[0])
682
0
      param->lineBuf1[1] = param->lineBuf1[0];
683
0
    else
684
0
    {
685
0
      int nSyms = 0;
686
0
      if (crxBitstreamGetBits(&param->bitStream, 1))
687
0
      {
688
0
        nSyms = 1;
689
0
        while (crxBitstreamGetBits(&param->bitStream, 1))
690
0
        {
691
0
          nSyms += JS[param->sParam];
692
0
          if (nSyms > length)
693
0
          {
694
0
            nSyms = length;
695
0
            break;
696
0
          }
697
0
          if (param->sParam < 31)
698
0
            ++param->sParam;
699
0
          if (nSyms == length)
700
0
            break;
701
0
        }
702
0
        if (nSyms < length)
703
0
        {
704
0
          if (J[param->sParam])
705
0
            nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
706
0
          if (param->sParam > 0)
707
0
            --param->sParam;
708
0
          if (nSyms > length)
709
0
            return -1;
710
0
        }
711
712
0
        length -= nSyms;
713
714
        // copy symbol nSyms times
715
0
        while (nSyms-- > 0)
716
0
        {
717
0
          param->lineBuf1[1] = param->lineBuf1[0];
718
0
          ++param->lineBuf1;
719
0
        }
720
721
0
        if (length <= 0)
722
0
          break;
723
0
      }
724
725
0
      param->lineBuf1[1] = 0;
726
0
    }
727
728
0
    uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
729
0
    if (bitCode >= 41)
730
0
      bitCode = crxBitstreamGetBits(&param->bitStream, 21);
731
0
    else if (param->kParam)
732
0
      bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
733
0
    param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
734
0
    param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
735
0
    ++param->lineBuf1;
736
0
  }
737
738
0
  if (length == 1)
739
0
  {
740
0
    param->lineBuf1[1] = param->lineBuf1[0];
741
0
    uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
742
0
    if (bitCode >= 41)
743
0
      bitCode = crxBitstreamGetBits(&param->bitStream, 21);
744
0
    else if (param->kParam)
745
0
      bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
746
0
    param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
747
0
    param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
748
0
    ++param->lineBuf1;
749
0
  }
750
751
0
  param->lineBuf1[1] = param->lineBuf1[0] + 1;
752
753
0
  return 0;
754
0
}
755
756
int crxDecodeTopLineRounded(CrxBandParam *param)
757
0
{
758
0
  param->lineBuf1[0] = 0;
759
760
0
  int32_t length = param->subbandWidth;
761
762
  // read the line from bitstream
763
0
  for (; length > 1; --length)
764
0
  {
765
0
    if (_abs(param->lineBuf1[0]) > param->roundedBitsMask)
766
0
      param->lineBuf1[1] = param->lineBuf1[0];
767
0
    else
768
0
    {
769
0
      int nSyms = 0;
770
0
      if (crxBitstreamGetBits(&param->bitStream, 1))
771
0
      {
772
0
        nSyms = 1;
773
0
        while (crxBitstreamGetBits(&param->bitStream, 1))
774
0
        {
775
0
          nSyms += JS[param->sParam];
776
0
          if (nSyms > length)
777
0
          {
778
0
            nSyms = length;
779
0
            break;
780
0
          }
781
0
          if (param->sParam < 31)
782
0
            ++param->sParam;
783
0
          if (nSyms == length)
784
0
            break;
785
0
        }
786
0
        if (nSyms < length)
787
0
        {
788
0
          if (J[param->sParam])
789
0
            nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
790
0
          if (param->sParam > 0)
791
0
            --param->sParam;
792
0
          if (nSyms > length)
793
0
            return -1;
794
0
        }
795
0
      }
796
797
0
      length -= nSyms;
798
799
      // copy symbol nSyms times
800
0
      while (nSyms-- > 0)
801
0
      {
802
0
        param->lineBuf1[1] = param->lineBuf1[0];
803
0
        ++param->lineBuf1;
804
0
      }
805
806
0
      if (length <= 0)
807
0
        break;
808
809
0
      param->lineBuf1[1] = 0;
810
0
    }
811
812
0
    uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
813
0
    if (bitCode >= 41)
814
0
      bitCode = crxBitstreamGetBits(&param->bitStream, 21);
815
0
    else if (param->kParam)
816
0
      bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
817
818
0
    int32_t sVal = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
819
0
    param->lineBuf1[1] += param->roundedBitsMask * 2 * sVal + (sVal >> 31);
820
0
    param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
821
0
    ++param->lineBuf1;
822
0
  }
823
824
0
  if (length == 1)
825
0
  {
826
0
    uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
827
0
    if (bitCode >= 41)
828
0
      bitCode = crxBitstreamGetBits(&param->bitStream, 21);
829
0
    else if (param->kParam)
830
0
      bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
831
0
    int32_t sVal = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
832
0
    param->lineBuf1[1] += param->roundedBitsMask * 2 * sVal + (sVal >> 31);
833
0
    param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
834
0
    ++param->lineBuf1;
835
0
  }
836
837
0
  param->lineBuf1[1] = param->lineBuf1[0] + 1;
838
839
0
  return 0;
840
0
}
841
842
int crxDecodeTopLineNoRefPrevLine(CrxBandParam *param)
843
0
{
844
0
  param->lineBuf0[0] = 0;
845
0
  param->lineBuf1[0] = 0;
846
0
  int32_t length = param->subbandWidth;
847
0
  for (; length > 1; --length)
848
0
  {
849
0
    if (param->lineBuf1[0])
850
0
    {
851
0
      uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
852
0
      if (bitCode >= 41)
853
0
        bitCode = crxBitstreamGetBits(&param->bitStream, 21);
854
0
      else if (param->kParam)
855
0
        bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
856
0
      param->lineBuf1[1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
857
0
      param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
858
0
    }
859
0
    else
860
0
    {
861
0
      int nSyms = 0;
862
0
      if (crxBitstreamGetBits(&param->bitStream, 1))
863
0
      {
864
0
        nSyms = 1;
865
0
        while (crxBitstreamGetBits(&param->bitStream, 1))
866
0
        {
867
0
          nSyms += JS[param->sParam];
868
0
          if (nSyms > length)
869
0
          {
870
0
            nSyms = length;
871
0
            break;
872
0
          }
873
0
          if (param->sParam < 31)
874
0
            ++param->sParam;
875
0
          if (nSyms == length)
876
0
            break;
877
0
        }
878
0
        if (nSyms < length)
879
0
        {
880
0
          if (J[param->sParam])
881
0
            nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
882
0
          if (param->sParam > 0)
883
0
            --param->sParam;
884
0
          if (nSyms > length)
885
0
            return -1;
886
0
        }
887
0
      }
888
889
0
      length -= nSyms;
890
891
      // copy symbol nSyms times
892
0
      while (nSyms-- > 0)
893
0
      {
894
0
        param->lineBuf2[0] = 0;
895
0
        param->lineBuf1[1] = 0;
896
0
        ++param->lineBuf1;
897
0
        ++param->lineBuf2;
898
0
      }
899
900
0
      if (length <= 0)
901
0
        break;
902
0
      uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
903
0
      if (bitCode >= 41)
904
0
        bitCode = crxBitstreamGetBits(&param->bitStream, 21);
905
0
      else if (param->kParam)
906
0
        bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
907
0
      param->lineBuf1[1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1);
908
0
      param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
909
0
    }
910
0
    param->lineBuf2[0] = param->kParam;
911
0
    ++param->lineBuf2;
912
0
    ++param->lineBuf1;
913
0
  }
914
915
0
  if (length == 1)
916
0
  {
917
0
    uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
918
0
    if (bitCode >= 41)
919
0
      bitCode = crxBitstreamGetBits(&param->bitStream, 21);
920
0
    else if (param->kParam)
921
0
      bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
922
0
    param->lineBuf1[1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
923
0
    param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
924
0
    param->lineBuf2[0] = param->kParam;
925
0
    ++param->lineBuf1;
926
0
  }
927
928
0
  param->lineBuf1[1] = 0;
929
930
0
  return 0;
931
0
}
932
933
int crxDecodeLine(CrxBandParam *param, uint8_t *bandBuf)
934
0
{
935
0
  if (!param || !bandBuf)
936
0
    return -1;
937
0
  if (param->curLine >= param->subbandHeight)
938
0
    return -1;
939
940
0
  if (param->curLine == 0)
941
0
  {
942
0
    int32_t lineLength = param->subbandWidth + 2;
943
944
0
    param->sParam = 0;
945
0
    param->kParam = 0;
946
0
    if (param->supportsPartial)
947
0
    {
948
0
      if (param->roundedBitsMask <= 0)
949
0
      {
950
0
        param->lineBuf0 = (int32_t *)param->paramData;
951
0
        param->lineBuf1 = param->lineBuf0 + lineLength;
952
0
        int32_t *lineBuf = param->lineBuf1 + 1;
953
0
        if (crxDecodeTopLine(param))
954
0
          return -1;
955
0
        memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
956
0
        ++param->curLine;
957
0
      }
958
0
      else
959
0
      {
960
0
        param->roundedBits = 1;
961
0
        if (param->roundedBitsMask & ~1)
962
0
        {
963
0
          while (param->roundedBitsMask >> param->roundedBits)
964
0
            ++param->roundedBits;
965
0
        }
966
0
        param->lineBuf0 = (int32_t *)param->paramData;
967
0
        param->lineBuf1 = param->lineBuf0 + lineLength;
968
0
        int32_t *lineBuf = param->lineBuf1 + 1;
969
0
        if (crxDecodeTopLineRounded(param))
970
0
          return -1;
971
0
        memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
972
0
        ++param->curLine;
973
0
      }
974
0
    }
975
0
    else
976
0
    {
977
0
      param->lineBuf2 = (int32_t *)param->nonProgrData;
978
0
      param->lineBuf0 = (int32_t *)param->paramData;
979
0
      param->lineBuf1 = param->lineBuf0 + lineLength;
980
0
      int32_t *lineBuf = param->lineBuf1 + 1;
981
0
      if (crxDecodeTopLineNoRefPrevLine(param))
982
0
        return -1;
983
0
      memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
984
0
      ++param->curLine;
985
0
    }
986
0
  }
987
0
  else if (!param->supportsPartial)
988
0
  {
989
0
    int32_t lineLength = param->subbandWidth + 2;
990
0
    param->lineBuf2 = (int32_t *)param->nonProgrData;
991
0
    if (param->curLine & 1)
992
0
    {
993
0
      param->lineBuf1 = (int32_t *)param->paramData;
994
0
      param->lineBuf0 = param->lineBuf1 + lineLength;
995
0
    }
996
0
    else
997
0
    {
998
0
      param->lineBuf0 = (int32_t *)param->paramData;
999
0
      param->lineBuf1 = param->lineBuf0 + lineLength;
1000
0
    }
1001
0
    int32_t *lineBuf = param->lineBuf1 + 1;
1002
0
    if (crxDecodeLineNoRefPrevLine(param))
1003
0
      return -1;
1004
0
    memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
1005
0
    ++param->curLine;
1006
0
  }
1007
0
  else if (param->roundedBitsMask <= 0)
1008
0
  {
1009
0
    int32_t lineLength = param->subbandWidth + 2;
1010
0
    if (param->curLine & 1)
1011
0
    {
1012
0
      param->lineBuf1 = (int32_t *)param->paramData;
1013
0
      param->lineBuf0 = param->lineBuf1 + lineLength;
1014
0
    }
1015
0
    else
1016
0
    {
1017
0
      param->lineBuf0 = (int32_t *)param->paramData;
1018
0
      param->lineBuf1 = param->lineBuf0 + lineLength;
1019
0
    }
1020
0
    int32_t *lineBuf = param->lineBuf1 + 1;
1021
0
    if (crxDecodeLine(param))
1022
0
      return -1;
1023
0
    memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
1024
0
    ++param->curLine;
1025
0
  }
1026
0
  else
1027
0
  {
1028
0
    int32_t lineLength = param->subbandWidth + 2;
1029
0
    if (param->curLine & 1)
1030
0
    {
1031
0
      param->lineBuf1 = (int32_t *)param->paramData;
1032
0
      param->lineBuf0 = param->lineBuf1 + lineLength;
1033
0
    }
1034
0
    else
1035
0
    {
1036
0
      param->lineBuf0 = (int32_t *)param->paramData;
1037
0
      param->lineBuf1 = param->lineBuf0 + lineLength;
1038
0
    }
1039
0
    int32_t *lineBuf = param->lineBuf1 + 1;
1040
0
    if (crxDecodeLineRounded(param))
1041
0
      return -1;
1042
0
    memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
1043
0
    ++param->curLine;
1044
0
  }
1045
0
  return 0;
1046
0
}
1047
1048
int crxUpdateQparam(CrxSubband *subband)
1049
0
{
1050
0
  uint32_t bitCode = crxBitstreamGetZeros(&subband->bandParam->bitStream);
1051
0
  if (bitCode >= 23)
1052
0
    bitCode = crxBitstreamGetBits(&subband->bandParam->bitStream, 8);
1053
0
  else if (subband->kParam)
1054
0
    bitCode = crxBitstreamGetBits(&subband->bandParam->bitStream, subband->kParam) | (bitCode << subband->kParam);
1055
1056
0
  subband->qParam += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); // converting encoded to signed integer
1057
0
  subband->kParam = crxPredictKParameter(subband->kParam, bitCode);
1058
0
  if (subband->kParam > 7)
1059
0
    return -1;
1060
0
  return 0;
1061
0
}
1062
1063
libraw_inline int getSubbandRow(CrxSubband *band, int row)
1064
0
{
1065
0
  return row < band->rowStartAddOn
1066
0
             ? 0
1067
0
             : (row < band->height - band->rowEndAddOn ? row - band->rowEndAddOn
1068
0
                                                       : band->height - band->rowEndAddOn - band->rowStartAddOn - 1);
1069
0
}
1070
int crxDecodeLineWithIQuantization(CrxSubband *band, CrxQStep *qStep)
1071
0
{
1072
0
  if (!band->dataSize)
1073
0
  {
1074
0
    memset(band->bandBuf, 0, band->bandSize);
1075
0
    return 0;
1076
0
  }
1077
1078
0
  if (band->supportsPartial && !qStep && crxUpdateQparam(band))
1079
0
    return -1;
1080
0
  if (crxDecodeLine(band->bandParam, band->bandBuf))
1081
0
    return -1;
1082
1083
0
  if (band->width <= 0)
1084
0
    return 0;
1085
1086
  // update band buffers
1087
0
  int32_t *bandBuf = (int32_t *)band->bandBuf;
1088
0
  if (qStep)
1089
0
  {
1090
    // new version
1091
0
    uint32_t *qStepTblPtr = &qStep->qStepTbl[qStep->width * getSubbandRow(band, band->bandParam->curLine - 1)];
1092
1093
0
    for (int i = 0; i < band->colStartAddOn; ++i)
1094
0
    {
1095
0
      int32_t quantVal = band->qStepBase + ((qStepTblPtr[0] * band->qStepMult) >> 3);
1096
0
      bandBuf[i] *= _constrain(quantVal, 1, 0x168000);
1097
0
    }
1098
1099
0
    for (int i = band->colStartAddOn; i < band->width - band->colEndAddOn; ++i)
1100
0
    {
1101
0
      int32_t quantVal =
1102
0
          band->qStepBase + ((qStepTblPtr[(i - band->colStartAddOn) >> band->levelShift] * band->qStepMult) >> 3);
1103
0
      bandBuf[i] *= _constrain(quantVal, 1, 0x168000);
1104
0
    }
1105
0
    int lastIdx = (band->width - band->colEndAddOn - band->colStartAddOn - 1) >> band->levelShift;
1106
0
    for (int i = band->width - band->colEndAddOn; i < band->width; ++i)
1107
0
    {
1108
0
      int32_t quantVal = band->qStepBase + ((qStepTblPtr[lastIdx] * band->qStepMult) >> 3);
1109
0
      bandBuf[i] *= _constrain(quantVal, 1, 0x168000);
1110
0
    }
1111
0
  }
1112
0
  else
1113
0
  {
1114
    // prev. version
1115
0
    int32_t qScale = q_step_tbl[band->qParam % 6] >> (6 - band->qParam / 6);
1116
0
    if (band->qParam / 6 >= 6)
1117
0
      qScale = q_step_tbl[band->qParam % 6] * (1 << (band->qParam / 6 + 26));
1118
1119
0
    if (qScale != 1)
1120
0
      for (int32_t i = 0; i < band->width; ++i)
1121
0
        bandBuf[i] *= qScale;
1122
0
  }
1123
1124
0
  return 0;
1125
0
}
1126
1127
void crxHorizontal53(int32_t *lineBufLA, int32_t *lineBufLB, CrxWaveletTransform *wavelet, uint32_t tileFlag)
1128
0
{
1129
0
  int32_t *band0Buf = wavelet->subband0Buf;
1130
0
  int32_t *band1Buf = wavelet->subband1Buf;
1131
0
  int32_t *band2Buf = wavelet->subband2Buf;
1132
0
  int32_t *band3Buf = wavelet->subband3Buf;
1133
1134
0
  if (wavelet->width <= 1)
1135
0
  {
1136
0
    lineBufLA[0] = band0Buf[0];
1137
0
    lineBufLB[0] = band2Buf[0];
1138
0
  }
1139
0
  else
1140
0
  {
1141
0
    if (tileFlag & E_HAS_TILES_ON_THE_LEFT)
1142
0
    {
1143
0
      lineBufLA[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1144
0
      lineBufLB[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1145
0
      ++band1Buf;
1146
0
      ++band3Buf;
1147
0
    }
1148
0
    else
1149
0
    {
1150
0
      lineBufLA[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1151
0
      lineBufLB[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1152
0
    }
1153
0
    ++band0Buf;
1154
0
    ++band2Buf;
1155
1156
0
    for (int i = 0; i < wavelet->width - 3; i += 2)
1157
0
    {
1158
0
      int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1159
0
      lineBufLA[1] = band1Buf[0] + ((delta + lineBufLA[0]) >> 1);
1160
0
      lineBufLA[2] = delta;
1161
1162
0
      delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1163
0
      lineBufLB[1] = band3Buf[0] + ((delta + lineBufLB[0]) >> 1);
1164
0
      lineBufLB[2] = delta;
1165
1166
0
      ++band0Buf;
1167
0
      ++band1Buf;
1168
0
      ++band2Buf;
1169
0
      ++band3Buf;
1170
0
      lineBufLA += 2;
1171
0
      lineBufLB += 2;
1172
0
    }
1173
0
    if (tileFlag & E_HAS_TILES_ON_THE_RIGHT)
1174
0
    {
1175
0
      int32_t deltaA = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1176
0
      lineBufLA[1] = band1Buf[0] + ((deltaA + lineBufLA[0]) >> 1);
1177
1178
0
      int32_t deltaB = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1179
0
      lineBufLB[1] = band3Buf[0] + ((deltaB + lineBufLB[0]) >> 1);
1180
1181
0
      if (wavelet->width & 1)
1182
0
      {
1183
0
        lineBufLA[2] = deltaA;
1184
0
        lineBufLB[2] = deltaB;
1185
0
      }
1186
0
    }
1187
0
    else if (wavelet->width & 1)
1188
0
    {
1189
0
      lineBufLA[1] = band1Buf[0] + ((lineBufLA[0] + band0Buf[0] - ((band1Buf[0] + 1) >> 1)) >> 1);
1190
0
      lineBufLA[2] = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1191
1192
0
      lineBufLB[1] = band3Buf[0] + ((lineBufLB[0] + band2Buf[0] - ((band3Buf[0] + 1) >> 1)) >> 1);
1193
0
      lineBufLB[2] = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1194
0
    }
1195
0
    else
1196
0
    {
1197
0
      lineBufLA[1] = lineBufLA[0] + band1Buf[0];
1198
0
      lineBufLB[1] = lineBufLB[0] + band3Buf[0];
1199
0
    }
1200
0
  }
1201
0
}
1202
1203
int32_t *crxIdwt53FilterGetLine(CrxPlaneComp *comp, int32_t level)
1204
0
{
1205
0
  int32_t *result = comp->wvltTransform[level]
1206
0
                        .lineBuf[(comp->wvltTransform[level].fltTapH - comp->wvltTransform[level].curH + 5) % 5 + 3];
1207
0
  comp->wvltTransform[level].curH--;
1208
0
  return result;
1209
0
}
1210
1211
int crxIdwt53FilterDecode(CrxPlaneComp *comp, int32_t level, CrxQStep *qStep)
1212
0
{
1213
0
  if (comp->wvltTransform[level].curH)
1214
0
    return 0;
1215
1216
0
  CrxSubband *sband = comp->subBands + 3 * level;
1217
0
  CrxQStep *qStepLevel = qStep ? qStep + level : 0;
1218
1219
0
  if (comp->wvltTransform[level].height - 3 <= comp->wvltTransform[level].curLine &&
1220
0
      !(comp->tileFlag & E_HAS_TILES_ON_THE_BOTTOM))
1221
0
  {
1222
0
    if (comp->wvltTransform[level].height & 1)
1223
0
    {
1224
0
      if (level)
1225
0
      {
1226
0
        if (crxIdwt53FilterDecode(comp, level - 1, qStep))
1227
0
          return -1;
1228
0
      }
1229
0
      else if (crxDecodeLineWithIQuantization(sband, qStepLevel))
1230
0
        return -1;
1231
1232
0
      if (crxDecodeLineWithIQuantization(sband + 1, qStepLevel))
1233
0
        return -1;
1234
0
    }
1235
0
  }
1236
0
  else
1237
0
  {
1238
0
    if (level)
1239
0
    {
1240
0
      if (crxIdwt53FilterDecode(comp, level - 1, qStep))
1241
0
        return -1;
1242
0
    }
1243
0
    else if (crxDecodeLineWithIQuantization(sband, qStepLevel)) // LL band
1244
0
      return -1;
1245
1246
0
    if (crxDecodeLineWithIQuantization(sband + 1, qStepLevel) || // HL band
1247
0
        crxDecodeLineWithIQuantization(sband + 2, qStepLevel) || // LH band
1248
0
        crxDecodeLineWithIQuantization(sband + 3, qStepLevel))   // HH band
1249
0
      return -1;
1250
0
  }
1251
1252
0
  return 0;
1253
0
}
1254
1255
int crxIdwt53FilterTransform(CrxPlaneComp *comp, uint32_t level)
1256
0
{
1257
0
  CrxWaveletTransform *wavelet = comp->wvltTransform + level;
1258
1259
0
  if (wavelet->curH)
1260
0
    return 0;
1261
1262
0
  if (wavelet->curLine >= wavelet->height - 3)
1263
0
  {
1264
0
    if (!(comp->tileFlag & E_HAS_TILES_ON_THE_BOTTOM))
1265
0
    {
1266
0
      if (wavelet->height & 1)
1267
0
      {
1268
0
        if (level)
1269
0
        {
1270
0
          if (!wavelet[-1].curH)
1271
0
            if (crxIdwt53FilterTransform(comp, level - 1))
1272
0
              return -1;
1273
0
          wavelet->subband0Buf = crxIdwt53FilterGetLine(comp, level - 1);
1274
0
        }
1275
0
        int32_t *band0Buf = wavelet->subband0Buf;
1276
0
        int32_t *band1Buf = wavelet->subband1Buf;
1277
0
        int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3];
1278
0
        int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3];
1279
0
        int32_t *lineBufH2 = wavelet->lineBuf[(wavelet->fltTapH + 2) % 5 + 3];
1280
1281
0
        int32_t *lineBufL0 = wavelet->lineBuf[0];
1282
0
        int32_t *lineBufL1 = wavelet->lineBuf[1];
1283
0
        wavelet->lineBuf[1] = wavelet->lineBuf[2];
1284
0
        wavelet->lineBuf[2] = lineBufL1;
1285
1286
        // process L bands
1287
0
        if (wavelet->width <= 1)
1288
0
        {
1289
0
          lineBufL0[0] = band0Buf[0];
1290
0
        }
1291
0
        else
1292
0
        {
1293
0
          if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT)
1294
0
          {
1295
0
            lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1296
0
            ++band1Buf;
1297
0
          }
1298
0
          else
1299
0
          {
1300
0
            lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1301
0
          }
1302
0
          ++band0Buf;
1303
0
          for (int i = 0; i < wavelet->width - 3; i += 2)
1304
0
          {
1305
0
            int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1306
0
            lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1);
1307
0
            lineBufL0[2] = delta;
1308
0
            ++band0Buf;
1309
0
            ++band1Buf;
1310
0
            lineBufL0 += 2;
1311
0
          }
1312
0
          if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
1313
0
          {
1314
0
            int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1315
0
            lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1);
1316
0
            if (wavelet->width & 1)
1317
0
              lineBufL0[2] = delta;
1318
0
          }
1319
0
          else if (wavelet->width & 1)
1320
0
          {
1321
0
            int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1322
0
            lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1);
1323
0
            lineBufL0[2] = delta;
1324
0
          }
1325
0
          else
1326
0
            lineBufL0[1] = band1Buf[0] + lineBufL0[0];
1327
0
        }
1328
1329
        // process H bands
1330
0
        lineBufL0 = wavelet->lineBuf[0];
1331
0
        lineBufL1 = wavelet->lineBuf[1];
1332
0
        for (int32_t i = 0; i < wavelet->width; i++)
1333
0
        {
1334
0
          int32_t delta = lineBufL0[i] - ((lineBufL1[i] + 1) >> 1);
1335
0
          lineBufH1[i] = lineBufL1[i] + ((delta + lineBufH0[i]) >> 1);
1336
0
          lineBufH2[i] = delta;
1337
0
        }
1338
0
        wavelet->curH += 3;
1339
0
        wavelet->curLine += 3;
1340
0
        wavelet->fltTapH = (wavelet->fltTapH + 3) % 5;
1341
0
      }
1342
0
      else
1343
0
      {
1344
0
        int32_t *lineBufL2 = wavelet->lineBuf[2];
1345
0
        int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3];
1346
0
        int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3];
1347
0
        wavelet->lineBuf[1] = lineBufL2;
1348
0
        wavelet->lineBuf[2] = wavelet->lineBuf[1];
1349
1350
0
        for (int32_t i = 0; i < wavelet->width; i++)
1351
0
          lineBufH1[i] = lineBufH0[i] + lineBufL2[i];
1352
1353
0
        wavelet->curH += 2;
1354
0
        wavelet->curLine += 2;
1355
0
        wavelet->fltTapH = (wavelet->fltTapH + 2) % 5;
1356
0
      }
1357
0
    }
1358
0
  }
1359
0
  else
1360
0
  {
1361
0
    if (level)
1362
0
    {
1363
0
      if (!wavelet[-1].curH && crxIdwt53FilterTransform(comp, level - 1))
1364
0
        return -1;
1365
0
      wavelet->subband0Buf = crxIdwt53FilterGetLine(comp, level - 1);
1366
0
    }
1367
1368
0
    int32_t *band0Buf = wavelet->subband0Buf;
1369
0
    int32_t *band1Buf = wavelet->subband1Buf;
1370
0
    int32_t *band2Buf = wavelet->subband2Buf;
1371
0
    int32_t *band3Buf = wavelet->subband3Buf;
1372
1373
0
    int32_t *lineBufL0 = wavelet->lineBuf[0];
1374
0
    int32_t *lineBufL1 = wavelet->lineBuf[1];
1375
0
    int32_t *lineBufL2 = wavelet->lineBuf[2];
1376
0
    int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3];
1377
0
    int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3];
1378
0
    int32_t *lineBufH2 = wavelet->lineBuf[(wavelet->fltTapH + 2) % 5 + 3];
1379
1380
0
    wavelet->lineBuf[1] = wavelet->lineBuf[2];
1381
0
    wavelet->lineBuf[2] = lineBufL1;
1382
1383
    // process L bands
1384
0
    if (wavelet->width <= 1)
1385
0
    {
1386
0
      lineBufL0[0] = band0Buf[0];
1387
0
      lineBufL1[0] = band2Buf[0];
1388
0
    }
1389
0
    else
1390
0
    {
1391
0
      if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT)
1392
0
      {
1393
0
        lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1394
0
        lineBufL1[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1395
0
        ++band1Buf;
1396
0
        ++band3Buf;
1397
0
      }
1398
0
      else
1399
0
      {
1400
0
        lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1401
0
        lineBufL1[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1402
0
      }
1403
0
      ++band0Buf;
1404
0
      ++band2Buf;
1405
0
      for (int i = 0; i < wavelet->width - 3; i += 2)
1406
0
      {
1407
0
        int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1408
0
        lineBufL0[1] = band1Buf[0] + ((delta + lineBufL0[0]) >> 1);
1409
0
        lineBufL0[2] = delta;
1410
1411
0
        delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1412
0
        lineBufL1[1] = band3Buf[0] + ((delta + lineBufL1[0]) >> 1);
1413
0
        lineBufL1[2] = delta;
1414
1415
0
        ++band0Buf;
1416
0
        ++band1Buf;
1417
0
        ++band2Buf;
1418
0
        ++band3Buf;
1419
0
        lineBufL0 += 2;
1420
0
        lineBufL1 += 2;
1421
0
      }
1422
0
      if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
1423
0
      {
1424
0
        int32_t deltaA = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1425
0
        lineBufL0[1] = band1Buf[0] + ((deltaA + lineBufL0[0]) >> 1);
1426
1427
0
        int32_t deltaB = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1428
0
        lineBufL1[1] = band3Buf[0] + ((deltaB + lineBufL1[0]) >> 1);
1429
1430
0
        if (wavelet->width & 1)
1431
0
        {
1432
0
          lineBufL0[2] = deltaA;
1433
0
          lineBufL1[2] = deltaB;
1434
0
        }
1435
0
      }
1436
0
      else if (wavelet->width & 1)
1437
0
      {
1438
0
        int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1439
0
        lineBufL0[1] = band1Buf[0] + ((delta + lineBufL0[0]) >> 1);
1440
0
        lineBufL0[2] = delta;
1441
1442
0
        delta = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1443
0
        lineBufL1[1] = band3Buf[0] + ((delta + lineBufL1[0]) >> 1);
1444
0
        lineBufL1[2] = delta;
1445
0
      }
1446
0
      else
1447
0
      {
1448
0
        lineBufL0[1] = lineBufL0[0] + band1Buf[0];
1449
0
        lineBufL1[1] = lineBufL1[0] + band3Buf[0];
1450
0
      }
1451
0
    }
1452
1453
    // process H bands
1454
0
    lineBufL0 = wavelet->lineBuf[0];
1455
0
    lineBufL1 = wavelet->lineBuf[1];
1456
0
    lineBufL2 = wavelet->lineBuf[2];
1457
0
    for (int32_t i = 0; i < wavelet->width; i++)
1458
0
    {
1459
0
      int32_t delta = lineBufL0[i] - ((lineBufL2[i] + lineBufL1[i] + 2) >> 2);
1460
0
      lineBufH1[i] = lineBufL1[i] + ((delta + lineBufH0[i]) >> 1);
1461
0
      lineBufH2[i] = delta;
1462
0
    }
1463
0
    if (wavelet->curLine >= wavelet->height - 3 && wavelet->height & 1)
1464
0
    {
1465
0
      wavelet->curH += 3;
1466
0
      wavelet->curLine += 3;
1467
0
      wavelet->fltTapH = (wavelet->fltTapH + 3) % 5;
1468
0
    }
1469
0
    else
1470
0
    {
1471
0
      wavelet->curH += 2;
1472
0
      wavelet->curLine += 2;
1473
0
      wavelet->fltTapH = (wavelet->fltTapH + 2) % 5;
1474
0
    }
1475
0
  }
1476
1477
0
  return 0;
1478
0
}
1479
1480
int crxIdwt53FilterInitialize(CrxPlaneComp *comp, int32_t level, CrxQStep *qStep)
1481
0
{
1482
0
  if (level == 0)
1483
0
    return 0;
1484
1485
0
  for (int curLevel = 0, curBand = 0; curLevel < level; curLevel++, curBand += 3)
1486
0
  {
1487
0
    CrxQStep *qStepLevel = qStep ? qStep + curLevel : 0;
1488
0
    CrxWaveletTransform *wavelet = comp->wvltTransform + curLevel;
1489
0
    if (curLevel)
1490
0
      wavelet[0].subband0Buf = crxIdwt53FilterGetLine(comp, curLevel - 1);
1491
0
    else if (crxDecodeLineWithIQuantization(comp->subBands + curBand, qStepLevel))
1492
0
      return -1;
1493
1494
0
    int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3];
1495
0
    if (wavelet->height > 1)
1496
0
    {
1497
0
      if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 1, qStepLevel) ||
1498
0
          crxDecodeLineWithIQuantization(comp->subBands + curBand + 2, qStepLevel) ||
1499
0
          crxDecodeLineWithIQuantization(comp->subBands + curBand + 3, qStepLevel))
1500
0
        return -1;
1501
1502
0
      int32_t *lineBufL0 = wavelet->lineBuf[0];
1503
0
      int32_t *lineBufL1 = wavelet->lineBuf[1];
1504
0
      int32_t *lineBufL2 = wavelet->lineBuf[2];
1505
1506
0
      if (comp->tileFlag & E_HAS_TILES_ON_THE_TOP)
1507
0
      {
1508
0
        crxHorizontal53(lineBufL0, wavelet->lineBuf[1], wavelet, comp->tileFlag);
1509
0
        if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 3, qStepLevel) ||
1510
0
            crxDecodeLineWithIQuantization(comp->subBands + curBand + 2, qStepLevel))
1511
0
          return -1;
1512
1513
0
        int32_t *band2Buf = wavelet->subband2Buf;
1514
0
        int32_t *band3Buf = wavelet->subband3Buf;
1515
1516
        // process L band
1517
0
        if (wavelet->width <= 1)
1518
0
          lineBufL2[0] = band2Buf[0];
1519
0
        else
1520
0
        {
1521
0
          if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT)
1522
0
          {
1523
0
            lineBufL2[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1524
0
            ++band3Buf;
1525
0
          }
1526
0
          else
1527
0
            lineBufL2[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1528
1529
0
          ++band2Buf;
1530
1531
0
          for (int i = 0; i < wavelet->width - 3; i += 2)
1532
0
          {
1533
0
            int32_t delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1534
0
            lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1);
1535
0
            lineBufL2[2] = delta;
1536
1537
0
            ++band2Buf;
1538
0
            ++band3Buf;
1539
0
            lineBufL2 += 2;
1540
0
          }
1541
0
          if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
1542
0
          {
1543
0
            int32_t delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1544
0
            lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1);
1545
0
            if (wavelet->width & 1)
1546
0
              lineBufL2[2] = delta;
1547
0
          }
1548
0
          else if (wavelet->width & 1)
1549
0
          {
1550
0
            int32_t delta = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1551
1552
0
            lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1);
1553
0
            lineBufL2[2] = delta;
1554
0
          }
1555
0
          else
1556
0
          {
1557
0
            lineBufL2[1] = band3Buf[0] + lineBufL2[0];
1558
0
          }
1559
0
        }
1560
1561
        // process H band
1562
0
        for (int32_t i = 0; i < wavelet->width; i++)
1563
0
          lineBufH0[i] = lineBufL0[i] - ((lineBufL1[i] + lineBufL2[i] + 2) >> 2);
1564
0
      }
1565
0
      else
1566
0
      {
1567
0
        crxHorizontal53(lineBufL0, wavelet->lineBuf[2], wavelet, comp->tileFlag);
1568
0
        for (int i = 0; i < wavelet->width; i++)
1569
0
          lineBufH0[i] = lineBufL0[i] - ((lineBufL2[i] + 1) >> 1);
1570
0
      }
1571
1572
0
      if (crxIdwt53FilterDecode(comp, curLevel, qStep) || crxIdwt53FilterTransform(comp, curLevel))
1573
0
        return -1;
1574
0
    }
1575
0
    else
1576
0
    {
1577
0
      if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 1, qStepLevel))
1578
0
        return -1;
1579
1580
0
      int32_t *band0Buf = wavelet->subband0Buf;
1581
0
      int32_t *band1Buf = wavelet->subband1Buf;
1582
1583
      // process H band
1584
0
      if (wavelet->width <= 1)
1585
0
        lineBufH0[0] = band0Buf[0];
1586
0
      else
1587
0
      {
1588
0
        if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT)
1589
0
        {
1590
0
          lineBufH0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1591
0
          ++band1Buf;
1592
0
        }
1593
0
        else
1594
0
          lineBufH0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1595
1596
0
        ++band0Buf;
1597
1598
0
        for (int i = 0; i < wavelet->width - 3; i += 2)
1599
0
        {
1600
0
          int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1601
0
          lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1);
1602
0
          lineBufH0[2] = delta;
1603
1604
0
          ++band0Buf;
1605
0
          ++band1Buf;
1606
0
          lineBufH0 += 2;
1607
0
        }
1608
1609
0
        if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
1610
0
        {
1611
0
          int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1612
0
          lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1);
1613
0
          lineBufH0[2] = delta;
1614
0
        }
1615
0
        else if (wavelet->width & 1)
1616
0
        {
1617
0
          int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1618
0
          lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1);
1619
0
          lineBufH0[2] = delta;
1620
0
        }
1621
0
        else
1622
0
        {
1623
0
          lineBufH0[1] = band1Buf[0] + lineBufH0[0];
1624
0
        }
1625
0
      }
1626
0
      ++wavelet->curLine;
1627
0
      ++wavelet->curH;
1628
0
      wavelet->fltTapH = (wavelet->fltTapH + 1) % 5;
1629
0
    }
1630
0
  }
1631
1632
0
  return 0;
1633
0
}
1634
1635
void crxFreeSubbandData(CrxImage *image, CrxPlaneComp *comp)
1636
0
{
1637
0
  if (comp->compBuf)
1638
0
  {
1639
0
    free(comp->compBuf);
1640
0
    comp->compBuf = 0;
1641
0
  }
1642
1643
0
  if (!comp->subBands)
1644
0
    return;
1645
1646
0
  for (int32_t i = 0; i < image->subbandCount; i++)
1647
0
  {
1648
0
    if (comp->subBands[i].bandParam)
1649
0
    {
1650
0
      free(comp->subBands[i].bandParam);
1651
0
      comp->subBands[i].bandParam = 0LL;
1652
0
    }
1653
1654
0
    comp->subBands[i].bandBuf = 0;
1655
0
    comp->subBands[i].bandSize = 0;
1656
0
  }
1657
0
}
1658
1659
void crxConvertPlaneLine(CrxImage *img, int imageRow, int imageCol = 0, int plane = 0, int32_t *lineData = 0,
1660
                         int lineLength = 0)
1661
0
{
1662
0
  if (lineData)
1663
0
  {
1664
0
    uint64_t rawOffset = 4 * img->planeWidth * imageRow + 2 * imageCol;
1665
0
    if (img->encType == 1)
1666
0
    {
1667
0
      int32_t maxVal = 1 << (img->nBits - 1);
1668
0
      int32_t minVal = -maxVal;
1669
0
      --maxVal;
1670
0
      for (int i = 0; i < lineLength; i++)
1671
0
        img->outBufs[plane][rawOffset + 2 * i] = _constrain(lineData[i], minVal, maxVal);
1672
0
    }
1673
0
    else if (img->encType == 3)
1674
0
    {
1675
      // copy to intermediate planeBuf
1676
0
      rawOffset = plane * img->planeWidth * img->planeHeight + img->planeWidth * imageRow + imageCol;
1677
0
      for (int i = 0; i < lineLength; i++)
1678
0
        img->planeBuf[rawOffset + i] = lineData[i];
1679
0
    }
1680
0
    else if (img->nPlanes == 4)
1681
0
    {
1682
0
      int32_t median = 1 << (img->nBits - 1);
1683
0
      int32_t maxVal = (1 << img->nBits) - 1;
1684
0
      for (int i = 0; i < lineLength; i++)
1685
0
        img->outBufs[plane][rawOffset + 2 * i] = _constrain(median + lineData[i], 0, maxVal);
1686
0
    }
1687
0
    else if (img->nPlanes == 1)
1688
0
    {
1689
0
      int32_t maxVal = (1 << img->nBits) - 1;
1690
0
      int32_t median = 1 << (img->nBits - 1);
1691
0
      rawOffset = img->planeWidth * imageRow + imageCol;
1692
0
      for (int i = 0; i < lineLength; i++)
1693
0
        img->outBufs[0][rawOffset + i] = _constrain(median + lineData[i], 0, maxVal);
1694
0
    }
1695
0
  }
1696
0
  else if (img->encType == 3 && img->planeBuf)
1697
0
  {
1698
0
    int32_t planeSize = img->planeWidth * img->planeHeight;
1699
0
    int16_t *plane0 = img->planeBuf + imageRow * img->planeWidth;
1700
0
    int16_t *plane1 = plane0 + planeSize;
1701
0
    int16_t *plane2 = plane1 + planeSize;
1702
0
    int16_t *plane3 = plane2 + planeSize;
1703
1704
0
    int32_t median = (1 << (img->medianBits - 1)) << 10;
1705
0
    int32_t maxVal = (1 << img->medianBits) - 1;
1706
0
    uint32_t rawLineOffset = 4 * img->planeWidth * imageRow;
1707
1708
    // for this stage - all except imageRow is ignored
1709
0
    for (int i = 0; i < img->planeWidth; i++)
1710
0
    {
1711
0
      int32_t gr = median + (plane0[i] << 10) - 168 * plane1[i] - 585 * plane3[i];
1712
0
      int32_t val = 0;
1713
0
      if (gr < 0)
1714
0
        gr = -(((_abs(gr) + 512) >> 9) & ~1);
1715
0
      else
1716
0
        gr = ((_abs(gr) + 512) >> 9) & ~1;
1717
1718
      // Essentially R = round(median + P0 + 1.474*P3)
1719
0
      val = (median + (plane0[i] << 10) + 1510 * plane3[i] + 512) >> 10;
1720
0
      img->outBufs[0][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal);
1721
      // Essentially G1 = round(median + P0 + P2 - 0.164*P1 - 0.571*P3)
1722
0
      val = (plane2[i] + gr + 1) >> 1;
1723
0
      img->outBufs[1][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal);
1724
      // Essentially G2 = round(median + P0 - P2 - 0.164*P1 - 0.571*P3)
1725
0
      val = (gr - plane2[i] + 1) >> 1;
1726
0
      img->outBufs[2][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal);
1727
      // Essentially B = round(median + P0 + 1.881*P1)
1728
0
      val = (median + (plane0[i] << 10) + 1927 * plane1[i] + 512) >> 10;
1729
0
      img->outBufs[3][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal);
1730
0
    }
1731
0
  }
1732
0
}
1733
1734
int crxParamInit(CrxImage *img, CrxBandParam **param, uint64_t subbandMdatOffset, uint64_t subbandDataSize,
1735
                 uint32_t subbandWidth, uint32_t subbandHeight, bool supportsPartial, uint32_t roundedBitsMask)
1736
0
{
1737
0
  int32_t progrDataSize = supportsPartial ? 0 : sizeof(int32_t) * subbandWidth;
1738
0
  int32_t paramLength = 2 * subbandWidth + 4;
1739
0
  uint8_t *paramBuf = 0;
1740
0
    paramBuf = (uint8_t *)
1741
0
#ifdef LIBRAW_CR3_MEMPOOL
1742
0
                   img->memmgr.
1743
0
#endif
1744
0
               calloc(1, sizeof(CrxBandParam) + sizeof(int32_t) * paramLength + progrDataSize);
1745
1746
0
  if (!paramBuf)
1747
0
    return -1;
1748
1749
0
  *param = (CrxBandParam *)paramBuf;
1750
1751
0
  paramBuf += sizeof(CrxBandParam);
1752
1753
0
  (*param)->paramData = (int32_t *)paramBuf;
1754
0
  (*param)->nonProgrData = progrDataSize ? (*param)->paramData + paramLength : 0;
1755
0
  (*param)->subbandWidth = subbandWidth;
1756
0
  (*param)->subbandHeight = subbandHeight;
1757
0
  (*param)->roundedBits = 0;
1758
0
  (*param)->curLine = 0;
1759
0
  (*param)->roundedBitsMask = roundedBitsMask;
1760
0
  (*param)->supportsPartial = supportsPartial;
1761
0
  (*param)->bitStream.bitData = 0;
1762
0
  (*param)->bitStream.bitsLeft = 0;
1763
0
  (*param)->bitStream.mdatSize = subbandDataSize;
1764
0
  (*param)->bitStream.curPos = 0;
1765
0
  (*param)->bitStream.curBufSize = 0;
1766
0
  (*param)->bitStream.curBufOffset = subbandMdatOffset;
1767
0
  (*param)->bitStream.input = img->input;
1768
1769
0
  crxFillBuffer(&(*param)->bitStream);
1770
1771
0
  return 0;
1772
0
}
1773
1774
int crxSetupSubbandData(CrxImage *img, CrxPlaneComp *planeComp, const CrxTile *tile, uint64_t mdatOffset)
1775
0
{
1776
0
  long compDataSize = 0;
1777
0
  long waveletDataOffset = 0;
1778
0
  long compCoeffDataOffset = 0;
1779
0
  int32_t toSubbands = 3 * img->levels + 1;
1780
0
  int32_t transformWidth = 0;
1781
1782
0
  CrxSubband *subbands = planeComp->subBands;
1783
1784
  // calculate sizes
1785
0
  for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++)
1786
0
  {
1787
0
    subbands[subbandNum].bandSize = subbands[subbandNum].width * sizeof(int32_t); // 4bytes
1788
0
    compDataSize += subbands[subbandNum].bandSize;
1789
0
  }
1790
1791
0
  if (img->levels)
1792
0
  {
1793
0
    int32_t encLevels = img->levels ? img->levels : 1;
1794
0
    waveletDataOffset = (compDataSize + 7) & ~7;
1795
0
    compDataSize = (sizeof(CrxWaveletTransform) * encLevels + waveletDataOffset + 7) & ~7;
1796
0
    compCoeffDataOffset = compDataSize;
1797
1798
    // calc wavelet line buffer sizes (always at one level up from current)
1799
0
    for (int level = 0; level < img->levels; ++level)
1800
0
      if (level < img->levels - 1)
1801
0
        compDataSize += 8 * sizeof(int32_t) * planeComp->subBands[3 * (level + 1) + 2].width;
1802
0
      else
1803
0
        compDataSize += 8 * sizeof(int32_t) * tile->width;
1804
0
  }
1805
    // buffer allocation
1806
0
    planeComp->compBuf = (uint8_t *)
1807
0
#ifdef LIBRAW_CR3_MEMPOOL
1808
0
                             img->memmgr.
1809
0
#endif
1810
0
                         malloc(compDataSize);
1811
0
  if (!planeComp->compBuf)
1812
0
    return -1;
1813
1814
  // subbands buffer and sizes initialisation
1815
0
  uint64_t subbandMdatOffset = img->mdatOffset + mdatOffset;
1816
0
  uint8_t *subbandBuf = planeComp->compBuf;
1817
1818
0
  for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++)
1819
0
  {
1820
0
    subbands[subbandNum].bandBuf = subbandBuf;
1821
0
    subbandBuf += subbands[subbandNum].bandSize;
1822
0
    subbands[subbandNum].mdatOffset = subbandMdatOffset + subbands[subbandNum].dataOffset;
1823
0
  }
1824
1825
  // wavelet data initialisation
1826
0
  if (img->levels)
1827
0
  {
1828
0
    CrxWaveletTransform *waveletTransforms = (CrxWaveletTransform *)(planeComp->compBuf + waveletDataOffset);
1829
0
    int32_t *paramData = (int32_t *)(planeComp->compBuf + compCoeffDataOffset);
1830
1831
0
    planeComp->wvltTransform = waveletTransforms;
1832
0
    waveletTransforms[0].subband0Buf = (int32_t *)subbands->bandBuf;
1833
1834
0
    for (int level = 0; level < img->levels; ++level)
1835
0
    {
1836
0
      int32_t band = 3 * level + 1;
1837
1838
0
      if (level >= img->levels - 1)
1839
0
      {
1840
0
        waveletTransforms[level].height = tile->height;
1841
0
        transformWidth = tile->width;
1842
0
      }
1843
0
      else
1844
0
      {
1845
0
        waveletTransforms[level].height = subbands[band + 3].height;
1846
0
        transformWidth = subbands[band + 4].width;
1847
0
      }
1848
0
      waveletTransforms[level].width = transformWidth;
1849
0
      waveletTransforms[level].lineBuf[0] = paramData;
1850
0
      waveletTransforms[level].lineBuf[1] = waveletTransforms[level].lineBuf[0] + transformWidth;
1851
0
      waveletTransforms[level].lineBuf[2] = waveletTransforms[level].lineBuf[1] + transformWidth;
1852
0
      waveletTransforms[level].lineBuf[3] = waveletTransforms[level].lineBuf[2] + transformWidth;
1853
0
      waveletTransforms[level].lineBuf[4] = waveletTransforms[level].lineBuf[3] + transformWidth;
1854
0
      waveletTransforms[level].lineBuf[5] = waveletTransforms[level].lineBuf[4] + transformWidth;
1855
0
      waveletTransforms[level].lineBuf[6] = waveletTransforms[level].lineBuf[5] + transformWidth;
1856
0
      waveletTransforms[level].lineBuf[7] = waveletTransforms[level].lineBuf[6] + transformWidth;
1857
0
      waveletTransforms[level].curLine = 0;
1858
0
      waveletTransforms[level].curH = 0;
1859
0
      waveletTransforms[level].fltTapH = 0;
1860
0
      waveletTransforms[level].subband1Buf = (int32_t *)subbands[band].bandBuf;
1861
0
      waveletTransforms[level].subband2Buf = (int32_t *)subbands[band + 1].bandBuf;
1862
0
      waveletTransforms[level].subband3Buf = (int32_t *)subbands[band + 2].bandBuf;
1863
1864
0
      paramData = waveletTransforms[level].lineBuf[7] + transformWidth;
1865
0
    }
1866
0
  }
1867
1868
  // decoding params and bitstream initialisation
1869
0
  for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++)
1870
0
  {
1871
0
    if (subbands[subbandNum].dataSize)
1872
0
    {
1873
0
      bool supportsPartial = false;
1874
0
      uint32_t roundedBitsMask = 0;
1875
1876
0
      if (planeComp->supportsPartial && subbandNum == 0)
1877
0
      {
1878
0
        roundedBitsMask = planeComp->roundedBitsMask;
1879
0
        supportsPartial = true;
1880
0
      }
1881
0
      if (crxParamInit(img, &subbands[subbandNum].bandParam, subbands[subbandNum].mdatOffset,
1882
0
                       subbands[subbandNum].dataSize, subbands[subbandNum].width, subbands[subbandNum].height,
1883
0
                       supportsPartial, roundedBitsMask))
1884
0
        return -1;
1885
0
    }
1886
0
  }
1887
1888
0
  return 0;
1889
0
}
1890
1891
int LibRaw::crxDecodePlane(void *p, uint32_t planeNumber)
1892
0
{
1893
0
  CrxImage *img = (CrxImage *)p;
1894
0
  int imageRow = 0;
1895
0
  for (int tRow = 0; tRow < img->tileRows; tRow++)
1896
0
  {
1897
0
    int imageCol = 0;
1898
0
    for (int tCol = 0; tCol < img->tileCols; tCol++)
1899
0
    {
1900
0
      CrxTile *tile = img->tiles + tRow * img->tileCols + tCol;
1901
0
      CrxPlaneComp *planeComp = tile->comps + planeNumber;
1902
0
      uint64_t tileMdatOffset = tile->dataOffset + tile->mdatQPDataSize + tile->mdatExtraSize + planeComp->dataOffset;
1903
1904
      // decode single tile
1905
0
      if (crxSetupSubbandData(img, planeComp, tile, tileMdatOffset))
1906
0
        return -1;
1907
1908
0
      if (img->levels)
1909
0
      {
1910
0
        if (crxIdwt53FilterInitialize(planeComp, img->levels, tile->qStep))
1911
0
          return -1;
1912
0
        for (int i = 0; i < tile->height; ++i)
1913
0
        {
1914
0
          if (crxIdwt53FilterDecode(planeComp, img->levels - 1, tile->qStep) ||
1915
0
              crxIdwt53FilterTransform(planeComp, img->levels - 1))
1916
0
            return -1;
1917
0
          int32_t *lineData = crxIdwt53FilterGetLine(planeComp, img->levels - 1);
1918
0
          crxConvertPlaneLine(img, imageRow + i, imageCol, planeNumber, lineData, tile->width);
1919
0
        }
1920
0
      }
1921
0
      else
1922
0
      {
1923
        // we have the only subband in this case
1924
0
        if (!planeComp->subBands->dataSize)
1925
0
        {
1926
0
          memset(planeComp->subBands->bandBuf, 0, planeComp->subBands->bandSize);
1927
0
          return 0;
1928
0
        }
1929
1930
0
        for (int i = 0; i < tile->height; ++i)
1931
0
        {
1932
0
          if (crxDecodeLine(planeComp->subBands->bandParam, planeComp->subBands->bandBuf))
1933
0
            return -1;
1934
0
          int32_t *lineData = (int32_t *)planeComp->subBands->bandBuf;
1935
0
          crxConvertPlaneLine(img, imageRow + i, imageCol, planeNumber, lineData, tile->width);
1936
0
        }
1937
0
      }
1938
0
      imageCol += tile->width;
1939
0
    }
1940
0
    imageRow += img->tiles[tRow * img->tileCols].height;
1941
0
  }
1942
1943
0
  return 0;
1944
0
}
1945
1946
uint32_t crxReadQP(CrxBitstream *bitStrm, int32_t kParam)
1947
0
{
1948
0
  uint32_t qp = crxBitstreamGetZeros(bitStrm);
1949
0
  if (qp >= 23)
1950
0
    qp = crxBitstreamGetBits(bitStrm, 8);
1951
0
  else if (kParam)
1952
0
    qp = crxBitstreamGetBits(bitStrm, kParam) | (qp << kParam);
1953
1954
0
  return qp;
1955
0
}
1956
1957
void crxDecodeGolombTop(CrxBitstream *bitStrm, int32_t width, int32_t *lineBuf, int32_t *kParam)
1958
0
{
1959
0
  lineBuf[0] = 0;
1960
0
  while (width-- > 0)
1961
0
  {
1962
0
    lineBuf[1] = lineBuf[0];
1963
0
    uint32_t qp = crxReadQP(bitStrm, *kParam);
1964
0
    lineBuf[1] += -(int32_t)(qp & 1) ^ (int32_t)(qp >> 1);
1965
0
    *kParam = crxPredictKParameter(*kParam, qp, 7);
1966
0
    ++lineBuf;
1967
0
  }
1968
0
  lineBuf[1] = lineBuf[0] + 1;
1969
0
}
1970
1971
void crxDecodeGolombNormal(CrxBitstream *bitStrm, int32_t width, int32_t *lineBuf0, int32_t *lineBuf1, int32_t *kParam)
1972
0
{
1973
0
  lineBuf1[0] = lineBuf0[1];
1974
0
  int32_t deltaH = lineBuf0[1] - lineBuf0[0];
1975
0
  while (width-- > 0)
1976
0
  {
1977
0
    lineBuf1[1] = crxPrediction(lineBuf1[0], lineBuf0[1], deltaH, lineBuf0[0] - lineBuf1[0]);
1978
0
    uint32_t qp = crxReadQP(bitStrm, *kParam);
1979
0
    lineBuf1[1] += -(int32_t)(qp & 1) ^ (int32_t)(qp >> 1);
1980
0
    if (width)
1981
0
    {
1982
0
      deltaH = lineBuf0[2] - lineBuf0[1];
1983
0
      *kParam = crxPredictKParameter(*kParam, (qp + 2 * _abs(deltaH)) >> 1, 7);
1984
0
      ++lineBuf0;
1985
0
    }
1986
0
    else
1987
0
      *kParam = crxPredictKParameter(*kParam, qp, 7);
1988
0
    ++lineBuf1;
1989
0
  }
1990
0
  lineBuf1[1] = lineBuf1[0] + 1;
1991
0
}
1992
1993
int crxMakeQStep(CrxImage *img, CrxTile *tile, int32_t *qpTable, uint32_t /*totalQP*/)
1994
0
{
1995
0
  if (img->levels > 3 || img->levels < 1)
1996
0
    return -1;
1997
0
  int qpWidth = (tile->width >> 3) + ((tile->width & 7) != 0);
1998
0
  int qpHeight = (tile->height >> 1) + (tile->height & 1);
1999
0
  int qpHeight4 = (tile->height >> 2) + ((tile->height & 3) != 0);
2000
0
  int qpHeight8 = (tile->height >> 3) + ((tile->height & 7) != 0);
2001
0
  uint32_t totalHeight = qpHeight;
2002
0
  if (img->levels > 1)
2003
0
    totalHeight += qpHeight4;
2004
0
  if (img->levels > 2)
2005
0
    totalHeight += qpHeight8;
2006
2007
0
  tile->qStep = (CrxQStep *)
2008
0
#ifdef LIBRAW_CR3_MEMPOOL
2009
0
                      img->memmgr.
2010
0
#endif
2011
0
                  malloc(totalHeight * qpWidth * sizeof(uint32_t) + img->levels * sizeof(CrxQStep));
2012
2013
0
  if (!tile->qStep)
2014
0
    return -1;
2015
0
  uint32_t *qStepTbl = (uint32_t *)(tile->qStep + img->levels);
2016
0
  CrxQStep *qStep = tile->qStep;
2017
0
  switch (img->levels)
2018
0
  {
2019
0
  case 3:
2020
0
    qStep->qStepTbl = qStepTbl;
2021
0
    qStep->width = qpWidth;
2022
0
    qStep->height = qpHeight8;
2023
0
    for (int qpRow = 0; qpRow < qpHeight8; ++qpRow)
2024
0
    {
2025
0
      int row0Idx = qpWidth * _min(4 * qpRow, qpHeight - 1);
2026
0
      int row1Idx = qpWidth * _min(4 * qpRow + 1, qpHeight - 1);
2027
0
      int row2Idx = qpWidth * _min(4 * qpRow + 2, qpHeight - 1);
2028
0
      int row3Idx = qpWidth * _min(4 * qpRow + 3, qpHeight - 1);
2029
2030
0
      for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl)
2031
0
      {
2032
0
        int32_t quantVal = qpTable[row0Idx++] + qpTable[row1Idx++] + qpTable[row2Idx++] + qpTable[row3Idx++];
2033
        // not sure about this nonsense - why is it not just avg like with 2 levels?
2034
0
        quantVal = ((quantVal < 0) * 3 + quantVal) >> 2;
2035
0
        if (quantVal / 6 >= 6)
2036
0
          *qStepTbl = q_step_tbl[quantVal % 6] << ((quantVal / 6 - 6 ) & 0x1f);
2037
0
        else
2038
0
          *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6);
2039
0
      }
2040
0
    }
2041
    // continue to the next level - we always decode all levels
2042
0
    ++qStep;
2043
0
  case 2:
2044
0
    qStep->qStepTbl = qStepTbl;
2045
0
    qStep->width = qpWidth;
2046
0
    qStep->height = qpHeight4;
2047
0
    for (int qpRow = 0; qpRow < qpHeight4; ++qpRow)
2048
0
    {
2049
0
      int row0Idx = qpWidth * _min(2 * qpRow, qpHeight - 1);
2050
0
      int row1Idx = qpWidth * _min(2 * qpRow + 1, qpHeight - 1);
2051
2052
0
      for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl)
2053
0
      {
2054
0
        int32_t quantVal = (qpTable[row0Idx++] + qpTable[row1Idx++]) / 2;
2055
0
        if (quantVal / 6 >= 6)
2056
0
          *qStepTbl = q_step_tbl[quantVal % 6] << ((quantVal / 6 - 6) & 0x1f);
2057
0
        else
2058
0
          *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6);
2059
0
      }
2060
0
    }
2061
    // continue to the next level - we always decode all levels
2062
0
    ++qStep;
2063
0
  case 1:
2064
0
    qStep->qStepTbl = qStepTbl;
2065
0
    qStep->width = qpWidth;
2066
0
    qStep->height = qpHeight;
2067
0
    for (int qpRow = 0; qpRow < qpHeight; ++qpRow)
2068
0
      for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl, ++qpTable)
2069
0
        if (*qpTable / 6 >= 6)
2070
0
          *qStepTbl = q_step_tbl[*qpTable % 6] << ((*qpTable / 6 - 6) & 0x1f);
2071
0
        else
2072
0
          *qStepTbl = q_step_tbl[*qpTable % 6] >> (6 - *qpTable / 6);
2073
2074
0
    break;
2075
0
  }
2076
0
  return 0;
2077
0
}
2078
2079
libraw_inline void crxSetupSubbandIdx(crx_data_header_t *hdr, CrxImage * /*img*/, CrxSubband *band, int level,
2080
                                      short colStartIdx, short bandWidthExCoef, short rowStartIdx,
2081
                                      short bandHeightExCoef)
2082
0
{
2083
0
  if (hdr->version == 0x200)
2084
0
  {
2085
0
    band->rowStartAddOn = rowStartIdx;
2086
0
    band->rowEndAddOn = bandHeightExCoef;
2087
0
    band->colStartAddOn = colStartIdx;
2088
0
    band->colEndAddOn = bandWidthExCoef;
2089
0
    band->levelShift = 3 - level;
2090
0
  }
2091
0
  else
2092
0
  {
2093
0
    band->rowStartAddOn = 0;
2094
0
    band->rowEndAddOn = 0;
2095
0
    band->colStartAddOn = 0;
2096
0
    band->colEndAddOn = 0;
2097
0
    band->levelShift = 0;
2098
0
  }
2099
0
}
2100
2101
int crxProcessSubbands(crx_data_header_t *hdr, CrxImage *img, CrxTile *tile, CrxPlaneComp *comp)
2102
0
{
2103
0
  CrxSubband *band = comp->subBands + img->subbandCount - 1; // set to last band
2104
0
  uint32_t bandHeight = tile->height;
2105
0
  uint32_t bandWidth = tile->width;
2106
0
  int32_t bandWidthExCoef = 0;
2107
0
  int32_t bandHeightExCoef = 0;
2108
0
  if (img->levels)
2109
0
  {
2110
    // Build up subband sequences to crxDecode to a level in a header
2111
2112
    // Coefficient structure is a bit unclear and convoluted:
2113
    //   3 levels max - 8 groups (for tile width rounded to 8 bytes)
2114
    //                  of 3 band per level 4 sets of coefficients for each
2115
0
    int32_t *rowExCoef = exCoefNumTbl + 0x30 * (img->levels - 1) + 6 * (tile->width & 7);
2116
0
    int32_t *colExCoef = exCoefNumTbl + 0x30 * (img->levels - 1) + 6 * (tile->height & 7);
2117
0
    for (int level = 0; level < img->levels; ++level)
2118
0
    {
2119
0
      int32_t widthOddPixel = bandWidth & 1;
2120
0
      int32_t heightOddPixel = bandHeight & 1;
2121
0
      bandWidth = (widthOddPixel + bandWidth) >> 1;
2122
0
      bandHeight = (heightOddPixel + bandHeight) >> 1;
2123
2124
0
      int32_t bandWidthExCoef0 = 0;
2125
0
      int32_t bandWidthExCoef1 = 0;
2126
0
      int32_t bandHeightExCoef0 = 0;
2127
0
      int32_t bandHeightExCoef1 = 0;
2128
0
      int32_t colStartIdx = 0;
2129
0
      int32_t rowStartIdx = 0;
2130
0
      if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
2131
0
      {
2132
0
        bandWidthExCoef0 = rowExCoef[2 * level];
2133
0
        bandWidthExCoef1 = rowExCoef[2 * level + 1];
2134
0
      }
2135
0
      if (tile->tileFlag & E_HAS_TILES_ON_THE_LEFT)
2136
0
      {
2137
0
        ++bandWidthExCoef0;
2138
0
        colStartIdx = 1;
2139
0
      }
2140
2141
0
      if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)
2142
0
      {
2143
0
        bandHeightExCoef0 = colExCoef[2 * level];
2144
0
        bandHeightExCoef1 = colExCoef[2 * level + 1];
2145
0
      }
2146
0
      if (tile->tileFlag & E_HAS_TILES_ON_THE_TOP)
2147
0
      {
2148
0
        ++bandHeightExCoef0;
2149
0
        rowStartIdx = 1;
2150
0
      }
2151
2152
0
      band[0].width = bandWidth + bandWidthExCoef0 - widthOddPixel;
2153
0
      band[0].height = bandHeight + bandHeightExCoef0 - heightOddPixel;
2154
0
      crxSetupSubbandIdx(hdr, img, band, level + 1, colStartIdx, bandWidthExCoef0 - colStartIdx, rowStartIdx,
2155
0
                         bandHeightExCoef0 - rowStartIdx);
2156
2157
0
      band[-1].width = bandWidth + bandWidthExCoef1;
2158
0
      band[-1].height = bandHeight + bandHeightExCoef0 - heightOddPixel;
2159
2160
0
      crxSetupSubbandIdx(hdr, img, band - 1, level + 1, 0, bandWidthExCoef1, rowStartIdx,
2161
0
                         bandHeightExCoef0 - rowStartIdx);
2162
2163
0
      band[-2].width = bandWidth + bandWidthExCoef0 - widthOddPixel;
2164
0
      band[-2].height = bandHeight + bandHeightExCoef1;
2165
0
      crxSetupSubbandIdx(hdr, img, band - 2, level + 1, colStartIdx, bandWidthExCoef0 - colStartIdx, 0,
2166
0
                         bandHeightExCoef1);
2167
2168
0
      band -= 3;
2169
0
    }
2170
0
    bandWidthExCoef = bandHeightExCoef = 0;
2171
0
    if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
2172
0
      bandWidthExCoef = rowExCoef[2 * img->levels - 1];
2173
0
    if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)
2174
0
      bandHeightExCoef = colExCoef[2 * img->levels - 1];
2175
0
  }
2176
0
  band->width = bandWidthExCoef + bandWidth;
2177
0
  band->height = bandHeightExCoef + bandHeight;
2178
0
  if (img->levels)
2179
0
    crxSetupSubbandIdx(hdr, img, band, img->levels, 0, bandWidthExCoef, 0, bandHeightExCoef);
2180
2181
0
  return 0;
2182
0
}
2183
2184
int crxReadSubbandHeaders(crx_data_header_t * /*hdr*/, CrxImage *img, CrxTile * /*tile*/, CrxPlaneComp *comp,
2185
                          uint8_t **subbandMdatPtr, int32_t *mdatSize)
2186
0
{
2187
0
  if (!img->subbandCount)
2188
0
    return 0;
2189
0
  int32_t subbandOffset = 0;
2190
0
  CrxSubband *band = comp->subBands;
2191
0
  for (int curSubband = 0; curSubband < img->subbandCount; curSubband++, band++)
2192
0
  {
2193
0
    if (*mdatSize < 4)
2194
0
      return -1;
2195
2196
0
    int hdrSign = LibRaw::sgetn(2, *subbandMdatPtr);
2197
0
    int hdrSize = LibRaw::sgetn(2, *subbandMdatPtr + 2);
2198
0
    if (*mdatSize < hdrSize + 4)
2199
0
      return -1;
2200
0
    if ((hdrSign != 0xFF03 || hdrSize != 8) && (hdrSign != 0xFF13 || hdrSize != 16))
2201
0
      return -1;
2202
2203
0
    int32_t subbandSize = LibRaw::sgetn(4, *subbandMdatPtr + 4);
2204
2205
0
    if (curSubband != ((*subbandMdatPtr)[8] & 0xF0) >> 4)
2206
0
    {
2207
0
      band->dataSize = subbandSize;
2208
0
      return -1;
2209
0
    }
2210
2211
0
    band->dataOffset = subbandOffset;
2212
0
    band->kParam = 0;
2213
0
    band->bandParam = 0;
2214
0
    band->bandBuf = 0;
2215
0
    band->bandSize = 0;
2216
2217
0
    if (hdrSign == 0xFF03)
2218
0
    {
2219
      // old header
2220
0
      uint32_t bitData = LibRaw::sgetn(4, *subbandMdatPtr + 8);
2221
0
      band->dataSize = subbandSize - (bitData & 0x7FFFF);
2222
0
      band->supportsPartial = bitData & 0x8000000;
2223
0
      band->qParam = (bitData >> 19) & 0xFF;
2224
0
      band->qStepBase = 0;
2225
0
      band->qStepMult = 0;
2226
0
    }
2227
0
    else
2228
0
    {
2229
      // new header
2230
0
      if (LibRaw::sgetn(2, *subbandMdatPtr + 8) & 0xFFF)
2231
        // partial and qParam are not supported
2232
0
        return -1;
2233
0
      if (LibRaw::sgetn(2, *subbandMdatPtr + 18))
2234
        // new header terninated by 2 zero bytes
2235
0
        return -1;
2236
0
      band->supportsPartial = false;
2237
0
      band->qParam = 0;
2238
0
      band->dataSize = subbandSize - LibRaw::sgetn(2, *subbandMdatPtr + 16);
2239
0
      band->qStepBase = LibRaw::sgetn(4, *subbandMdatPtr + 12);
2240
0
      ;
2241
0
      band->qStepMult = LibRaw::sgetn(2, *subbandMdatPtr + 10);
2242
0
      ;
2243
0
    }
2244
2245
0
    subbandOffset += subbandSize;
2246
2247
0
    *subbandMdatPtr += hdrSize + 4;
2248
0
    *mdatSize -= hdrSize + 4;
2249
0
  }
2250
2251
0
  return 0;
2252
0
}
2253
2254
int crxReadImageHeaders(crx_data_header_t *hdr, CrxImage *img, uint8_t *mdatPtr, int32_t mdatHdrSize)
2255
0
{
2256
0
  int nTiles = img->tileRows * img->tileCols;
2257
2258
0
  if (!nTiles)
2259
0
    return -1;
2260
2261
0
  if (!img->tiles)
2262
0
  {
2263
0
      img->tiles = (CrxTile *)
2264
0
#ifdef LIBRAW_CR3_MEMPOOL
2265
0
                       img->memmgr.
2266
0
#endif
2267
0
                   calloc(sizeof(CrxTile) * nTiles + sizeof(CrxPlaneComp) * nTiles * img->nPlanes +
2268
0
                              sizeof(CrxSubband) * nTiles * img->nPlanes * img->subbandCount,
2269
0
                          1);
2270
0
    if (!img->tiles)
2271
0
      return -1;
2272
2273
    // memory areas in allocated chunk
2274
0
    CrxTile *tile = img->tiles;
2275
0
    CrxPlaneComp *comps = (CrxPlaneComp *)(tile + nTiles);
2276
0
    CrxSubband *bands = (CrxSubband *)(comps + img->nPlanes * nTiles);
2277
2278
0
    for (int curTile = 0; curTile < nTiles; curTile++, tile++)
2279
0
    {
2280
0
      tile->tileFlag = 0; // tile neighbouring flags
2281
0
      tile->tileNumber = curTile;
2282
0
      tile->tileSize = 0;
2283
0
      tile->comps = comps + curTile * img->nPlanes;
2284
2285
0
      if ((curTile + 1) % img->tileCols)
2286
0
      {
2287
        // not the last tile in a tile row
2288
0
        tile->width = hdr->tileWidth;
2289
0
        if (img->tileCols > 1)
2290
0
        {
2291
0
          tile->tileFlag = E_HAS_TILES_ON_THE_RIGHT;
2292
0
          if (curTile % img->tileCols)
2293
            // not the first tile in tile row
2294
0
            tile->tileFlag |= E_HAS_TILES_ON_THE_LEFT;
2295
0
        }
2296
0
      }
2297
0
      else
2298
0
      {
2299
        // last tile in a tile row
2300
0
        tile->width = img->planeWidth - hdr->tileWidth * (img->tileCols - 1);
2301
0
        if (img->tileCols > 1)
2302
0
          tile->tileFlag = E_HAS_TILES_ON_THE_LEFT;
2303
0
      }
2304
0
      if (curTile < nTiles - img->tileCols)
2305
0
      {
2306
        // in first tile row
2307
0
        tile->height = hdr->tileHeight;
2308
0
        if (img->tileRows > 1)
2309
0
        {
2310
0
          tile->tileFlag |= E_HAS_TILES_ON_THE_BOTTOM;
2311
0
          if (curTile >= img->tileCols)
2312
0
            tile->tileFlag |= E_HAS_TILES_ON_THE_TOP;
2313
0
        }
2314
0
      }
2315
0
      else
2316
0
      {
2317
        // non first tile row
2318
0
        tile->height = img->planeHeight - hdr->tileHeight * (img->tileRows - 1);
2319
0
        if (img->tileRows > 1)
2320
0
          tile->tileFlag |= E_HAS_TILES_ON_THE_TOP;
2321
0
      }
2322
0
      if (img->nPlanes)
2323
0
      {
2324
0
        CrxPlaneComp *comp = tile->comps;
2325
0
        CrxSubband *band = bands + curTile * img->nPlanes * img->subbandCount;
2326
2327
0
        for (int curComp = 0; curComp < img->nPlanes; curComp++, comp++)
2328
0
        {
2329
0
          comp->compNumber = curComp;
2330
0
          comp->supportsPartial = true;
2331
0
          comp->tileFlag = tile->tileFlag;
2332
0
          comp->subBands = band;
2333
0
          comp->compBuf = 0;
2334
0
          comp->wvltTransform = 0;
2335
0
          if (img->subbandCount)
2336
0
          {
2337
0
            for (int curBand = 0; curBand < img->subbandCount; curBand++, band++)
2338
0
            {
2339
0
              band->supportsPartial = false;
2340
0
              band->qParam = 4;
2341
0
              band->bandParam = 0;
2342
0
              band->dataSize = 0;
2343
0
            }
2344
0
          }
2345
0
        }
2346
0
      }
2347
0
    }
2348
0
  }
2349
2350
0
  uint32_t tileOffset = 0;
2351
0
  int32_t dataSize = mdatHdrSize;
2352
0
  uint8_t *dataPtr = mdatPtr;
2353
0
  CrxTile *tile = img->tiles;
2354
2355
0
  for (int curTile = 0; curTile < nTiles; ++curTile, ++tile)
2356
0
  {
2357
0
    if (dataSize < 4)
2358
0
      return -1;
2359
2360
0
    int hdrSign = LibRaw::sgetn(2, dataPtr);
2361
0
    int hdrSize = LibRaw::sgetn(2, dataPtr + 2);
2362
0
    if ((hdrSign != 0xFF01 || hdrSize != 8) && (hdrSign != 0xFF11 || (hdrSize != 8 && hdrSize != 16)))
2363
0
      return -1;
2364
0
    if (dataSize < hdrSize + 4)
2365
0
      return -1;
2366
0
    int tailSign = LibRaw::sgetn(2, dataPtr + 10);
2367
0
    if ((hdrSize == 8 && tailSign) || (hdrSize == 16 && tailSign != 0x4000))
2368
0
      return -1;
2369
0
    if (LibRaw::sgetn(2, dataPtr + 8) != (unsigned)curTile)
2370
0
      return -1;
2371
2372
0
    dataSize -= hdrSize + 4;
2373
2374
0
    tile->tileSize = LibRaw::sgetn(4, dataPtr + 4);
2375
0
    tile->dataOffset = tileOffset;
2376
0
    tile->qStep = 0;
2377
0
    if (hdrSize == 16)
2378
0
    {
2379
      // extended header data - terminated by 0 bytes
2380
0
      if (LibRaw::sgetn(2, dataPtr + 18) != 0)
2381
0
        return -1;
2382
0
      tile->hasQPData = true;
2383
0
      tile->mdatQPDataSize = LibRaw::sgetn(4, dataPtr + 12);
2384
0
      tile->mdatExtraSize = LibRaw::sgetn(2, dataPtr + 16);
2385
0
    }
2386
0
    else
2387
0
    {
2388
0
      tile->hasQPData = false;
2389
0
      tile->mdatQPDataSize = 0;
2390
0
      tile->mdatExtraSize = 0;
2391
0
    }
2392
2393
0
    dataPtr += hdrSize + 4;
2394
0
    tileOffset += tile->tileSize;
2395
2396
0
    uint32_t compOffset = 0;
2397
0
    CrxPlaneComp *comp = tile->comps;
2398
2399
0
    for (int compNum = 0; compNum < img->nPlanes; ++compNum, ++comp)
2400
0
    {
2401
0
      if (dataSize < 0xC)
2402
0
        return -1;
2403
0
      hdrSign = LibRaw::sgetn(2, dataPtr);
2404
0
      hdrSize = LibRaw::sgetn(2, dataPtr + 2);
2405
0
      if ((hdrSign != 0xFF02 && hdrSign != 0xFF12) || hdrSize != 8)
2406
0
        return -1;
2407
0
      if (compNum != dataPtr[8] >> 4)
2408
0
        return -1;
2409
0
      if (LibRaw::sgetn(3, dataPtr + 9) != 0)
2410
0
        return -1;
2411
2412
0
      comp->compSize = LibRaw::sgetn(4, dataPtr + 4);
2413
2414
0
      int32_t compHdrRoundedBits = (dataPtr[8] >> 1) & 3;
2415
0
      comp->supportsPartial = (dataPtr[8] & 8) != 0;
2416
2417
0
      comp->dataOffset = compOffset;
2418
0
      comp->tileFlag = tile->tileFlag;
2419
2420
0
      compOffset += comp->compSize;
2421
0
      dataSize -= 0xC;
2422
0
      dataPtr += 0xC;
2423
2424
0
      comp->roundedBitsMask = 0;
2425
2426
0
      if (compHdrRoundedBits)
2427
0
      {
2428
0
        if (img->levels || !comp->supportsPartial)
2429
0
          return -1;
2430
2431
0
        comp->roundedBitsMask = 1 << (compHdrRoundedBits - 1);
2432
0
      }
2433
2434
0
      if (crxReadSubbandHeaders(hdr, img, tile, comp, &dataPtr, &dataSize) || crxProcessSubbands(hdr, img, tile, comp))
2435
0
        return -1;
2436
0
    }
2437
0
  }
2438
2439
0
  if (hdr->version != 0x200)
2440
0
    return 0;
2441
2442
0
  tile = img->tiles;
2443
0
  for (int curTile = 0; curTile < nTiles; ++curTile, ++tile)
2444
0
  {
2445
0
    if (tile->hasQPData)
2446
0
    {
2447
0
      CrxBitstream bitStrm;
2448
0
      bitStrm.bitData = 0;
2449
0
      bitStrm.bitsLeft = 0;
2450
0
      bitStrm.curPos = 0;
2451
0
      bitStrm.curBufSize = 0;
2452
0
      bitStrm.mdatSize = tile->mdatQPDataSize;
2453
0
      bitStrm.curBufOffset = img->mdatOffset + tile->dataOffset;
2454
0
      bitStrm.input = img->input;
2455
2456
0
      crxFillBuffer(&bitStrm);
2457
2458
0
      unsigned int qpWidth = (tile->width >> 3) + ((tile->width & 7) != 0);
2459
0
      unsigned int qpHeight = (tile->height >> 1) + (tile->height & 1);
2460
0
      unsigned long totalQP = qpHeight * qpWidth;
2461
2462
0
      try
2463
0
      {
2464
0
        std::vector<int32_t> qpTable(totalQP + 2 * (qpWidth + 2));
2465
0
        int32_t *qpCurElem = qpTable.data();
2466
        // 2 lines padded with extra pixels at the start and at the end
2467
0
        int32_t *qpLineBuf = qpTable.data() + totalQP;
2468
0
        int32_t kParam = 0;
2469
0
        for (unsigned qpRow = 0; qpRow < qpHeight; ++qpRow)
2470
0
        {
2471
0
          int32_t *qpLine0 = qpRow & 1 ? qpLineBuf + qpWidth + 2 : qpLineBuf;
2472
0
          int32_t *qpLine1 = qpRow & 1 ? qpLineBuf : qpLineBuf + qpWidth + 2;
2473
2474
0
          if (qpRow)
2475
0
            crxDecodeGolombNormal(&bitStrm, qpWidth, qpLine0, qpLine1, &kParam);
2476
0
          else
2477
0
            crxDecodeGolombTop(&bitStrm, qpWidth, qpLine1, &kParam);
2478
2479
0
          for (unsigned qpCol = 0; qpCol < qpWidth; ++qpCol)
2480
0
            *qpCurElem++ = qpLine1[qpCol + 1] + 4;
2481
0
        }
2482
2483
        // now we read QP data - build tile QStep
2484
0
        if (crxMakeQStep(img, tile, qpTable.data(), totalQP))
2485
0
          return -1;
2486
0
      }
2487
0
      catch (...)
2488
0
      {
2489
0
        return -1;
2490
0
      }
2491
0
    }
2492
0
  }
2493
2494
0
  return 0;
2495
0
}
2496
2497
int crxSetupImageData(crx_data_header_t *hdr, CrxImage *img, int16_t *outBuf, int64_t mdatOffset, int64_t mdatSize,
2498
                      uint8_t *mdatHdrPtr, int32_t mdatHdrSize)
2499
0
{
2500
0
  int IncrBitTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0};
2501
2502
0
  img->planeWidth = hdr->f_width;
2503
0
  img->planeHeight = hdr->f_height;
2504
2505
0
  if (hdr->tileWidth < 0x16 || hdr->tileHeight < 0x16 || img->planeWidth > 0x7FFF || img->planeHeight > 0x7FFF)
2506
0
    return -1;
2507
2508
0
  img->tileCols = (img->planeWidth + hdr->tileWidth - 1) / hdr->tileWidth;
2509
0
  img->tileRows = (img->planeHeight + hdr->tileHeight - 1) / hdr->tileHeight;
2510
2511
0
  if (img->tileCols > 0xFF || img->tileRows > 0xFF || img->planeWidth - hdr->tileWidth * (img->tileCols - 1) < 0x16 ||
2512
0
      img->planeHeight - hdr->tileHeight * (img->tileRows - 1) < 0x16)
2513
0
    return -1;
2514
2515
0
  img->tiles = 0;
2516
0
  img->levels = hdr->imageLevels;
2517
0
  img->subbandCount = 3 * img->levels + 1; // 3 bands per level + one last LL
2518
0
  img->nPlanes = hdr->nPlanes;
2519
0
  img->nBits = hdr->nBits;
2520
0
  img->encType = hdr->encType;
2521
0
  img->samplePrecision = hdr->nBits + IncrBitTable[4 * hdr->encType + 2] + 1;
2522
0
  img->mdatOffset = mdatOffset + hdr->mdatHdrSize;
2523
0
  img->mdatSize = mdatSize;
2524
0
  img->planeBuf = 0;
2525
0
  img->outBufs[0] = img->outBufs[1] = img->outBufs[2] = img->outBufs[3] = 0;
2526
0
  img->medianBits = hdr->medianBits;
2527
2528
  // The encoding type 3 needs all 4 planes to be decoded to generate row of
2529
  // RGGB values. It seems to be using some other colour space for raw encoding
2530
  // It is a massive buffer so ideallly it will need a different approach:
2531
  // decode planes line by line and convert single line then without
2532
  // intermediate plane buffer. At the moment though it's too many changes so
2533
  // left as is.
2534
0
  if (img->encType == 3 && img->nPlanes == 4 && img->nBits > 8)
2535
0
  {
2536
0
      img->planeBuf = (int16_t *)
2537
0
#ifdef LIBRAW_CR3_MEMPOOL
2538
0
                          img->memmgr.
2539
0
#endif
2540
0
                      malloc(img->planeHeight * img->planeWidth * img->nPlanes * ((img->samplePrecision + 7) >> 3));
2541
0
    if (!img->planeBuf)
2542
0
      return -1;
2543
0
  }
2544
2545
0
  int32_t rowSize = 2 * img->planeWidth;
2546
2547
0
  if (img->nPlanes == 1)
2548
0
    img->outBufs[0] = outBuf;
2549
0
  else
2550
0
    switch (hdr->cfaLayout)
2551
0
    {
2552
0
    case 0:
2553
      // R G
2554
      // G B
2555
0
      img->outBufs[0] = outBuf;
2556
0
      img->outBufs[1] = outBuf + 1;
2557
0
      img->outBufs[2] = outBuf + rowSize;
2558
0
      img->outBufs[3] = img->outBufs[2] + 1;
2559
0
      break;
2560
0
    case 1:
2561
      // G R
2562
      // B G
2563
0
      img->outBufs[1] = outBuf;
2564
0
      img->outBufs[0] = outBuf + 1;
2565
0
      img->outBufs[3] = outBuf + rowSize;
2566
0
      img->outBufs[2] = img->outBufs[3] + 1;
2567
0
      break;
2568
0
    case 2:
2569
      // G B
2570
      // R G
2571
0
      img->outBufs[2] = outBuf;
2572
0
      img->outBufs[3] = outBuf + 1;
2573
0
      img->outBufs[0] = outBuf + rowSize;
2574
0
      img->outBufs[1] = img->outBufs[0] + 1;
2575
0
      break;
2576
0
    case 3:
2577
      // B G
2578
      // G R
2579
0
      img->outBufs[3] = outBuf;
2580
0
      img->outBufs[2] = outBuf + 1;
2581
0
      img->outBufs[1] = outBuf + rowSize;
2582
0
      img->outBufs[0] = img->outBufs[1] + 1;
2583
0
      break;
2584
0
    }
2585
2586
  // read header
2587
0
  return crxReadImageHeaders(hdr, img, mdatHdrPtr, mdatHdrSize);
2588
0
}
2589
2590
int crxFreeImageData(CrxImage *img)
2591
0
{
2592
0
#ifdef LIBRAW_CR3_MEMPOOL
2593
0
  img->memmgr.cleanup();
2594
#else
2595
  CrxTile *tile = img->tiles;
2596
  int nTiles = img->tileRows * img->tileCols;
2597
2598
  if (img->tiles)
2599
  {
2600
    for (int32_t curTile = 0; curTile < nTiles; curTile++)
2601
    {
2602
      if (tile[curTile].comps)
2603
        for (int32_t curPlane = 0; curPlane < img->nPlanes; curPlane++)
2604
          crxFreeSubbandData(img, tile[curTile].comps + curPlane);
2605
      if (tile[curTile].qStep)
2606
        free(tile[curTile].qStep);
2607
    }
2608
    free(img->tiles);
2609
    img->tiles = 0;
2610
  }
2611
2612
  if (img->planeBuf)
2613
  {
2614
    free(img->planeBuf);
2615
    img->planeBuf = 0;
2616
  }
2617
#endif
2618
0
  return 0;
2619
0
}
2620
void LibRaw::crxLoadDecodeLoop(void *img, int nPlanes)
2621
0
{
2622
#ifdef LIBRAW_USE_OPENMP
2623
  int results[4] ={0,0,0,0}; // nPlanes is always <= 4
2624
#pragma omp parallel for
2625
  for (int32_t plane = 0; plane < nPlanes; ++plane)
2626
   try {
2627
    results[plane] = crxDecodePlane(img, plane);
2628
   } catch (...) {
2629
    results[plane] = 1;
2630
   }
2631
2632
  for (int32_t plane = 0; plane < nPlanes; ++plane)
2633
    if (results[plane])
2634
      derror();
2635
#else
2636
0
  for (int32_t plane = 0; plane < nPlanes; ++plane)
2637
0
    if (crxDecodePlane(img, plane))
2638
0
      derror();
2639
0
#endif
2640
0
}
2641
2642
0
void LibRaw::crxConvertPlaneLineDf(void *p, int imageRow) { crxConvertPlaneLine((CrxImage *)p, imageRow); }
2643
2644
void LibRaw::crxLoadFinalizeLoopE3(void *p, int planeHeight)
2645
0
{
2646
#ifdef LIBRAW_USE_OPENMP
2647
#pragma omp parallel for
2648
#endif
2649
0
  for (int i = 0; i < planeHeight; ++i)
2650
0
    crxConvertPlaneLineDf(p, i);
2651
0
}
2652
2653
void LibRaw::crxLoadRaw()
2654
0
{
2655
0
  CrxImage img;
2656
0
  if (libraw_internal_data.unpacker_data.crx_track_selected < 0 ||
2657
0
      libraw_internal_data.unpacker_data.crx_track_selected >= LIBRAW_CRXTRACKS_MAXCOUNT)
2658
0
    derror();
2659
2660
0
  crx_data_header_t hdr =
2661
0
      libraw_internal_data.unpacker_data.crx_header[libraw_internal_data.unpacker_data.crx_track_selected];
2662
2663
0
  if (libraw_internal_data.unpacker_data.data_size < (unsigned)hdr.mdatHdrSize)
2664
0
    derror();
2665
2666
0
  img.input = libraw_internal_data.internal_data.input;
2667
2668
  // update sizes for the planes
2669
0
  if (hdr.nPlanes == 4)
2670
0
  {
2671
0
    hdr.f_width >>= 1;
2672
0
    hdr.f_height >>= 1;
2673
0
    hdr.tileWidth >>= 1;
2674
0
    hdr.tileHeight >>= 1;
2675
0
  }
2676
2677
0
  imgdata.color.maximum = (1 << hdr.nBits) - 1;
2678
2679
0
  std::vector<uint8_t> hdrBuf(hdr.mdatHdrSize);
2680
2681
0
  int bytes = 0;
2682
  // read image header
2683
#ifdef LIBRAW_USE_OPENMP
2684
#pragma omp critical
2685
#endif
2686
0
  {
2687
0
#ifndef LIBRAW_USE_OPENMP
2688
0
    libraw_internal_data.internal_data.input->lock();
2689
0
#endif
2690
0
    libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
2691
0
    bytes = libraw_internal_data.internal_data.input->read(hdrBuf.data(), 1, hdr.mdatHdrSize);
2692
0
#ifndef LIBRAW_USE_OPENMP
2693
0
    libraw_internal_data.internal_data.input->unlock();
2694
0
#endif
2695
0
  }
2696
2697
0
  if (bytes != hdr.mdatHdrSize)
2698
0
    throw LIBRAW_EXCEPTION_IO_EOF;
2699
2700
  // parse and setup the image data
2701
0
  if (crxSetupImageData(&hdr, &img, (int16_t *)imgdata.rawdata.raw_image,
2702
0
    libraw_internal_data.unpacker_data.data_offset, libraw_internal_data.unpacker_data.data_size,
2703
0
    hdrBuf.data(), hdr.mdatHdrSize))
2704
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
2705
2706
0
  crxLoadDecodeLoop(&img, hdr.nPlanes);
2707
2708
0
  if (img.encType == 3)
2709
0
    crxLoadFinalizeLoopE3(&img, img.planeHeight);
2710
2711
0
  crxFreeImageData(&img);
2712
0
}
2713
2714
int LibRaw::crxParseImageHeader(uchar *cmp1TagData, int nTrack, INT64 size)
2715
0
{
2716
0
  if (nTrack < 0 || nTrack >= LIBRAW_CRXTRACKS_MAXCOUNT || size < 32)
2717
0
    return -1;
2718
0
  if (!cmp1TagData)
2719
0
    return -1;
2720
2721
0
  crx_data_header_t *hdr = &libraw_internal_data.unpacker_data.crx_header[nTrack];
2722
2723
0
  hdr->version = sgetn(2, cmp1TagData + 4);
2724
0
  hdr->f_width = sgetn(4, cmp1TagData + 8);
2725
0
  hdr->f_height = sgetn(4, cmp1TagData + 12);
2726
0
  hdr->tileWidth = sgetn(4, cmp1TagData + 16);
2727
0
  hdr->tileHeight = sgetn(4, cmp1TagData + 20);
2728
0
  hdr->nBits = cmp1TagData[24];
2729
0
  hdr->nPlanes = cmp1TagData[25] >> 4;
2730
0
  hdr->cfaLayout = cmp1TagData[25] & 0xF;
2731
0
  hdr->encType = cmp1TagData[26] >> 4;
2732
0
  hdr->imageLevels = cmp1TagData[26] & 0xF;
2733
0
  hdr->hasTileCols = cmp1TagData[27] >> 7;
2734
0
  hdr->hasTileRows = (cmp1TagData[27] >> 6) & 1;
2735
0
  hdr->mdatHdrSize = sgetn(4, cmp1TagData + 28);
2736
0
  int extHeader = cmp1TagData[32] >> 7;
2737
0
  int useMedianBits = 0;
2738
0
  hdr->medianBits = hdr->nBits;
2739
2740
0
  if (extHeader && size >= 56 && hdr->nPlanes == 4)
2741
0
    useMedianBits = cmp1TagData[56] >> 6 & 1;
2742
2743
0
  if (useMedianBits && size >= 84)
2744
0
    hdr->medianBits = cmp1TagData[84];
2745
2746
  // validation
2747
0
  if ((hdr->version != 0x100 && hdr->version != 0x200) || !hdr->mdatHdrSize)
2748
0
    return -1;
2749
0
  if (hdr->encType == 1)
2750
0
  {
2751
0
    if (hdr->nBits > 15)
2752
0
      return -1;
2753
0
  }
2754
0
  else
2755
0
  {
2756
0
    if (hdr->encType && hdr->encType != 3)
2757
0
      return -1;
2758
0
    if (hdr->nBits > 14)
2759
0
      return -1;
2760
0
  }
2761
2762
0
  if (hdr->nPlanes == 1)
2763
0
  {
2764
0
    if (hdr->cfaLayout || hdr->encType || hdr->nBits != 8)
2765
0
      return -1;
2766
0
  }
2767
0
  else if (hdr->nPlanes != 4 || hdr->f_width & 1 || hdr->f_height & 1 || hdr->tileWidth & 1 || hdr->tileHeight & 1 ||
2768
0
           hdr->cfaLayout > 3 || hdr->nBits == 8)
2769
0
    return -1;
2770
2771
0
  if (hdr->tileWidth > hdr->f_width || hdr->tileHeight > hdr->f_height)
2772
0
    return -1;
2773
2774
0
  if (hdr->imageLevels > 3 || hdr->hasTileCols > 1 || hdr->hasTileRows > 1)
2775
0
    return -1;
2776
0
  return 0;
2777
0
}
2778
2779
#undef _abs
2780
#undef _min
2781
#undef _constrain
2782
#undef libraw_inline