Coverage Report

Created: 2024-07-23 06:29

/src/libraw/src/decoders/crx.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- C++ -*-
2
 * File: libraw_crxdec.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
  uint64_t mdatSize;
58
  uint64_t 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
  uint64_t 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
  uint64_t dataSize;
112
  int64_t 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_t 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 = nextData << (32 - nonZeroBit);
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 = nextData << (32 - nonZeroBit);
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, uint32_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
0
    tile->qStep = (CrxQStep *)
2007
0
#ifdef LIBRAW_CR3_MEMPOOL
2008
0
                      img->memmgr.
2009
0
#endif
2010
0
                  malloc(totalHeight * qpWidth * sizeof(uint32_t) + img->levels * sizeof(CrxQStep));
2011
2012
0
  if (!tile->qStep)
2013
0
    return -1;
2014
0
  uint32_t *qStepTbl = (uint32_t *)(tile->qStep + img->levels);
2015
0
  CrxQStep *qStep = tile->qStep;
2016
0
  switch (img->levels)
2017
0
  {
2018
0
  case 3:
2019
0
    qStep->qStepTbl = qStepTbl;
2020
0
    qStep->width = qpWidth;
2021
0
    qStep->height = qpHeight8;
2022
0
    for (int qpRow = 0; qpRow < qpHeight8; ++qpRow)
2023
0
    {
2024
0
      int row0Idx = qpWidth * _min(4 * qpRow, qpHeight - 1);
2025
0
      int row1Idx = qpWidth * _min(4 * qpRow + 1, qpHeight - 1);
2026
0
      int row2Idx = qpWidth * _min(4 * qpRow + 2, qpHeight - 1);
2027
0
      int row3Idx = qpWidth * _min(4 * qpRow + 3, qpHeight - 1);
2028
2029
0
      for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl)
2030
0
      {
2031
0
        int32_t quantVal = qpTable[row0Idx++] + qpTable[row1Idx++] + qpTable[row2Idx++] + qpTable[row3Idx++];
2032
        // not sure about this nonsense - why is it not just avg like with 2 levels?
2033
0
        quantVal = ((quantVal < 0) * 3 + quantVal) >> 2;
2034
0
        if (quantVal / 6 >= 6)
2035
0
          *qStepTbl = q_step_tbl[quantVal % 6] * (1 << ((quantVal / 6 - 6 ) & 0x1f));
2036
0
        else
2037
0
          *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6);
2038
0
      }
2039
0
    }
2040
    // continue to the next level - we always decode all levels
2041
0
    ++qStep;
2042
0
  case 2:
2043
0
    qStep->qStepTbl = qStepTbl;
2044
0
    qStep->width = qpWidth;
2045
0
    qStep->height = qpHeight4;
2046
0
    for (int qpRow = 0; qpRow < qpHeight4; ++qpRow)
2047
0
    {
2048
0
      int row0Idx = qpWidth * _min(2 * qpRow, qpHeight - 1);
2049
0
      int row1Idx = qpWidth * _min(2 * qpRow + 1, qpHeight - 1);
2050
2051
0
      for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl)
2052
0
      {
2053
0
        int32_t quantVal = (qpTable[row0Idx++] + qpTable[row1Idx++]) / 2;
2054
0
        if (quantVal / 6 >= 6)
2055
0
          *qStepTbl = q_step_tbl[quantVal % 6] * (1 << ((quantVal / 6 - 6) & 0x1f));
2056
0
        else
2057
0
          *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6);
2058
0
      }
2059
0
    }
2060
    // continue to the next level - we always decode all levels
2061
0
    ++qStep;
2062
0
  case 1:
2063
0
    qStep->qStepTbl = qStepTbl;
2064
0
    qStep->width = qpWidth;
2065
0
    qStep->height = qpHeight;
2066
0
    for (int qpRow = 0; qpRow < qpHeight; ++qpRow)
2067
0
      for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl, ++qpTable)
2068
0
        if (*qpTable / 6 >= 6)
2069
0
          *qStepTbl = q_step_tbl[*qpTable % 6] * (1 << ((*qpTable / 6 - 6) & 0x1f));
2070
0
        else
2071
0
          *qStepTbl = q_step_tbl[*qpTable % 6] >> (6 - *qpTable / 6);
2072
2073
0
    break;
2074
0
  }
2075
0
  return 0;
2076
0
}
2077
2078
libraw_inline void crxSetupSubbandIdx(crx_data_header_t *hdr, CrxImage * /*img*/, CrxSubband *band, int level,
2079
                                      short colStartIdx, short bandWidthExCoef, short rowStartIdx,
2080
                                      short bandHeightExCoef)
2081
0
{
2082
0
  if (hdr->version == 0x200)
2083
0
  {
2084
0
    band->rowStartAddOn = rowStartIdx;
2085
0
    band->rowEndAddOn = bandHeightExCoef;
2086
0
    band->colStartAddOn = colStartIdx;
2087
0
    band->colEndAddOn = bandWidthExCoef;
2088
0
    band->levelShift = 3 - level;
2089
0
  }
2090
0
  else
2091
0
  {
2092
0
    band->rowStartAddOn = 0;
2093
0
    band->rowEndAddOn = 0;
2094
0
    band->colStartAddOn = 0;
2095
0
    band->colEndAddOn = 0;
2096
0
    band->levelShift = 0;
2097
0
  }
2098
0
}
2099
2100
int crxProcessSubbands(crx_data_header_t *hdr, CrxImage *img, CrxTile *tile, CrxPlaneComp *comp)
2101
0
{
2102
0
  CrxSubband *band = comp->subBands + img->subbandCount - 1; // set to last band
2103
0
  uint32_t bandHeight = tile->height;
2104
0
  uint32_t bandWidth = tile->width;
2105
0
  int32_t bandWidthExCoef = 0;
2106
0
  int32_t bandHeightExCoef = 0;
2107
0
  if (img->levels)
2108
0
  {
2109
    // Build up subband sequences to crxDecode to a level in a header
2110
2111
    // Coefficient structure is a bit unclear and convoluted:
2112
    //   3 levels max - 8 groups (for tile width rounded to 8 bytes)
2113
    //                  of 3 band per level 4 sets of coefficients for each
2114
0
    int32_t *rowExCoef = exCoefNumTbl + 0x30 * (img->levels - 1) + 6 * (tile->width & 7);
2115
0
    int32_t *colExCoef = exCoefNumTbl + 0x30 * (img->levels - 1) + 6 * (tile->height & 7);
2116
0
    for (int level = 0; level < img->levels; ++level)
2117
0
    {
2118
0
      int32_t widthOddPixel = bandWidth & 1;
2119
0
      int32_t heightOddPixel = bandHeight & 1;
2120
0
      bandWidth = (widthOddPixel + bandWidth) >> 1;
2121
0
      bandHeight = (heightOddPixel + bandHeight) >> 1;
2122
2123
0
      int32_t bandWidthExCoef0 = 0;
2124
0
      int32_t bandWidthExCoef1 = 0;
2125
0
      int32_t bandHeightExCoef0 = 0;
2126
0
      int32_t bandHeightExCoef1 = 0;
2127
0
      int32_t colStartIdx = 0;
2128
0
      int32_t rowStartIdx = 0;
2129
0
      if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
2130
0
      {
2131
0
        bandWidthExCoef0 = rowExCoef[2 * level];
2132
0
        bandWidthExCoef1 = rowExCoef[2 * level + 1];
2133
0
      }
2134
0
      if (tile->tileFlag & E_HAS_TILES_ON_THE_LEFT)
2135
0
      {
2136
0
        ++bandWidthExCoef0;
2137
0
        colStartIdx = 1;
2138
0
      }
2139
2140
0
      if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)
2141
0
      {
2142
0
        bandHeightExCoef0 = colExCoef[2 * level];
2143
0
        bandHeightExCoef1 = colExCoef[2 * level + 1];
2144
0
      }
2145
0
      if (tile->tileFlag & E_HAS_TILES_ON_THE_TOP)
2146
0
      {
2147
0
        ++bandHeightExCoef0;
2148
0
        rowStartIdx = 1;
2149
0
      }
2150
2151
0
      band[0].width = bandWidth + bandWidthExCoef0 - widthOddPixel;
2152
0
      band[0].height = bandHeight + bandHeightExCoef0 - heightOddPixel;
2153
0
      crxSetupSubbandIdx(hdr, img, band, level + 1, colStartIdx, bandWidthExCoef0 - colStartIdx, rowStartIdx,
2154
0
                         bandHeightExCoef0 - rowStartIdx);
2155
2156
0
      band[-1].width = bandWidth + bandWidthExCoef1;
2157
0
      band[-1].height = bandHeight + bandHeightExCoef0 - heightOddPixel;
2158
2159
0
      crxSetupSubbandIdx(hdr, img, band - 1, level + 1, 0, bandWidthExCoef1, rowStartIdx,
2160
0
                         bandHeightExCoef0 - rowStartIdx);
2161
2162
0
      band[-2].width = bandWidth + bandWidthExCoef0 - widthOddPixel;
2163
0
      band[-2].height = bandHeight + bandHeightExCoef1;
2164
0
      crxSetupSubbandIdx(hdr, img, band - 2, level + 1, colStartIdx, bandWidthExCoef0 - colStartIdx, 0,
2165
0
                         bandHeightExCoef1);
2166
2167
0
      band -= 3;
2168
0
    }
2169
0
    bandWidthExCoef = bandHeightExCoef = 0;
2170
0
    if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
2171
0
      bandWidthExCoef = rowExCoef[2 * img->levels - 1];
2172
0
    if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)
2173
0
      bandHeightExCoef = colExCoef[2 * img->levels - 1];
2174
0
  }
2175
0
  band->width = bandWidthExCoef + bandWidth;
2176
0
  band->height = bandHeightExCoef + bandHeight;
2177
0
  if (img->levels)
2178
0
    crxSetupSubbandIdx(hdr, img, band, img->levels, 0, bandWidthExCoef, 0, bandHeightExCoef);
2179
2180
0
  return 0;
2181
0
}
2182
2183
int crxReadSubbandHeaders(crx_data_header_t * /*hdr*/, CrxImage *img, CrxTile * /*tile*/, CrxPlaneComp *comp,
2184
                          uint8_t **subbandMdatPtr, int32_t *mdatSize)
2185
0
{
2186
0
  if (!img->subbandCount)
2187
0
    return 0;
2188
0
  int32_t subbandOffset = 0;
2189
0
  CrxSubband *band = comp->subBands;
2190
0
  for (int curSubband = 0; curSubband < img->subbandCount; curSubband++, band++)
2191
0
  {
2192
0
    if (*mdatSize < 4)
2193
0
      return -1;
2194
2195
0
    int hdrSign = LibRaw::sgetn(2, *subbandMdatPtr);
2196
0
    int hdrSize = LibRaw::sgetn(2, *subbandMdatPtr + 2);
2197
0
    if (*mdatSize < hdrSize + 4)
2198
0
      return -1;
2199
0
    if ((hdrSign != 0xFF03 || hdrSize != 8) && (hdrSign != 0xFF13 || hdrSize != 16))
2200
0
      return -1;
2201
2202
0
    int32_t subbandSize = LibRaw::sgetn(4, *subbandMdatPtr + 4);
2203
2204
0
    if (curSubband != ((*subbandMdatPtr)[8] & 0xF0) >> 4)
2205
0
    {
2206
0
      band->dataSize = subbandSize;
2207
0
      return -1;
2208
0
    }
2209
2210
0
    band->dataOffset = subbandOffset;
2211
0
    band->kParam = 0;
2212
0
    band->bandParam = 0;
2213
0
    band->bandBuf = 0;
2214
0
    band->bandSize = 0;
2215
2216
0
    if (hdrSign == 0xFF03)
2217
0
    {
2218
      // old header
2219
0
      uint32_t bitData = LibRaw::sgetn(4, *subbandMdatPtr + 8);
2220
0
      band->dataSize = subbandSize - (bitData & 0x7FFFF);
2221
0
      band->supportsPartial = bitData & 0x8000000;
2222
0
      band->qParam = (bitData >> 19) & 0xFF;
2223
0
      band->qStepBase = 0;
2224
0
      band->qStepMult = 0;
2225
0
    }
2226
0
    else
2227
0
    {
2228
      // new header
2229
0
      if (LibRaw::sgetn(2, *subbandMdatPtr + 8) & 0xFFF)
2230
        // partial and qParam are not supported
2231
0
        return -1;
2232
0
      if (LibRaw::sgetn(2, *subbandMdatPtr + 18))
2233
        // new header terninated by 2 zero bytes
2234
0
        return -1;
2235
0
      band->supportsPartial = false;
2236
0
      band->qParam = 0;
2237
0
      band->dataSize = subbandSize - LibRaw::sgetn(2, *subbandMdatPtr + 16);
2238
0
      band->qStepBase = LibRaw::sgetn(4, *subbandMdatPtr + 12);
2239
0
      ;
2240
0
      band->qStepMult = LibRaw::sgetn(2, *subbandMdatPtr + 10);
2241
0
      ;
2242
0
    }
2243
2244
0
    subbandOffset += subbandSize;
2245
2246
0
    *subbandMdatPtr += hdrSize + 4;
2247
0
    *mdatSize -= hdrSize + 4;
2248
0
  }
2249
2250
0
  return 0;
2251
0
}
2252
2253
int crxReadImageHeaders(crx_data_header_t *hdr, CrxImage *img, uint8_t *mdatPtr, int32_t mdatHdrSize)
2254
0
{
2255
0
  int nTiles = img->tileRows * img->tileCols;
2256
2257
0
  if (!nTiles)
2258
0
    return -1;
2259
2260
0
  if (!img->tiles)
2261
0
  {
2262
0
      img->tiles = (CrxTile *)
2263
0
#ifdef LIBRAW_CR3_MEMPOOL
2264
0
                       img->memmgr.
2265
0
#endif
2266
0
                   calloc(sizeof(CrxTile) * nTiles + sizeof(CrxPlaneComp) * nTiles * img->nPlanes +
2267
0
                              sizeof(CrxSubband) * nTiles * img->nPlanes * img->subbandCount,
2268
0
                          1);
2269
0
    if (!img->tiles)
2270
0
      return -1;
2271
2272
    // memory areas in allocated chunk
2273
0
    CrxTile *tile = img->tiles;
2274
0
    CrxPlaneComp *comps = (CrxPlaneComp *)(tile + nTiles);
2275
0
    CrxSubband *bands = (CrxSubband *)(comps + img->nPlanes * nTiles);
2276
2277
0
    for (int curTile = 0; curTile < nTiles; curTile++, tile++)
2278
0
    {
2279
0
      tile->tileFlag = 0; // tile neighbouring flags
2280
0
      tile->tileNumber = curTile;
2281
0
      tile->tileSize = 0;
2282
0
      tile->comps = comps + curTile * img->nPlanes;
2283
2284
0
      if ((curTile + 1) % img->tileCols)
2285
0
      {
2286
        // not the last tile in a tile row
2287
0
        tile->width = hdr->tileWidth;
2288
0
        if (img->tileCols > 1)
2289
0
        {
2290
0
          tile->tileFlag = E_HAS_TILES_ON_THE_RIGHT;
2291
0
          if (curTile % img->tileCols)
2292
            // not the first tile in tile row
2293
0
            tile->tileFlag |= E_HAS_TILES_ON_THE_LEFT;
2294
0
        }
2295
0
      }
2296
0
      else
2297
0
      {
2298
        // last tile in a tile row
2299
0
        tile->width = img->planeWidth - hdr->tileWidth * (img->tileCols - 1);
2300
0
        if (img->tileCols > 1)
2301
0
          tile->tileFlag = E_HAS_TILES_ON_THE_LEFT;
2302
0
      }
2303
0
      if (curTile < nTiles - img->tileCols)
2304
0
      {
2305
        // in first tile row
2306
0
        tile->height = hdr->tileHeight;
2307
0
        if (img->tileRows > 1)
2308
0
        {
2309
0
          tile->tileFlag |= E_HAS_TILES_ON_THE_BOTTOM;
2310
0
          if (curTile >= img->tileCols)
2311
0
            tile->tileFlag |= E_HAS_TILES_ON_THE_TOP;
2312
0
        }
2313
0
      }
2314
0
      else
2315
0
      {
2316
        // non first tile row
2317
0
        tile->height = img->planeHeight - hdr->tileHeight * (img->tileRows - 1);
2318
0
        if (img->tileRows > 1)
2319
0
          tile->tileFlag |= E_HAS_TILES_ON_THE_TOP;
2320
0
      }
2321
0
      if (img->nPlanes)
2322
0
      {
2323
0
        CrxPlaneComp *comp = tile->comps;
2324
0
        CrxSubband *band = bands + curTile * img->nPlanes * img->subbandCount;
2325
2326
0
        for (int curComp = 0; curComp < img->nPlanes; curComp++, comp++)
2327
0
        {
2328
0
          comp->compNumber = curComp;
2329
0
          comp->supportsPartial = true;
2330
0
          comp->tileFlag = tile->tileFlag;
2331
0
          comp->subBands = band;
2332
0
          comp->compBuf = 0;
2333
0
          comp->wvltTransform = 0;
2334
0
          if (img->subbandCount)
2335
0
          {
2336
0
            for (int curBand = 0; curBand < img->subbandCount; curBand++, band++)
2337
0
            {
2338
0
              band->supportsPartial = false;
2339
0
              band->qParam = 4;
2340
0
              band->bandParam = 0;
2341
0
              band->dataSize = 0;
2342
0
            }
2343
0
          }
2344
0
        }
2345
0
      }
2346
0
    }
2347
0
  }
2348
2349
0
  uint32_t tileOffset = 0;
2350
0
  int32_t dataSize = mdatHdrSize;
2351
0
  uint8_t *dataPtr = mdatPtr;
2352
0
  CrxTile *tile = img->tiles;
2353
2354
0
  for (int curTile = 0; curTile < nTiles; ++curTile, ++tile)
2355
0
  {
2356
0
    if (dataSize < 4)
2357
0
      return -1;
2358
2359
0
    int hdrSign = LibRaw::sgetn(2, dataPtr);
2360
0
    int hdrSize = LibRaw::sgetn(2, dataPtr + 2);
2361
0
    if ((hdrSign != 0xFF01 || hdrSize != 8) && (hdrSign != 0xFF11 || (hdrSize != 8 && hdrSize != 16)))
2362
0
      return -1;
2363
0
    if (dataSize < hdrSize + 4)
2364
0
      return -1;
2365
0
    int tailSign = LibRaw::sgetn(2, dataPtr + 10);
2366
0
    if ((hdrSize == 8 && tailSign) || (hdrSize == 16 && tailSign != 0x4000))
2367
0
      return -1;
2368
0
    if (LibRaw::sgetn(2, dataPtr + 8) != (unsigned)curTile)
2369
0
      return -1;
2370
2371
0
    dataSize -= hdrSize + 4;
2372
2373
0
    tile->tileSize = LibRaw::sgetn(4, dataPtr + 4);
2374
0
    tile->dataOffset = tileOffset;
2375
0
    tile->qStep = 0;
2376
0
    if (hdrSize == 16)
2377
0
    {
2378
      // extended header data - terminated by 0 bytes
2379
0
      if (LibRaw::sgetn(2, dataPtr + 18) != 0)
2380
0
        return -1;
2381
0
      tile->hasQPData = true;
2382
0
      tile->mdatQPDataSize = LibRaw::sgetn(4, dataPtr + 12);
2383
0
      tile->mdatExtraSize = LibRaw::sgetn(2, dataPtr + 16);
2384
0
    }
2385
0
    else
2386
0
    {
2387
0
      tile->hasQPData = false;
2388
0
      tile->mdatQPDataSize = 0;
2389
0
      tile->mdatExtraSize = 0;
2390
0
    }
2391
2392
0
    dataPtr += hdrSize + 4;
2393
0
    tileOffset += tile->tileSize;
2394
2395
0
    uint32_t compOffset = 0;
2396
0
    CrxPlaneComp *comp = tile->comps;
2397
2398
0
    for (int compNum = 0; compNum < img->nPlanes; ++compNum, ++comp)
2399
0
    {
2400
0
      if (dataSize < 0xC)
2401
0
        return -1;
2402
0
      hdrSign = LibRaw::sgetn(2, dataPtr);
2403
0
      hdrSize = LibRaw::sgetn(2, dataPtr + 2);
2404
0
      if ((hdrSign != 0xFF02 && hdrSign != 0xFF12) || hdrSize != 8)
2405
0
        return -1;
2406
0
      if (compNum != dataPtr[8] >> 4)
2407
0
        return -1;
2408
0
      if (LibRaw::sgetn(3, dataPtr + 9) != 0)
2409
0
        return -1;
2410
2411
0
      comp->compSize = LibRaw::sgetn(4, dataPtr + 4);
2412
2413
0
      int32_t compHdrRoundedBits = (dataPtr[8] >> 1) & 3;
2414
0
      comp->supportsPartial = (dataPtr[8] & 8) != 0;
2415
2416
0
      comp->dataOffset = compOffset;
2417
0
      comp->tileFlag = tile->tileFlag;
2418
2419
0
      compOffset += comp->compSize;
2420
0
      dataSize -= 0xC;
2421
0
      dataPtr += 0xC;
2422
2423
0
      comp->roundedBitsMask = 0;
2424
2425
0
      if (compHdrRoundedBits)
2426
0
      {
2427
0
        if (img->levels || !comp->supportsPartial)
2428
0
          return -1;
2429
2430
0
        comp->roundedBitsMask = 1 << (compHdrRoundedBits - 1);
2431
0
      }
2432
2433
0
      if (crxReadSubbandHeaders(hdr, img, tile, comp, &dataPtr, &dataSize) || crxProcessSubbands(hdr, img, tile, comp))
2434
0
        return -1;
2435
0
    }
2436
0
  }
2437
2438
0
  if (hdr->version != 0x200)
2439
0
    return 0;
2440
2441
0
  tile = img->tiles;
2442
0
  for (int curTile = 0; curTile < nTiles; ++curTile, ++tile)
2443
0
  {
2444
0
    if (tile->hasQPData)
2445
0
    {
2446
0
      CrxBitstream bitStrm;
2447
0
      bitStrm.bitData = 0;
2448
0
      bitStrm.bitsLeft = 0;
2449
0
      bitStrm.curPos = 0;
2450
0
      bitStrm.curBufSize = 0;
2451
0
      bitStrm.mdatSize = tile->mdatQPDataSize;
2452
0
      bitStrm.curBufOffset = img->mdatOffset + tile->dataOffset;
2453
0
      bitStrm.input = img->input;
2454
2455
0
      crxFillBuffer(&bitStrm);
2456
2457
0
      unsigned int qpWidth = (tile->width >> 3) + ((tile->width & 7) != 0);
2458
0
      unsigned int qpHeight = (tile->height >> 1) + (tile->height & 1);
2459
0
      unsigned long totalQP = qpHeight * qpWidth;
2460
2461
0
      try
2462
0
      {
2463
0
        std::vector<int32_t> qpTable(totalQP + 2 * (qpWidth + 2));
2464
0
        int32_t *qpCurElem = qpTable.data();
2465
        // 2 lines padded with extra pixels at the start and at the end
2466
0
        int32_t *qpLineBuf = qpTable.data() + totalQP;
2467
0
        int32_t kParam = 0;
2468
0
        for (unsigned qpRow = 0; qpRow < qpHeight; ++qpRow)
2469
0
        {
2470
0
          int32_t *qpLine0 = qpRow & 1 ? qpLineBuf + qpWidth + 2 : qpLineBuf;
2471
0
          int32_t *qpLine1 = qpRow & 1 ? qpLineBuf : qpLineBuf + qpWidth + 2;
2472
2473
0
          if (qpRow)
2474
0
            crxDecodeGolombNormal(&bitStrm, qpWidth, qpLine0, qpLine1, &kParam);
2475
0
          else
2476
0
            crxDecodeGolombTop(&bitStrm, qpWidth, qpLine1, &kParam);
2477
2478
0
          for (unsigned qpCol = 0; qpCol < qpWidth; ++qpCol)
2479
0
            *qpCurElem++ = qpLine1[qpCol + 1] + 4;
2480
0
        }
2481
2482
        // now we read QP data - build tile QStep
2483
0
        if (crxMakeQStep(img, tile, qpTable.data(), totalQP))
2484
0
          return -1;
2485
0
      }
2486
0
      catch (...)
2487
0
      {
2488
0
        return -1;
2489
0
      }
2490
0
    }
2491
0
  }
2492
2493
0
  return 0;
2494
0
}
2495
2496
int crxSetupImageData(crx_data_header_t *hdr, CrxImage *img, int16_t *outBuf, uint64_t mdatOffset, uint32_t mdatSize,
2497
                      uint8_t *mdatHdrPtr, int32_t mdatHdrSize)
2498
0
{
2499
0
  int IncrBitTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0};
2500
2501
0
  img->planeWidth = hdr->f_width;
2502
0
  img->planeHeight = hdr->f_height;
2503
2504
0
  if (hdr->tileWidth < 0x16 || hdr->tileHeight < 0x16 || img->planeWidth > 0x7FFF || img->planeHeight > 0x7FFF)
2505
0
    return -1;
2506
2507
0
  img->tileCols = (img->planeWidth + hdr->tileWidth - 1) / hdr->tileWidth;
2508
0
  img->tileRows = (img->planeHeight + hdr->tileHeight - 1) / hdr->tileHeight;
2509
2510
0
  if (img->tileCols > 0xFF || img->tileRows > 0xFF || img->planeWidth - hdr->tileWidth * (img->tileCols - 1) < 0x16 ||
2511
0
      img->planeHeight - hdr->tileHeight * (img->tileRows - 1) < 0x16)
2512
0
    return -1;
2513
2514
0
  img->tiles = 0;
2515
0
  img->levels = hdr->imageLevels;
2516
0
  img->subbandCount = 3 * img->levels + 1; // 3 bands per level + one last LL
2517
0
  img->nPlanes = hdr->nPlanes;
2518
0
  img->nBits = hdr->nBits;
2519
0
  img->encType = hdr->encType;
2520
0
  img->samplePrecision = hdr->nBits + IncrBitTable[4 * hdr->encType + 2] + 1;
2521
0
  img->mdatOffset = mdatOffset + hdr->mdatHdrSize;
2522
0
  img->mdatSize = mdatSize;
2523
0
  img->planeBuf = 0;
2524
0
  img->outBufs[0] = img->outBufs[1] = img->outBufs[2] = img->outBufs[3] = 0;
2525
0
  img->medianBits = hdr->medianBits;
2526
2527
  // The encoding type 3 needs all 4 planes to be decoded to generate row of
2528
  // RGGB values. It seems to be using some other colour space for raw encoding
2529
  // It is a massive buffer so ideallly it will need a different approach:
2530
  // decode planes line by line and convert single line then without
2531
  // intermediate plane buffer. At the moment though it's too many changes so
2532
  // left as is.
2533
0
  if (img->encType == 3 && img->nPlanes == 4 && img->nBits > 8)
2534
0
  {
2535
0
      img->planeBuf = (int16_t *)
2536
0
#ifdef LIBRAW_CR3_MEMPOOL
2537
0
                          img->memmgr.
2538
0
#endif
2539
0
                      malloc(img->planeHeight * img->planeWidth * img->nPlanes * ((img->samplePrecision + 7) >> 3));
2540
0
    if (!img->planeBuf)
2541
0
      return -1;
2542
0
  }
2543
2544
0
  int32_t rowSize = 2 * img->planeWidth;
2545
2546
0
  if (img->nPlanes == 1)
2547
0
    img->outBufs[0] = outBuf;
2548
0
  else
2549
0
    switch (hdr->cfaLayout)
2550
0
    {
2551
0
    case 0:
2552
      // R G
2553
      // G B
2554
0
      img->outBufs[0] = outBuf;
2555
0
      img->outBufs[1] = outBuf + 1;
2556
0
      img->outBufs[2] = outBuf + rowSize;
2557
0
      img->outBufs[3] = img->outBufs[2] + 1;
2558
0
      break;
2559
0
    case 1:
2560
      // G R
2561
      // B G
2562
0
      img->outBufs[1] = outBuf;
2563
0
      img->outBufs[0] = outBuf + 1;
2564
0
      img->outBufs[3] = outBuf + rowSize;
2565
0
      img->outBufs[2] = img->outBufs[3] + 1;
2566
0
      break;
2567
0
    case 2:
2568
      // G B
2569
      // R G
2570
0
      img->outBufs[2] = outBuf;
2571
0
      img->outBufs[3] = outBuf + 1;
2572
0
      img->outBufs[0] = outBuf + rowSize;
2573
0
      img->outBufs[1] = img->outBufs[0] + 1;
2574
0
      break;
2575
0
    case 3:
2576
      // B G
2577
      // G R
2578
0
      img->outBufs[3] = outBuf;
2579
0
      img->outBufs[2] = outBuf + 1;
2580
0
      img->outBufs[1] = outBuf + rowSize;
2581
0
      img->outBufs[0] = img->outBufs[1] + 1;
2582
0
      break;
2583
0
    }
2584
2585
  // read header
2586
0
  return crxReadImageHeaders(hdr, img, mdatHdrPtr, mdatHdrSize);
2587
0
}
2588
2589
int crxFreeImageData(CrxImage *img)
2590
0
{
2591
0
#ifdef LIBRAW_CR3_MEMPOOL
2592
0
  img->memmgr.cleanup();
2593
#else
2594
  CrxTile *tile = img->tiles;
2595
  int nTiles = img->tileRows * img->tileCols;
2596
2597
  if (img->tiles)
2598
  {
2599
    for (int32_t curTile = 0; curTile < nTiles; curTile++)
2600
    {
2601
      if (tile[curTile].comps)
2602
        for (int32_t curPlane = 0; curPlane < img->nPlanes; curPlane++)
2603
          crxFreeSubbandData(img, tile[curTile].comps + curPlane);
2604
      if (tile[curTile].qStep)
2605
        free(tile[curTile].qStep);
2606
    }
2607
    free(img->tiles);
2608
    img->tiles = 0;
2609
  }
2610
2611
  if (img->planeBuf)
2612
  {
2613
    free(img->planeBuf);
2614
    img->planeBuf = 0;
2615
  }
2616
#endif
2617
0
  return 0;
2618
0
}
2619
void LibRaw::crxLoadDecodeLoop(void *img, int nPlanes)
2620
0
{
2621
#ifdef LIBRAW_USE_OPENMP
2622
  int results[4] ={0,0,0,0}; // nPlanes is always <= 4
2623
#pragma omp parallel for
2624
  for (int32_t plane = 0; plane < nPlanes; ++plane)
2625
   try {
2626
    results[plane] = crxDecodePlane(img, plane);
2627
   } catch (...) {
2628
    results[plane] = 1;
2629
   }
2630
2631
  for (int32_t plane = 0; plane < nPlanes; ++plane)
2632
    if (results[plane])
2633
      derror();
2634
#else
2635
0
  for (int32_t plane = 0; plane < nPlanes; ++plane)
2636
0
    if (crxDecodePlane(img, plane))
2637
0
      derror();
2638
0
#endif
2639
0
}
2640
2641
0
void LibRaw::crxConvertPlaneLineDf(void *p, int imageRow) { crxConvertPlaneLine((CrxImage *)p, imageRow); }
2642
2643
void LibRaw::crxLoadFinalizeLoopE3(void *p, int planeHeight)
2644
0
{
2645
#ifdef LIBRAW_USE_OPENMP
2646
#pragma omp parallel for
2647
#endif
2648
0
  for (int i = 0; i < planeHeight; ++i)
2649
0
    crxConvertPlaneLineDf(p, i);
2650
0
}
2651
2652
void LibRaw::crxLoadRaw()
2653
0
{
2654
0
  CrxImage img;
2655
0
  if (libraw_internal_data.unpacker_data.crx_track_selected < 0 ||
2656
0
      libraw_internal_data.unpacker_data.crx_track_selected >= LIBRAW_CRXTRACKS_MAXCOUNT)
2657
0
    derror();
2658
2659
0
  crx_data_header_t hdr =
2660
0
      libraw_internal_data.unpacker_data.crx_header[libraw_internal_data.unpacker_data.crx_track_selected];
2661
2662
0
  if (libraw_internal_data.unpacker_data.data_size < (unsigned)hdr.mdatHdrSize)
2663
0
    derror();
2664
2665
0
  img.input = libraw_internal_data.internal_data.input;
2666
2667
  // update sizes for the planes
2668
0
  if (hdr.nPlanes == 4)
2669
0
  {
2670
0
    hdr.f_width >>= 1;
2671
0
    hdr.f_height >>= 1;
2672
0
    hdr.tileWidth >>= 1;
2673
0
    hdr.tileHeight >>= 1;
2674
0
  }
2675
2676
0
  imgdata.color.maximum = (1 << hdr.nBits) - 1;
2677
2678
0
  std::vector<uint8_t> hdrBuf(hdr.mdatHdrSize);
2679
2680
0
  unsigned bytes = 0;
2681
  // read image header
2682
#ifdef LIBRAW_USE_OPENMP
2683
#pragma omp critical
2684
#endif
2685
0
  {
2686
0
#ifndef LIBRAW_USE_OPENMP
2687
0
    libraw_internal_data.internal_data.input->lock();
2688
0
#endif
2689
0
    libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
2690
0
    bytes = libraw_internal_data.internal_data.input->read(hdrBuf.data(), 1, hdr.mdatHdrSize);
2691
0
#ifndef LIBRAW_USE_OPENMP
2692
0
    libraw_internal_data.internal_data.input->unlock();
2693
0
#endif
2694
0
  }
2695
2696
0
  if (bytes != hdr.mdatHdrSize)
2697
0
    throw LIBRAW_EXCEPTION_IO_EOF;
2698
2699
  // parse and setup the image data
2700
0
  if (crxSetupImageData(&hdr, &img, (int16_t *)imgdata.rawdata.raw_image,
2701
0
    libraw_internal_data.unpacker_data.data_offset, libraw_internal_data.unpacker_data.data_size,
2702
0
    hdrBuf.data(), hdr.mdatHdrSize))
2703
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
2704
2705
0
  crxLoadDecodeLoop(&img, hdr.nPlanes);
2706
2707
0
  if (img.encType == 3)
2708
0
    crxLoadFinalizeLoopE3(&img, img.planeHeight);
2709
2710
0
  crxFreeImageData(&img);
2711
0
}
2712
2713
int LibRaw::crxParseImageHeader(uchar *cmp1TagData, int nTrack, int size)
2714
0
{
2715
0
  if (nTrack < 0 || nTrack >= LIBRAW_CRXTRACKS_MAXCOUNT)
2716
0
    return -1;
2717
0
  if (!cmp1TagData)
2718
0
    return -1;
2719
2720
0
  crx_data_header_t *hdr = &libraw_internal_data.unpacker_data.crx_header[nTrack];
2721
2722
0
  hdr->version = sgetn(2, cmp1TagData + 4);
2723
0
  hdr->f_width = sgetn(4, cmp1TagData + 8);
2724
0
  hdr->f_height = sgetn(4, cmp1TagData + 12);
2725
0
  hdr->tileWidth = sgetn(4, cmp1TagData + 16);
2726
0
  hdr->tileHeight = sgetn(4, cmp1TagData + 20);
2727
0
  hdr->nBits = cmp1TagData[24];
2728
0
  hdr->nPlanes = cmp1TagData[25] >> 4;
2729
0
  hdr->cfaLayout = cmp1TagData[25] & 0xF;
2730
0
  hdr->encType = cmp1TagData[26] >> 4;
2731
0
  hdr->imageLevels = cmp1TagData[26] & 0xF;
2732
0
  hdr->hasTileCols = cmp1TagData[27] >> 7;
2733
0
  hdr->hasTileRows = (cmp1TagData[27] >> 6) & 1;
2734
0
  hdr->mdatHdrSize = sgetn(4, cmp1TagData + 28);
2735
0
  int extHeader = cmp1TagData[32] >> 7;
2736
0
  int useMedianBits = 0;
2737
0
  hdr->medianBits = hdr->nBits;
2738
2739
0
  if (extHeader && size >= 56 && hdr->nPlanes == 4)
2740
0
    useMedianBits = cmp1TagData[56] >> 6 & 1;
2741
2742
0
  if (useMedianBits && size >= 84)
2743
0
    hdr->medianBits = cmp1TagData[84];
2744
2745
  // validation
2746
0
  if ((hdr->version != 0x100 && hdr->version != 0x200) || !hdr->mdatHdrSize)
2747
0
    return -1;
2748
0
  if (hdr->encType == 1)
2749
0
  {
2750
0
    if (hdr->nBits > 15)
2751
0
      return -1;
2752
0
  }
2753
0
  else
2754
0
  {
2755
0
    if (hdr->encType && hdr->encType != 3)
2756
0
      return -1;
2757
0
    if (hdr->nBits > 14)
2758
0
      return -1;
2759
0
  }
2760
2761
0
  if (hdr->nPlanes == 1)
2762
0
  {
2763
0
    if (hdr->cfaLayout || hdr->encType || hdr->nBits != 8)
2764
0
      return -1;
2765
0
  }
2766
0
  else if (hdr->nPlanes != 4 || hdr->f_width & 1 || hdr->f_height & 1 || hdr->tileWidth & 1 || hdr->tileHeight & 1 ||
2767
0
           hdr->cfaLayout > 3 || hdr->nBits == 8)
2768
0
    return -1;
2769
2770
0
  if (hdr->tileWidth > hdr->f_width || hdr->tileHeight > hdr->f_height)
2771
0
    return -1;
2772
2773
0
  if (hdr->imageLevels > 3 || hdr->hasTileCols > 1 || hdr->hasTileRows > 1)
2774
0
    return -1;
2775
0
  return 0;
2776
0
}
2777
2778
#undef _abs
2779
#undef _min
2780
#undef _constrain
2781
#undef libraw_inline