File indexing completed on 2025-01-05 03:56:50

0001 /* -*- C++ -*-
0002  * File: libraw_crxdec.cpp
0003  * Copyright (C) 2018-2019 Alexey Danilchenko
0004  * Copyright (C) 2019 Alex Tutubalin, LibRaw LLC
0005  *
0006    Canon CR3 file decoder
0007 
0008 LibRaw is free software; you can redistribute it and/or modify
0009 it under the terms of the one of two licenses as you choose:
0010 
0011 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0012    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0013 
0014 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0015    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0016 
0017  */
0018 
0019 #include "../../internal/libraw_cxx_defs.h"
0020 
0021 #ifdef _abs
0022 #undef _abs
0023 #undef _min
0024 #undef _constrain
0025 #endif
0026 #define _abs(x) (((x) ^ ((int32_t)(x) >> 31)) - ((int32_t)(x) >> 31))
0027 #define _min(a, b) ((a) < (b) ? (a) : (b))
0028 #define _constrain(x, l, u) ((x) < (l) ? (l) : ((x) > (u) ? (u) : (x)))
0029 
0030 #if defined(__clang__) || defined(__GNUG__)
0031 #define libraw_inline inline __attribute__((always_inline))
0032 #elif defined(_MSC_VER) && _MSC_VER > 1400
0033 #define libraw_inline __forceinline
0034 #else
0035 #define libraw_inline inline
0036 #endif
0037 
0038 // this should be divisible by 4
0039 #define CRX_BUF_SIZE 0x10000
0040 #if !defined(_WIN32) || (defined(__GNUC__) && !defined(__INTRINSIC_SPECIAL__BitScanReverse))
0041 /* __INTRINSIC_SPECIAL__BitScanReverse found in MinGW32-W64 v7.30 headers, may be there is a better solution? */
0042 typedef uint32_t DWORD;
0043 libraw_inline void _BitScanReverse(DWORD *Index, unsigned long Mask)
0044 {
0045   *Index = sizeof(unsigned long) * 8 - 1 - __builtin_clzl(Mask);
0046 }
0047 #if LibRawBigEndian
0048 #define _byteswap_ulong(x) (x)
0049 #else
0050 #define _byteswap_ulong(x) __builtin_bswap32(x)
0051 #endif
0052 #endif
0053 
0054 struct CrxBitstream
0055 {
0056   uint8_t mdatBuf[CRX_BUF_SIZE];
0057   uint64_t mdatSize;
0058   uint64_t curBufOffset;
0059   uint32_t curPos;
0060   uint32_t curBufSize;
0061   uint32_t bitData;
0062   int32_t bitsLeft;
0063   LibRaw_abstract_datastream *input;
0064 };
0065 
0066 struct CrxBandParam
0067 {
0068   CrxBitstream bitStream;
0069   int16_t subbandWidth;
0070   int16_t subbandHeight;
0071   int32_t roundedBitsMask;
0072   int32_t roundedBits;
0073   int16_t curLine;
0074   int32_t *lineBuf0;
0075   int32_t *lineBuf1;
0076   int32_t *lineBuf2;
0077   int32_t sParam;
0078   int32_t kParam;
0079   int32_t *paramData;
0080   int32_t *nonProgrData;
0081   bool supportsPartial;
0082 };
0083 
0084 struct CrxWaveletTransform
0085 {
0086   int32_t *subband0Buf;
0087   int32_t *subband1Buf;
0088   int32_t *subband2Buf;
0089   int32_t *subband3Buf;
0090   int32_t *lineBuf[8];
0091   int16_t curLine;
0092   int16_t curH;
0093   int8_t fltTapH;
0094   int16_t height;
0095   int16_t width;
0096 };
0097 
0098 struct CrxSubband
0099 {
0100   CrxBandParam *bandParam;
0101   uint64_t mdatOffset;
0102   uint8_t *bandBuf;
0103   uint16_t width;
0104   uint16_t height;
0105   int32_t qParam;
0106   int32_t kParam;
0107   int32_t qStepBase;
0108   uint32_t qStepMult;
0109   bool supportsPartial;
0110   int32_t bandSize;
0111   uint64_t dataSize;
0112   int64_t dataOffset;
0113   short rowStartAddOn;
0114   short rowEndAddOn;
0115   short colStartAddOn;
0116   short colEndAddOn;
0117   short levelShift;
0118 };
0119 
0120 struct CrxPlaneComp
0121 {
0122   uint8_t *compBuf;
0123   CrxSubband *subBands;
0124   CrxWaveletTransform *wvltTransform;
0125   int8_t compNumber;
0126   int64_t dataOffset;
0127   int32_t compSize;
0128   bool supportsPartial;
0129   int32_t roundedBitsMask;
0130   int8_t tileFlag;
0131 };
0132 
0133 struct CrxQStep
0134 {
0135   uint32_t *qStepTbl;
0136   int width;
0137   int height;
0138 };
0139 
0140 struct CrxTile
0141 {
0142   CrxPlaneComp *comps;
0143   int8_t tileFlag;
0144   int8_t tileNumber;
0145   int64_t dataOffset;
0146   int32_t tileSize;
0147   uint16_t width;
0148   uint16_t height;
0149   bool hasQPData;
0150   CrxQStep *qStep;
0151   uint32_t mdatQPDataSize;
0152   uint16_t mdatExtraSize;
0153 };
0154 
0155 struct CrxImage
0156 {
0157   uint8_t nPlanes;
0158   uint16_t planeWidth;
0159   uint16_t planeHeight;
0160   uint8_t samplePrecision;
0161   uint8_t medianBits;
0162   uint8_t subbandCount;
0163   uint8_t levels;
0164   uint8_t nBits;
0165   uint8_t encType;
0166   uint8_t tileCols;
0167   uint8_t tileRows;
0168   CrxTile *tiles;
0169   uint64_t mdatOffset;
0170   uint64_t mdatSize;
0171   int16_t *outBufs[4]; // one per plane
0172   int16_t *planeBuf;
0173   LibRaw_abstract_datastream *input;
0174 #ifdef LIBRAW_CR3_MEMPOOL
0175   libraw_memmgr memmgr;
0176   CrxImage() : memmgr(0) {}
0177 #endif
0178 };
0179 
0180 enum TileFlags
0181 {
0182   E_HAS_TILES_ON_THE_RIGHT = 1,
0183   E_HAS_TILES_ON_THE_LEFT = 2,
0184   E_HAS_TILES_ON_THE_BOTTOM = 4,
0185   E_HAS_TILES_ON_THE_TOP = 8
0186 };
0187 
0188 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,
0189                              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,
0190                              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,
0191                              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,
0192                              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};
0193 
0194 int32_t q_step_tbl[8] = {0x28, 0x2D, 0x33, 0x39, 0x40, 0x48};
0195 
0196 uint32_t JS[32] = {1,    1,    1,     1,     2,     2,     2,      2,      4,      4,     4,
0197                    4,    8,    8,     8,     8,     0x10,  0x10,   0x20,   0x20,   0x40,  0x40,
0198                    0x80, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000};
0199 
0200 uint32_t J[32] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,    2,    3,    3,    3,    3,
0201                   4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
0202 
0203 static inline void crxFillBuffer(CrxBitstream *bitStrm)
0204 {
0205   if (bitStrm->curPos >= bitStrm->curBufSize && bitStrm->mdatSize)
0206   {
0207     bitStrm->curPos = 0;
0208     bitStrm->curBufOffset += bitStrm->curBufSize;
0209 #ifdef LIBRAW_USE_OPENMP
0210 #pragma omp critical
0211 #endif
0212     {
0213 #ifndef LIBRAW_USE_OPENMP
0214       bitStrm->input->lock();
0215 #endif
0216       bitStrm->input->seek(bitStrm->curBufOffset, SEEK_SET);
0217       bitStrm->curBufSize = bitStrm->input->read(bitStrm->mdatBuf, 1, _min(bitStrm->mdatSize, CRX_BUF_SIZE));
0218 #ifndef LIBRAW_USE_OPENMP
0219       bitStrm->input->unlock();
0220 #endif
0221     }
0222     if (bitStrm->curBufSize < 1) // nothing read
0223       throw LIBRAW_EXCEPTION_IO_EOF;
0224     bitStrm->mdatSize -= bitStrm->curBufSize;
0225   }
0226 }
0227 
0228 libraw_inline int crxBitstreamGetZeros(CrxBitstream *bitStrm)
0229 {
0230   uint32_t nonZeroBit = 0;
0231   uint64_t nextData = 0;
0232   int32_t result = 0;
0233 
0234   if (bitStrm->bitData)
0235   {
0236     _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)bitStrm->bitData);
0237     result = 31 - nonZeroBit;
0238     bitStrm->bitData <<= 32 - nonZeroBit;
0239     bitStrm->bitsLeft -= 32 - nonZeroBit;
0240   }
0241   else
0242   {
0243     uint32_t bitsLeft = bitStrm->bitsLeft;
0244     while (1)
0245     {
0246       while (bitStrm->curPos + 4 <= bitStrm->curBufSize)
0247       {
0248         nextData = _byteswap_ulong(*(uint32_t *)(bitStrm->mdatBuf + bitStrm->curPos));
0249         bitStrm->curPos += 4;
0250         crxFillBuffer(bitStrm);
0251         if (nextData)
0252         {
0253           _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)nextData);
0254           result = bitsLeft + 31 - nonZeroBit;
0255           bitStrm->bitData = nextData << (32 - nonZeroBit);
0256           bitStrm->bitsLeft = nonZeroBit;
0257           return result;
0258         }
0259         bitsLeft += 32;
0260       }
0261       if (bitStrm->curBufSize < bitStrm->curPos + 1)
0262         break; // error
0263       nextData = bitStrm->mdatBuf[bitStrm->curPos++];
0264       crxFillBuffer(bitStrm);
0265       if (nextData)
0266         break;
0267       bitsLeft += 8;
0268     }
0269     _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)nextData);
0270     result = (uint32_t)(bitsLeft + 7 - nonZeroBit);
0271     bitStrm->bitData = nextData << (32 - nonZeroBit);
0272     bitStrm->bitsLeft = nonZeroBit;
0273   }
0274   return result;
0275 }
0276 
0277 libraw_inline uint32_t crxBitstreamGetBits(CrxBitstream *bitStrm, int bits)
0278 {
0279   int bitsLeft = bitStrm->bitsLeft;
0280   uint32_t bitData = bitStrm->bitData;
0281   uint32_t nextWord;
0282   uint8_t nextByte;
0283   uint32_t result;
0284 
0285   if (bitsLeft < bits)
0286   {
0287     // get them from stream
0288     if (bitStrm->curPos + 4 <= bitStrm->curBufSize)
0289     {
0290       nextWord = _byteswap_ulong(*(uint32_t *)(bitStrm->mdatBuf + bitStrm->curPos));
0291       bitStrm->curPos += 4;
0292       crxFillBuffer(bitStrm);
0293       bitStrm->bitsLeft = 32 - (bits - bitsLeft);
0294       result = ((nextWord >> bitsLeft) | bitData) >> (32 - bits);
0295       bitStrm->bitData = nextWord << (bits - bitsLeft);
0296       return result;
0297     }
0298     // less than a word left - read byte at a time
0299     do
0300     {
0301       if (bitStrm->curPos >= bitStrm->curBufSize)
0302         break; // error
0303       bitsLeft += 8;
0304       nextByte = bitStrm->mdatBuf[bitStrm->curPos++];
0305       crxFillBuffer(bitStrm);
0306       bitData |= nextByte << (32 - bitsLeft);
0307     } while (bitsLeft < bits);
0308   }
0309   result = bitData >> (32 - bits); // 32-bits
0310   bitStrm->bitData = bitData << bits;
0311   bitStrm->bitsLeft = bitsLeft - bits;
0312   return result;
0313 }
0314 
0315 libraw_inline int32_t crxPrediction(int32_t left, int32_t top, int32_t deltaH, int32_t deltaV)
0316 {
0317   int32_t symb[4] = {left + deltaH, left + deltaH, left, top};
0318 
0319   return symb[(((deltaV < 0) ^ (deltaH < 0)) << 1) + ((left < top) ^ (deltaH < 0))];
0320 }
0321 
0322 libraw_inline int32_t crxPredictKParameter(int32_t prevK, int32_t bitCode, int32_t maxVal = 0)
0323 {
0324   int32_t newKParam = prevK - (bitCode < (1 << prevK >> 1)) + ((bitCode >> prevK) > 2) + ((bitCode >> prevK) > 5);
0325 
0326   return !maxVal || newKParam < maxVal ? newKParam : maxVal;
0327 }
0328 
0329 libraw_inline void crxDecodeSymbolL1(CrxBandParam *param, int32_t doMedianPrediction, int32_t notEOL = 0)
0330 {
0331   if (doMedianPrediction)
0332   {
0333     int32_t symb[4];
0334 
0335     int32_t delta = param->lineBuf0[1] - param->lineBuf0[0];
0336     symb[2] = param->lineBuf1[0];
0337     symb[0] = symb[1] = delta + symb[2];
0338     symb[3] = param->lineBuf0[1];
0339 
0340     param->lineBuf1[1] = symb[(((param->lineBuf0[0] < param->lineBuf1[0]) ^ (delta < 0)) << 1) +
0341                               ((param->lineBuf1[0] < param->lineBuf0[1]) ^ (delta < 0))];
0342   }
0343   else
0344     param->lineBuf1[1] = param->lineBuf0[1];
0345 
0346   // get next error symbol
0347   uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0348   if (bitCode >= 41)
0349     bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0350   else if (param->kParam)
0351     bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0352 
0353   // add converted (+/-) error code to predicted value
0354   param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
0355 
0356   // for not end of the line - use one symbol ahead to estimate next K
0357   if (notEOL)
0358   {
0359     int32_t nextDelta = (param->lineBuf0[2] - param->lineBuf0[1]) << 1;
0360     bitCode = (bitCode + _abs(nextDelta)) >> 1;
0361     ++param->lineBuf0;
0362   }
0363 
0364   // update K parameter
0365   param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0366 
0367   ++param->lineBuf1;
0368 }
0369 
0370 int crxDecodeLine(CrxBandParam *param)
0371 {
0372   int length = param->subbandWidth;
0373 
0374   param->lineBuf1[0] = param->lineBuf0[1];
0375   for (; length > 1; --length)
0376   {
0377     if (param->lineBuf1[0] != param->lineBuf0[1] || param->lineBuf1[0] != param->lineBuf0[2])
0378     {
0379       crxDecodeSymbolL1(param, 1, 1);
0380     }
0381     else
0382     {
0383       int nSyms = 0;
0384       if (crxBitstreamGetBits(&param->bitStream, 1))
0385       {
0386         nSyms = 1;
0387         while (crxBitstreamGetBits(&param->bitStream, 1))
0388         {
0389           nSyms += JS[param->sParam];
0390           if (nSyms > length)
0391           {
0392             nSyms = length;
0393             break;
0394           }
0395           if (param->sParam < 31)
0396             ++param->sParam;
0397           if (nSyms == length)
0398             break;
0399         }
0400 
0401         if (nSyms < length)
0402         {
0403           if (J[param->sParam])
0404             nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
0405           if (param->sParam > 0)
0406             --param->sParam;
0407           if (nSyms > length)
0408             return -1;
0409         }
0410 
0411         length -= nSyms;
0412 
0413         // copy symbol nSyms times
0414         param->lineBuf0 += nSyms;
0415 
0416         // copy symbol nSyms times
0417         while (nSyms-- > 0)
0418         {
0419           param->lineBuf1[1] = param->lineBuf1[0];
0420           ++param->lineBuf1;
0421         }
0422       }
0423 
0424       if (length > 0)
0425         crxDecodeSymbolL1(param, 0, (length > 1));
0426     }
0427   }
0428 
0429   if (length == 1)
0430     crxDecodeSymbolL1(param, 1, 0);
0431 
0432   param->lineBuf1[1] = param->lineBuf1[0] + 1;
0433 
0434   return 0;
0435 }
0436 
0437 libraw_inline void crxDecodeSymbolL1Rounded(CrxBandParam *param, int32_t doSym = 1, int32_t doCode = 1)
0438 {
0439   int32_t sym = param->lineBuf0[1];
0440 
0441   if (doSym)
0442   {
0443     // calculate the next symbol gradient
0444     int32_t symb[4];
0445     int32_t deltaH = param->lineBuf0[1] - param->lineBuf0[0];
0446     symb[2] = param->lineBuf1[0];
0447     symb[0] = symb[1] = deltaH + symb[2];
0448     symb[3] = param->lineBuf0[1];
0449     sym = symb[(((param->lineBuf0[0] < param->lineBuf1[0]) ^ (deltaH < 0)) << 1) +
0450                ((param->lineBuf1[0] < param->lineBuf0[1]) ^ (deltaH < 0))];
0451   }
0452 
0453   uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0454   if (bitCode >= 41)
0455     bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0456   else if (param->kParam)
0457     bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0458   int32_t code = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
0459   param->lineBuf1[1] = param->roundedBitsMask * 2 * code + (code >> 31) + sym;
0460 
0461   if (doCode)
0462   {
0463     if (param->lineBuf0[2] > param->lineBuf0[1])
0464       code = (param->lineBuf0[2] - param->lineBuf0[1] + param->roundedBitsMask - 1) >> param->roundedBits;
0465     else
0466       code = -((param->lineBuf0[1] - param->lineBuf0[2] + param->roundedBitsMask) >> param->roundedBits);
0467 
0468     param->kParam = crxPredictKParameter(param->kParam, (bitCode + 2 * _abs(code)) >> 1, 15);
0469   }
0470   else
0471     param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0472 
0473   ++param->lineBuf1;
0474 }
0475 
0476 int crxDecodeLineRounded(CrxBandParam *param)
0477 {
0478   int32_t valueReached = 0;
0479 
0480   param->lineBuf0[0] = param->lineBuf0[1];
0481   param->lineBuf1[0] = param->lineBuf0[1];
0482   int32_t length = param->subbandWidth;
0483 
0484   for (; length > 1; --length)
0485   {
0486     if (_abs(param->lineBuf0[2] - param->lineBuf0[1]) > param->roundedBitsMask)
0487     {
0488       crxDecodeSymbolL1Rounded(param);
0489       ++param->lineBuf0;
0490       valueReached = 1;
0491     }
0492     else if (valueReached || _abs(param->lineBuf0[0] - param->lineBuf1[0]) > param->roundedBitsMask)
0493     {
0494       crxDecodeSymbolL1Rounded(param);
0495       ++param->lineBuf0;
0496       valueReached = 0;
0497     }
0498     else
0499     {
0500       int nSyms = 0;
0501       if (crxBitstreamGetBits(&param->bitStream, 1))
0502       {
0503         nSyms = 1;
0504         while (crxBitstreamGetBits(&param->bitStream, 1))
0505         {
0506           nSyms += JS[param->sParam];
0507           if (nSyms > length)
0508           {
0509             nSyms = length;
0510             break;
0511           }
0512           if (param->sParam < 31)
0513             ++param->sParam;
0514           if (nSyms == length)
0515             break;
0516         }
0517         if (nSyms < length)
0518         {
0519           if (J[param->sParam])
0520             nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
0521           if (param->sParam > 0)
0522             --param->sParam;
0523         }
0524         if (nSyms > length)
0525           return -1;
0526       }
0527       length -= nSyms;
0528 
0529       // copy symbol nSyms times
0530       param->lineBuf0 += nSyms;
0531 
0532       // copy symbol nSyms times
0533       while (nSyms-- > 0)
0534       {
0535         param->lineBuf1[1] = param->lineBuf1[0];
0536         ++param->lineBuf1;
0537       }
0538 
0539       if (length > 1)
0540       {
0541         crxDecodeSymbolL1Rounded(param, 0);
0542         ++param->lineBuf0;
0543         valueReached = _abs(param->lineBuf0[1] - param->lineBuf0[0]) > param->roundedBitsMask;
0544       }
0545       else if (length == 1)
0546         crxDecodeSymbolL1Rounded(param, 0, 0);
0547     }
0548   }
0549   if (length == 1)
0550     crxDecodeSymbolL1Rounded(param, 1, 0);
0551 
0552   param->lineBuf1[1] = param->lineBuf1[0] + 1;
0553 
0554   return 0;
0555 }
0556 
0557 int crxDecodeLineNoRefPrevLine(CrxBandParam *param)
0558 {
0559   int32_t i = 0;
0560 
0561   for (; i < param->subbandWidth - 1; i++)
0562   {
0563     if (param->lineBuf0[i + 2] | param->lineBuf0[i + 1] | param->lineBuf1[i])
0564     {
0565       uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0566       if (bitCode >= 41)
0567         bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0568       else if (param->kParam)
0569         bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0570       param->lineBuf1[i + 1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
0571       param->kParam = crxPredictKParameter(param->kParam, bitCode);
0572       if (param->lineBuf2[i + 1] - param->kParam <= 1)
0573       {
0574         if (param->kParam >= 15)
0575           param->kParam = 15;
0576       }
0577       else
0578         ++param->kParam;
0579     }
0580     else
0581     {
0582       int nSyms = 0;
0583       if (crxBitstreamGetBits(&param->bitStream, 1))
0584       {
0585         nSyms = 1;
0586         if (i != param->subbandWidth - 1)
0587         {
0588           while (crxBitstreamGetBits(&param->bitStream, 1))
0589           {
0590             nSyms += JS[param->sParam];
0591             if (i + nSyms > param->subbandWidth)
0592             {
0593               nSyms = param->subbandWidth - i;
0594               break;
0595             }
0596             if (param->sParam < 31)
0597               ++param->sParam;
0598             if (i + nSyms == param->subbandWidth)
0599               break;
0600           }
0601           if (i + nSyms < param->subbandWidth)
0602           {
0603             if (J[param->sParam])
0604               nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
0605             if (param->sParam > 0)
0606               --param->sParam;
0607           }
0608           if (i + nSyms > param->subbandWidth)
0609             return -1;
0610         }
0611       }
0612       else if (i > param->subbandWidth)
0613         return -1;
0614 
0615       if (nSyms > 0)
0616       {
0617         memset(param->lineBuf1 + i + 1, 0, nSyms * sizeof(int32_t));
0618         memset(param->lineBuf2 + i, 0, nSyms * sizeof(int32_t));
0619         i += nSyms;
0620       }
0621 
0622       if (i >= param->subbandWidth - 1)
0623       {
0624         if (i == param->subbandWidth - 1)
0625         {
0626           uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0627           if (bitCode >= 41)
0628             bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0629           else if (param->kParam)
0630             bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0631           param->lineBuf1[i + 1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1);
0632           param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0633           param->lineBuf2[i] = param->kParam;
0634         }
0635         continue;
0636       }
0637       else
0638       {
0639         uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0640         if (bitCode >= 41)
0641           bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0642         else if (param->kParam)
0643           bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0644         param->lineBuf1[i + 1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1);
0645         param->kParam = crxPredictKParameter(param->kParam, bitCode);
0646         if (param->lineBuf2[i + 1] - param->kParam <= 1)
0647         {
0648           if (param->kParam >= 15)
0649             param->kParam = 15;
0650         }
0651         else
0652           ++param->kParam;
0653       }
0654     }
0655     param->lineBuf2[i] = param->kParam;
0656   }
0657   if (i == param->subbandWidth - 1)
0658   {
0659     int32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0660     if (bitCode >= 41)
0661       bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0662     else if (param->kParam)
0663       bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0664     param->lineBuf1[i + 1] = -(bitCode & 1) ^ (bitCode >> 1);
0665     param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0666     param->lineBuf2[i] = param->kParam;
0667   }
0668 
0669   return 0;
0670 }
0671 
0672 int crxDecodeTopLine(CrxBandParam *param)
0673 {
0674   param->lineBuf1[0] = 0;
0675 
0676   int32_t length = param->subbandWidth;
0677 
0678   // read the line from bitstream
0679   for (; length > 1; --length)
0680   {
0681     if (param->lineBuf1[0])
0682       param->lineBuf1[1] = param->lineBuf1[0];
0683     else
0684     {
0685       int nSyms = 0;
0686       if (crxBitstreamGetBits(&param->bitStream, 1))
0687       {
0688         nSyms = 1;
0689         while (crxBitstreamGetBits(&param->bitStream, 1))
0690         {
0691           nSyms += JS[param->sParam];
0692           if (nSyms > length)
0693           {
0694             nSyms = length;
0695             break;
0696           }
0697           if (param->sParam < 31)
0698             ++param->sParam;
0699           if (nSyms == length)
0700             break;
0701         }
0702         if (nSyms < length)
0703         {
0704           if (J[param->sParam])
0705             nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
0706           if (param->sParam > 0)
0707             --param->sParam;
0708           if (nSyms > length)
0709             return -1;
0710         }
0711 
0712         length -= nSyms;
0713 
0714         // copy symbol nSyms times
0715         while (nSyms-- > 0)
0716         {
0717           param->lineBuf1[1] = param->lineBuf1[0];
0718           ++param->lineBuf1;
0719         }
0720 
0721         if (length <= 0)
0722           break;
0723       }
0724 
0725       param->lineBuf1[1] = 0;
0726     }
0727 
0728     uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0729     if (bitCode >= 41)
0730       bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0731     else if (param->kParam)
0732       bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0733     param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
0734     param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0735     ++param->lineBuf1;
0736   }
0737 
0738   if (length == 1)
0739   {
0740     param->lineBuf1[1] = param->lineBuf1[0];
0741     uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0742     if (bitCode >= 41)
0743       bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0744     else if (param->kParam)
0745       bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0746     param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
0747     param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0748     ++param->lineBuf1;
0749   }
0750 
0751   param->lineBuf1[1] = param->lineBuf1[0] + 1;
0752 
0753   return 0;
0754 }
0755 
0756 int crxDecodeTopLineRounded(CrxBandParam *param)
0757 {
0758   param->lineBuf1[0] = 0;
0759 
0760   int32_t length = param->subbandWidth;
0761 
0762   // read the line from bitstream
0763   for (; length > 1; --length)
0764   {
0765     if (_abs(param->lineBuf1[0]) > param->roundedBitsMask)
0766       param->lineBuf1[1] = param->lineBuf1[0];
0767     else
0768     {
0769       int nSyms = 0;
0770       if (crxBitstreamGetBits(&param->bitStream, 1))
0771       {
0772         nSyms = 1;
0773         while (crxBitstreamGetBits(&param->bitStream, 1))
0774         {
0775           nSyms += JS[param->sParam];
0776           if (nSyms > length)
0777           {
0778             nSyms = length;
0779             break;
0780           }
0781           if (param->sParam < 31)
0782             ++param->sParam;
0783           if (nSyms == length)
0784             break;
0785         }
0786         if (nSyms < length)
0787         {
0788           if (J[param->sParam])
0789             nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
0790           if (param->sParam > 0)
0791             --param->sParam;
0792           if (nSyms > length)
0793             return -1;
0794         }
0795       }
0796 
0797       length -= nSyms;
0798 
0799       // copy symbol nSyms times
0800       while (nSyms-- > 0)
0801       {
0802         param->lineBuf1[1] = param->lineBuf1[0];
0803         ++param->lineBuf1;
0804       }
0805 
0806       if (length <= 0)
0807         break;
0808 
0809       param->lineBuf1[1] = 0;
0810     }
0811 
0812     uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0813     if (bitCode >= 41)
0814       bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0815     else if (param->kParam)
0816       bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0817 
0818     int32_t sVal = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
0819     param->lineBuf1[1] += param->roundedBitsMask * 2 * sVal + (sVal >> 31);
0820     param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0821     ++param->lineBuf1;
0822   }
0823 
0824   if (length == 1)
0825   {
0826     uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0827     if (bitCode >= 41)
0828       bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0829     else if (param->kParam)
0830       bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0831     int32_t sVal = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
0832     param->lineBuf1[1] += param->roundedBitsMask * 2 * sVal + (sVal >> 31);
0833     param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0834     ++param->lineBuf1;
0835   }
0836 
0837   param->lineBuf1[1] = param->lineBuf1[0] + 1;
0838 
0839   return 0;
0840 }
0841 
0842 int crxDecodeTopLineNoRefPrevLine(CrxBandParam *param)
0843 {
0844   param->lineBuf0[0] = 0;
0845   param->lineBuf1[0] = 0;
0846   int32_t length = param->subbandWidth;
0847   for (; length > 1; --length)
0848   {
0849     if (param->lineBuf1[0])
0850     {
0851       uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0852       if (bitCode >= 41)
0853         bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0854       else if (param->kParam)
0855         bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0856       param->lineBuf1[1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
0857       param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0858     }
0859     else
0860     {
0861       int nSyms = 0;
0862       if (crxBitstreamGetBits(&param->bitStream, 1))
0863       {
0864         nSyms = 1;
0865         while (crxBitstreamGetBits(&param->bitStream, 1))
0866         {
0867           nSyms += JS[param->sParam];
0868           if (nSyms > length)
0869           {
0870             nSyms = length;
0871             break;
0872           }
0873           if (param->sParam < 31)
0874             ++param->sParam;
0875           if (nSyms == length)
0876             break;
0877         }
0878         if (nSyms < length)
0879         {
0880           if (J[param->sParam])
0881             nSyms += crxBitstreamGetBits(&param->bitStream, J[param->sParam]);
0882           if (param->sParam > 0)
0883             --param->sParam;
0884           if (nSyms > length)
0885             return -1;
0886         }
0887       }
0888 
0889       length -= nSyms;
0890 
0891       // copy symbol nSyms times
0892       while (nSyms-- > 0)
0893       {
0894         param->lineBuf2[0] = 0;
0895         param->lineBuf1[1] = 0;
0896         ++param->lineBuf1;
0897         ++param->lineBuf2;
0898       }
0899 
0900       if (length <= 0)
0901         break;
0902       uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0903       if (bitCode >= 41)
0904         bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0905       else if (param->kParam)
0906         bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0907       param->lineBuf1[1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1);
0908       param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0909     }
0910     param->lineBuf2[0] = param->kParam;
0911     ++param->lineBuf2;
0912     ++param->lineBuf1;
0913   }
0914 
0915   if (length == 1)
0916   {
0917     uint32_t bitCode = crxBitstreamGetZeros(&param->bitStream);
0918     if (bitCode >= 41)
0919       bitCode = crxBitstreamGetBits(&param->bitStream, 21);
0920     else if (param->kParam)
0921       bitCode = crxBitstreamGetBits(&param->bitStream, param->kParam) | (bitCode << param->kParam);
0922     param->lineBuf1[1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1);
0923     param->kParam = crxPredictKParameter(param->kParam, bitCode, 15);
0924     param->lineBuf2[0] = param->kParam;
0925     ++param->lineBuf1;
0926   }
0927 
0928   param->lineBuf1[1] = 0;
0929 
0930   return 0;
0931 }
0932 
0933 int crxDecodeLine(CrxBandParam *param, uint8_t *bandBuf)
0934 {
0935   if (!param || !bandBuf)
0936     return -1;
0937   if (param->curLine >= param->subbandHeight)
0938     return -1;
0939 
0940   if (param->curLine == 0)
0941   {
0942     int32_t lineLength = param->subbandWidth + 2;
0943 
0944     param->sParam = 0;
0945     param->kParam = 0;
0946     if (param->supportsPartial)
0947     {
0948       if (param->roundedBitsMask <= 0)
0949       {
0950         param->lineBuf0 = (int32_t *)param->paramData;
0951         param->lineBuf1 = param->lineBuf0 + lineLength;
0952         int32_t *lineBuf = param->lineBuf1 + 1;
0953         if (crxDecodeTopLine(param))
0954           return -1;
0955         memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
0956         ++param->curLine;
0957       }
0958       else
0959       {
0960         param->roundedBits = 1;
0961         if (param->roundedBitsMask & ~1)
0962         {
0963           while (param->roundedBitsMask >> param->roundedBits)
0964             ++param->roundedBits;
0965         }
0966         param->lineBuf0 = (int32_t *)param->paramData;
0967         param->lineBuf1 = param->lineBuf0 + lineLength;
0968         int32_t *lineBuf = param->lineBuf1 + 1;
0969         if (crxDecodeTopLineRounded(param))
0970           return -1;
0971         memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
0972         ++param->curLine;
0973       }
0974     }
0975     else
0976     {
0977       param->lineBuf2 = (int32_t *)param->nonProgrData;
0978       param->lineBuf0 = (int32_t *)param->paramData;
0979       param->lineBuf1 = param->lineBuf0 + lineLength;
0980       int32_t *lineBuf = param->lineBuf1 + 1;
0981       if (crxDecodeTopLineNoRefPrevLine(param))
0982         return -1;
0983       memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
0984       ++param->curLine;
0985     }
0986   }
0987   else if (!param->supportsPartial)
0988   {
0989     int32_t lineLength = param->subbandWidth + 2;
0990     param->lineBuf2 = (int32_t *)param->nonProgrData;
0991     if (param->curLine & 1)
0992     {
0993       param->lineBuf1 = (int32_t *)param->paramData;
0994       param->lineBuf0 = param->lineBuf1 + lineLength;
0995     }
0996     else
0997     {
0998       param->lineBuf0 = (int32_t *)param->paramData;
0999       param->lineBuf1 = param->lineBuf0 + lineLength;
1000     }
1001     int32_t *lineBuf = param->lineBuf1 + 1;
1002     if (crxDecodeLineNoRefPrevLine(param))
1003       return -1;
1004     memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
1005     ++param->curLine;
1006   }
1007   else if (param->roundedBitsMask <= 0)
1008   {
1009     int32_t lineLength = param->subbandWidth + 2;
1010     if (param->curLine & 1)
1011     {
1012       param->lineBuf1 = (int32_t *)param->paramData;
1013       param->lineBuf0 = param->lineBuf1 + lineLength;
1014     }
1015     else
1016     {
1017       param->lineBuf0 = (int32_t *)param->paramData;
1018       param->lineBuf1 = param->lineBuf0 + lineLength;
1019     }
1020     int32_t *lineBuf = param->lineBuf1 + 1;
1021     if (crxDecodeLine(param))
1022       return -1;
1023     memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
1024     ++param->curLine;
1025   }
1026   else
1027   {
1028     int32_t lineLength = param->subbandWidth + 2;
1029     if (param->curLine & 1)
1030     {
1031       param->lineBuf1 = (int32_t *)param->paramData;
1032       param->lineBuf0 = param->lineBuf1 + lineLength;
1033     }
1034     else
1035     {
1036       param->lineBuf0 = (int32_t *)param->paramData;
1037       param->lineBuf1 = param->lineBuf0 + lineLength;
1038     }
1039     int32_t *lineBuf = param->lineBuf1 + 1;
1040     if (crxDecodeLineRounded(param))
1041       return -1;
1042     memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t));
1043     ++param->curLine;
1044   }
1045   return 0;
1046 }
1047 
1048 int crxUpdateQparam(CrxSubband *subband)
1049 {
1050   uint32_t bitCode = crxBitstreamGetZeros(&subband->bandParam->bitStream);
1051   if (bitCode >= 23)
1052     bitCode = crxBitstreamGetBits(&subband->bandParam->bitStream, 8);
1053   else if (subband->kParam)
1054     bitCode = crxBitstreamGetBits(&subband->bandParam->bitStream, subband->kParam) | (bitCode << subband->kParam);
1055 
1056   subband->qParam += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); // converting encoded to signed integer
1057   subband->kParam = crxPredictKParameter(subband->kParam, bitCode);
1058   if (subband->kParam > 7)
1059     return -1;
1060   return 0;
1061 }
1062 
1063 libraw_inline int getSubbandRow(CrxSubband *band, int row)
1064 {
1065   return row < band->rowStartAddOn
1066              ? 0
1067              : (row < band->height - band->rowEndAddOn ? row - band->rowEndAddOn
1068                                                        : band->height - band->rowEndAddOn - band->rowStartAddOn - 1);
1069 }
1070 int crxDecodeLineWithIQuantization(CrxSubband *band, CrxQStep *qStep)
1071 {
1072   if (!band->dataSize)
1073   {
1074     memset(band->bandBuf, 0, band->bandSize);
1075     return 0;
1076   }
1077 
1078   if (band->supportsPartial && !qStep && crxUpdateQparam(band))
1079     return -1;
1080   if (crxDecodeLine(band->bandParam, band->bandBuf))
1081     return -1;
1082 
1083   if (band->width <= 0)
1084     return 0;
1085 
1086   // update band buffers
1087   int32_t *bandBuf = (int32_t *)band->bandBuf;
1088   if (qStep)
1089   {
1090     // new version
1091     uint32_t *qStepTblPtr = &qStep->qStepTbl[qStep->width * getSubbandRow(band, band->bandParam->curLine - 1)];
1092 
1093     for (int i = 0; i < band->colStartAddOn; ++i)
1094     {
1095       int32_t quantVal = band->qStepBase + ((qStepTblPtr[0] * band->qStepMult) >> 3);
1096       bandBuf[i] *= _constrain(quantVal, 1, 0x168000);
1097     }
1098 
1099     for (int i = band->colStartAddOn; i < band->width - band->colEndAddOn; ++i)
1100     {
1101       int32_t quantVal =
1102           band->qStepBase + ((qStepTblPtr[(i - band->colStartAddOn) >> band->levelShift] * band->qStepMult) >> 3);
1103       bandBuf[i] *= _constrain(quantVal, 1, 0x168000);
1104     }
1105     int lastIdx = (band->width - band->colEndAddOn - band->colStartAddOn - 1) >> band->levelShift;
1106     for (int i = band->width - band->colEndAddOn; i < band->width; ++i)
1107     {
1108       int32_t quantVal = band->qStepBase + ((qStepTblPtr[lastIdx] * band->qStepMult) >> 3);
1109       bandBuf[i] *= _constrain(quantVal, 1, 0x168000);
1110     }
1111   }
1112   else
1113   {
1114     // prev. version
1115     int32_t qScale = q_step_tbl[band->qParam % 6] >> (6 - band->qParam / 6);
1116     if (band->qParam / 6 >= 6)
1117       qScale = q_step_tbl[band->qParam % 6] * (1 << (band->qParam / 6 + 26));
1118 
1119     if (qScale != 1)
1120       for (int32_t i = 0; i < band->width; ++i)
1121         bandBuf[i] *= qScale;
1122   }
1123 
1124   return 0;
1125 }
1126 
1127 void crxHorizontal53(int32_t *lineBufLA, int32_t *lineBufLB, CrxWaveletTransform *wavelet, uint32_t tileFlag)
1128 {
1129   int32_t *band0Buf = wavelet->subband0Buf;
1130   int32_t *band1Buf = wavelet->subband1Buf;
1131   int32_t *band2Buf = wavelet->subband2Buf;
1132   int32_t *band3Buf = wavelet->subband3Buf;
1133 
1134   if (wavelet->width <= 1)
1135   {
1136     lineBufLA[0] = band0Buf[0];
1137     lineBufLB[0] = band2Buf[0];
1138   }
1139   else
1140   {
1141     if (tileFlag & E_HAS_TILES_ON_THE_LEFT)
1142     {
1143       lineBufLA[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1144       lineBufLB[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1145       ++band1Buf;
1146       ++band3Buf;
1147     }
1148     else
1149     {
1150       lineBufLA[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1151       lineBufLB[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1152     }
1153     ++band0Buf;
1154     ++band2Buf;
1155 
1156     for (int i = 0; i < wavelet->width - 3; i += 2)
1157     {
1158       int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1159       lineBufLA[1] = band1Buf[0] + ((delta + lineBufLA[0]) >> 1);
1160       lineBufLA[2] = delta;
1161 
1162       delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1163       lineBufLB[1] = band3Buf[0] + ((delta + lineBufLB[0]) >> 1);
1164       lineBufLB[2] = delta;
1165 
1166       ++band0Buf;
1167       ++band1Buf;
1168       ++band2Buf;
1169       ++band3Buf;
1170       lineBufLA += 2;
1171       lineBufLB += 2;
1172     }
1173     if (tileFlag & E_HAS_TILES_ON_THE_RIGHT)
1174     {
1175       int32_t deltaA = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1176       lineBufLA[1] = band1Buf[0] + ((deltaA + lineBufLA[0]) >> 1);
1177 
1178       int32_t deltaB = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1179       lineBufLB[1] = band3Buf[0] + ((deltaB + lineBufLB[0]) >> 1);
1180 
1181       if (wavelet->width & 1)
1182       {
1183         lineBufLA[2] = deltaA;
1184         lineBufLB[2] = deltaB;
1185       }
1186     }
1187     else if (wavelet->width & 1)
1188     {
1189       lineBufLA[1] = band1Buf[0] + ((lineBufLA[0] + band0Buf[0] - ((band1Buf[0] + 1) >> 1)) >> 1);
1190       lineBufLA[2] = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1191 
1192       lineBufLB[1] = band3Buf[0] + ((lineBufLB[0] + band2Buf[0] - ((band3Buf[0] + 1) >> 1)) >> 1);
1193       lineBufLB[2] = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1194     }
1195     else
1196     {
1197       lineBufLA[1] = lineBufLA[0] + band1Buf[0];
1198       lineBufLB[1] = lineBufLB[0] + band3Buf[0];
1199     }
1200   }
1201 }
1202 
1203 int32_t *crxIdwt53FilterGetLine(CrxPlaneComp *comp, int32_t level)
1204 {
1205   int32_t *result = comp->wvltTransform[level]
1206                         .lineBuf[(comp->wvltTransform[level].fltTapH - comp->wvltTransform[level].curH + 5) % 5 + 3];
1207   comp->wvltTransform[level].curH--;
1208   return result;
1209 }
1210 
1211 int crxIdwt53FilterDecode(CrxPlaneComp *comp, int32_t level, CrxQStep *qStep)
1212 {
1213   if (comp->wvltTransform[level].curH)
1214     return 0;
1215 
1216   CrxSubband *sband = comp->subBands + 3 * level;
1217   CrxQStep *qStepLevel = qStep ? qStep + level : 0;
1218 
1219   if (comp->wvltTransform[level].height - 3 <= comp->wvltTransform[level].curLine &&
1220       !(comp->tileFlag & E_HAS_TILES_ON_THE_BOTTOM))
1221   {
1222     if (comp->wvltTransform[level].height & 1)
1223     {
1224       if (level)
1225       {
1226         if (crxIdwt53FilterDecode(comp, level - 1, qStep))
1227           return -1;
1228       }
1229       else if (crxDecodeLineWithIQuantization(sband, qStepLevel))
1230         return -1;
1231 
1232       if (crxDecodeLineWithIQuantization(sband + 1, qStepLevel))
1233         return -1;
1234     }
1235   }
1236   else
1237   {
1238     if (level)
1239     {
1240       if (crxIdwt53FilterDecode(comp, level - 1, qStep))
1241         return -1;
1242     }
1243     else if (crxDecodeLineWithIQuantization(sband, qStepLevel)) // LL band
1244       return -1;
1245 
1246     if (crxDecodeLineWithIQuantization(sband + 1, qStepLevel) || // HL band
1247         crxDecodeLineWithIQuantization(sband + 2, qStepLevel) || // LH band
1248         crxDecodeLineWithIQuantization(sband + 3, qStepLevel))   // HH band
1249       return -1;
1250   }
1251 
1252   return 0;
1253 }
1254 
1255 int crxIdwt53FilterTransform(CrxPlaneComp *comp, uint32_t level)
1256 {
1257   CrxWaveletTransform *wavelet = comp->wvltTransform + level;
1258 
1259   if (wavelet->curH)
1260     return 0;
1261 
1262   if (wavelet->curLine >= wavelet->height - 3)
1263   {
1264     if (!(comp->tileFlag & E_HAS_TILES_ON_THE_BOTTOM))
1265     {
1266       if (wavelet->height & 1)
1267       {
1268         if (level)
1269         {
1270           if (!wavelet[-1].curH)
1271             if (crxIdwt53FilterTransform(comp, level - 1))
1272               return -1;
1273           wavelet->subband0Buf = crxIdwt53FilterGetLine(comp, level - 1);
1274         }
1275         int32_t *band0Buf = wavelet->subband0Buf;
1276         int32_t *band1Buf = wavelet->subband1Buf;
1277         int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3];
1278         int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3];
1279         int32_t *lineBufH2 = wavelet->lineBuf[(wavelet->fltTapH + 2) % 5 + 3];
1280 
1281         int32_t *lineBufL0 = wavelet->lineBuf[0];
1282         int32_t *lineBufL1 = wavelet->lineBuf[1];
1283         wavelet->lineBuf[1] = wavelet->lineBuf[2];
1284         wavelet->lineBuf[2] = lineBufL1;
1285 
1286         // process L bands
1287         if (wavelet->width <= 1)
1288         {
1289           lineBufL0[0] = band0Buf[0];
1290         }
1291         else
1292         {
1293           if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT)
1294           {
1295             lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1296             ++band1Buf;
1297           }
1298           else
1299           {
1300             lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1301           }
1302           ++band0Buf;
1303           for (int i = 0; i < wavelet->width - 3; i += 2)
1304           {
1305             int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1306             lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1);
1307             lineBufL0[2] = delta;
1308             ++band0Buf;
1309             ++band1Buf;
1310             lineBufL0 += 2;
1311           }
1312           if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
1313           {
1314             int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1315             lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1);
1316             if (wavelet->width & 1)
1317               lineBufL0[2] = delta;
1318           }
1319           else if (wavelet->width & 1)
1320           {
1321             int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1322             lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1);
1323             lineBufL0[2] = delta;
1324           }
1325           else
1326             lineBufL0[1] = band1Buf[0] + lineBufL0[0];
1327         }
1328 
1329         // process H bands
1330         lineBufL0 = wavelet->lineBuf[0];
1331         lineBufL1 = wavelet->lineBuf[1];
1332         for (int32_t i = 0; i < wavelet->width; i++)
1333         {
1334           int32_t delta = lineBufL0[i] - ((lineBufL1[i] + 1) >> 1);
1335           lineBufH1[i] = lineBufL1[i] + ((delta + lineBufH0[i]) >> 1);
1336           lineBufH2[i] = delta;
1337         }
1338         wavelet->curH += 3;
1339         wavelet->curLine += 3;
1340         wavelet->fltTapH = (wavelet->fltTapH + 3) % 5;
1341       }
1342       else
1343       {
1344         int32_t *lineBufL2 = wavelet->lineBuf[2];
1345         int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3];
1346         int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3];
1347         wavelet->lineBuf[1] = lineBufL2;
1348         wavelet->lineBuf[2] = wavelet->lineBuf[1];
1349 
1350         for (int32_t i = 0; i < wavelet->width; i++)
1351           lineBufH1[i] = lineBufH0[i] + lineBufL2[i];
1352 
1353         wavelet->curH += 2;
1354         wavelet->curLine += 2;
1355         wavelet->fltTapH = (wavelet->fltTapH + 2) % 5;
1356       }
1357     }
1358   }
1359   else
1360   {
1361     if (level)
1362     {
1363       if (!wavelet[-1].curH && crxIdwt53FilterTransform(comp, level - 1))
1364         return -1;
1365       wavelet->subband0Buf = crxIdwt53FilterGetLine(comp, level - 1);
1366     }
1367 
1368     int32_t *band0Buf = wavelet->subband0Buf;
1369     int32_t *band1Buf = wavelet->subband1Buf;
1370     int32_t *band2Buf = wavelet->subband2Buf;
1371     int32_t *band3Buf = wavelet->subband3Buf;
1372 
1373     int32_t *lineBufL0 = wavelet->lineBuf[0];
1374     int32_t *lineBufL1 = wavelet->lineBuf[1];
1375     int32_t *lineBufL2 = wavelet->lineBuf[2];
1376     int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3];
1377     int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3];
1378     int32_t *lineBufH2 = wavelet->lineBuf[(wavelet->fltTapH + 2) % 5 + 3];
1379 
1380     wavelet->lineBuf[1] = wavelet->lineBuf[2];
1381     wavelet->lineBuf[2] = lineBufL1;
1382 
1383     // process L bands
1384     if (wavelet->width <= 1)
1385     {
1386       lineBufL0[0] = band0Buf[0];
1387       lineBufL1[0] = band2Buf[0];
1388     }
1389     else
1390     {
1391       if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT)
1392       {
1393         lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1394         lineBufL1[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1395         ++band1Buf;
1396         ++band3Buf;
1397       }
1398       else
1399       {
1400         lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1401         lineBufL1[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1402       }
1403       ++band0Buf;
1404       ++band2Buf;
1405       for (int i = 0; i < wavelet->width - 3; i += 2)
1406       {
1407         int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1408         lineBufL0[1] = band1Buf[0] + ((delta + lineBufL0[0]) >> 1);
1409         lineBufL0[2] = delta;
1410 
1411         delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1412         lineBufL1[1] = band3Buf[0] + ((delta + lineBufL1[0]) >> 1);
1413         lineBufL1[2] = delta;
1414 
1415         ++band0Buf;
1416         ++band1Buf;
1417         ++band2Buf;
1418         ++band3Buf;
1419         lineBufL0 += 2;
1420         lineBufL1 += 2;
1421       }
1422       if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
1423       {
1424         int32_t deltaA = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1425         lineBufL0[1] = band1Buf[0] + ((deltaA + lineBufL0[0]) >> 1);
1426 
1427         int32_t deltaB = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1428         lineBufL1[1] = band3Buf[0] + ((deltaB + lineBufL1[0]) >> 1);
1429 
1430         if (wavelet->width & 1)
1431         {
1432           lineBufL0[2] = deltaA;
1433           lineBufL1[2] = deltaB;
1434         }
1435       }
1436       else if (wavelet->width & 1)
1437       {
1438         int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1439         lineBufL0[1] = band1Buf[0] + ((delta + lineBufL0[0]) >> 1);
1440         lineBufL0[2] = delta;
1441 
1442         delta = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1443         lineBufL1[1] = band3Buf[0] + ((delta + lineBufL1[0]) >> 1);
1444         lineBufL1[2] = delta;
1445       }
1446       else
1447       {
1448         lineBufL0[1] = lineBufL0[0] + band1Buf[0];
1449         lineBufL1[1] = lineBufL1[0] + band3Buf[0];
1450       }
1451     }
1452 
1453     // process H bands
1454     lineBufL0 = wavelet->lineBuf[0];
1455     lineBufL1 = wavelet->lineBuf[1];
1456     lineBufL2 = wavelet->lineBuf[2];
1457     for (int32_t i = 0; i < wavelet->width; i++)
1458     {
1459       int32_t delta = lineBufL0[i] - ((lineBufL2[i] + lineBufL1[i] + 2) >> 2);
1460       lineBufH1[i] = lineBufL1[i] + ((delta + lineBufH0[i]) >> 1);
1461       lineBufH2[i] = delta;
1462     }
1463     if (wavelet->curLine >= wavelet->height - 3 && wavelet->height & 1)
1464     {
1465       wavelet->curH += 3;
1466       wavelet->curLine += 3;
1467       wavelet->fltTapH = (wavelet->fltTapH + 3) % 5;
1468     }
1469     else
1470     {
1471       wavelet->curH += 2;
1472       wavelet->curLine += 2;
1473       wavelet->fltTapH = (wavelet->fltTapH + 2) % 5;
1474     }
1475   }
1476 
1477   return 0;
1478 }
1479 
1480 int crxIdwt53FilterInitialize(CrxPlaneComp *comp, int32_t level, CrxQStep *qStep)
1481 {
1482   if (level == 0)
1483     return 0;
1484 
1485   for (int curLevel = 0, curBand = 0; curLevel < level; curLevel++, curBand += 3)
1486   {
1487     CrxQStep *qStepLevel = qStep ? qStep + curLevel : 0;
1488     CrxWaveletTransform *wavelet = comp->wvltTransform + curLevel;
1489     if (curLevel)
1490       wavelet[0].subband0Buf = crxIdwt53FilterGetLine(comp, curLevel - 1);
1491     else if (crxDecodeLineWithIQuantization(comp->subBands + curBand, qStepLevel))
1492       return -1;
1493 
1494     int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3];
1495     if (wavelet->height > 1)
1496     {
1497       if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 1, qStepLevel) ||
1498           crxDecodeLineWithIQuantization(comp->subBands + curBand + 2, qStepLevel) ||
1499           crxDecodeLineWithIQuantization(comp->subBands + curBand + 3, qStepLevel))
1500         return -1;
1501 
1502       int32_t *lineBufL0 = wavelet->lineBuf[0];
1503       int32_t *lineBufL1 = wavelet->lineBuf[1];
1504       int32_t *lineBufL2 = wavelet->lineBuf[2];
1505 
1506       if (comp->tileFlag & E_HAS_TILES_ON_THE_TOP)
1507       {
1508         crxHorizontal53(lineBufL0, wavelet->lineBuf[1], wavelet, comp->tileFlag);
1509         if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 3, qStepLevel) ||
1510             crxDecodeLineWithIQuantization(comp->subBands + curBand + 2, qStepLevel))
1511           return -1;
1512 
1513         int32_t *band2Buf = wavelet->subband2Buf;
1514         int32_t *band3Buf = wavelet->subband3Buf;
1515 
1516         // process L band
1517         if (wavelet->width <= 1)
1518           lineBufL2[0] = band2Buf[0];
1519         else
1520         {
1521           if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT)
1522           {
1523             lineBufL2[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1524             ++band3Buf;
1525           }
1526           else
1527             lineBufL2[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1528 
1529           ++band2Buf;
1530 
1531           for (int i = 0; i < wavelet->width - 3; i += 2)
1532           {
1533             int32_t delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1534             lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1);
1535             lineBufL2[2] = delta;
1536 
1537             ++band2Buf;
1538             ++band3Buf;
1539             lineBufL2 += 2;
1540           }
1541           if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
1542           {
1543             int32_t delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2);
1544             lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1);
1545             if (wavelet->width & 1)
1546               lineBufL2[2] = delta;
1547           }
1548           else if (wavelet->width & 1)
1549           {
1550             int32_t delta = band2Buf[0] - ((band3Buf[0] + 1) >> 1);
1551 
1552             lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1);
1553             lineBufL2[2] = delta;
1554           }
1555           else
1556           {
1557             lineBufL2[1] = band3Buf[0] + lineBufL2[0];
1558           }
1559         }
1560 
1561         // process H band
1562         for (int32_t i = 0; i < wavelet->width; i++)
1563           lineBufH0[i] = lineBufL0[i] - ((lineBufL1[i] + lineBufL2[i] + 2) >> 2);
1564       }
1565       else
1566       {
1567         crxHorizontal53(lineBufL0, wavelet->lineBuf[2], wavelet, comp->tileFlag);
1568         for (int i = 0; i < wavelet->width; i++)
1569           lineBufH0[i] = lineBufL0[i] - ((lineBufL2[i] + 1) >> 1);
1570       }
1571 
1572       if (crxIdwt53FilterDecode(comp, curLevel, qStep) || crxIdwt53FilterTransform(comp, curLevel))
1573         return -1;
1574     }
1575     else
1576     {
1577       if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 1, qStepLevel))
1578         return -1;
1579 
1580       int32_t *band0Buf = wavelet->subband0Buf;
1581       int32_t *band1Buf = wavelet->subband1Buf;
1582 
1583       // process H band
1584       if (wavelet->width <= 1)
1585         lineBufH0[0] = band0Buf[0];
1586       else
1587       {
1588         if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT)
1589         {
1590           lineBufH0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1591           ++band1Buf;
1592         }
1593         else
1594           lineBufH0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1595 
1596         ++band0Buf;
1597 
1598         for (int i = 0; i < wavelet->width - 3; i += 2)
1599         {
1600           int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1601           lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1);
1602           lineBufH0[2] = delta;
1603 
1604           ++band0Buf;
1605           ++band1Buf;
1606           lineBufH0 += 2;
1607         }
1608 
1609         if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
1610         {
1611           int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2);
1612           lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1);
1613           lineBufH0[2] = delta;
1614         }
1615         else if (wavelet->width & 1)
1616         {
1617           int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1);
1618           lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1);
1619           lineBufH0[2] = delta;
1620         }
1621         else
1622         {
1623           lineBufH0[1] = band1Buf[0] + lineBufH0[0];
1624         }
1625       }
1626       ++wavelet->curLine;
1627       ++wavelet->curH;
1628       wavelet->fltTapH = (wavelet->fltTapH + 1) % 5;
1629     }
1630   }
1631 
1632   return 0;
1633 }
1634 
1635 void crxFreeSubbandData(CrxImage *image, CrxPlaneComp *comp)
1636 {
1637   if (comp->compBuf)
1638   {
1639     free(comp->compBuf);
1640     comp->compBuf = 0;
1641   }
1642 
1643   if (!comp->subBands)
1644     return;
1645 
1646   for (int32_t i = 0; i < image->subbandCount; i++)
1647   {
1648     if (comp->subBands[i].bandParam)
1649     {
1650       free(comp->subBands[i].bandParam);
1651       comp->subBands[i].bandParam = 0LL;
1652     }
1653 
1654     comp->subBands[i].bandBuf = 0;
1655     comp->subBands[i].bandSize = 0;
1656   }
1657 }
1658 
1659 void crxConvertPlaneLine(CrxImage *img, int imageRow, int imageCol = 0, int plane = 0, int32_t *lineData = 0,
1660                          int lineLength = 0)
1661 {
1662   if (lineData)
1663   {
1664     uint64_t rawOffset = 4 * img->planeWidth * imageRow + 2 * imageCol;
1665     if (img->encType == 1)
1666     {
1667       int32_t maxVal = 1 << (img->nBits - 1);
1668       int32_t minVal = -maxVal;
1669       --maxVal;
1670       for (int i = 0; i < lineLength; i++)
1671         img->outBufs[plane][rawOffset + 2 * i] = _constrain(lineData[i], minVal, maxVal);
1672     }
1673     else if (img->encType == 3)
1674     {
1675       // copy to intermediate planeBuf
1676       rawOffset = plane * img->planeWidth * img->planeHeight + img->planeWidth * imageRow + imageCol;
1677       for (int i = 0; i < lineLength; i++)
1678         img->planeBuf[rawOffset + i] = lineData[i];
1679     }
1680     else if (img->nPlanes == 4)
1681     {
1682       int32_t median = 1 << (img->nBits - 1);
1683       int32_t maxVal = (1 << img->nBits) - 1;
1684       for (int i = 0; i < lineLength; i++)
1685         img->outBufs[plane][rawOffset + 2 * i] = _constrain(median + lineData[i], 0, maxVal);
1686     }
1687     else if (img->nPlanes == 1)
1688     {
1689       int32_t maxVal = (1 << img->nBits) - 1;
1690       int32_t median = 1 << (img->nBits - 1);
1691       rawOffset = img->planeWidth * imageRow + imageCol;
1692       for (int i = 0; i < lineLength; i++)
1693         img->outBufs[0][rawOffset + i] = _constrain(median + lineData[i], 0, maxVal);
1694     }
1695   }
1696   else if (img->encType == 3 && img->planeBuf)
1697   {
1698     int32_t planeSize = img->planeWidth * img->planeHeight;
1699     int16_t *plane0 = img->planeBuf + imageRow * img->planeWidth;
1700     int16_t *plane1 = plane0 + planeSize;
1701     int16_t *plane2 = plane1 + planeSize;
1702     int16_t *plane3 = plane2 + planeSize;
1703 
1704     int32_t median = (1 << (img->medianBits - 1)) << 10;
1705     int32_t maxVal = (1 << img->medianBits) - 1;
1706     uint32_t rawLineOffset = 4 * img->planeWidth * imageRow;
1707 
1708     // for this stage - all except imageRow is ignored
1709     for (int i = 0; i < img->planeWidth; i++)
1710     {
1711       int32_t gr = median + (plane0[i] << 10) - 168 * plane1[i] - 585 * plane3[i];
1712       int32_t val = 0;
1713       if (gr < 0)
1714         gr = -(((_abs(gr) + 512) >> 9) & ~1);
1715       else
1716         gr = ((_abs(gr) + 512) >> 9) & ~1;
1717 
1718       // Essentially R = round(median + P0 + 1.474*P3)
1719       val = (median + (plane0[i] << 10) + 1510 * plane3[i] + 512) >> 10;
1720       img->outBufs[0][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal);
1721       // Essentially G1 = round(median + P0 + P2 - 0.164*P1 - 0.571*P3)
1722       val = (plane2[i] + gr + 1) >> 1;
1723       img->outBufs[1][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal);
1724       // Essentially G2 = round(median + P0 - P2 - 0.164*P1 - 0.571*P3)
1725       val = (gr - plane2[i] + 1) >> 1;
1726       img->outBufs[2][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal);
1727       // Essentially B = round(median + P0 + 1.881*P1)
1728       val = (median + (plane0[i] << 10) + 1927 * plane1[i] + 512) >> 10;
1729       img->outBufs[3][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal);
1730     }
1731   }
1732 }
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 {
1737   int32_t progrDataSize = supportsPartial ? 0 : sizeof(int32_t) * subbandWidth;
1738   int32_t paramLength = 2 * subbandWidth + 4;
1739   uint8_t *paramBuf = 0;
1740     paramBuf = (uint8_t *)
1741 #ifdef LIBRAW_CR3_MEMPOOL
1742                    img->memmgr.
1743 #endif
1744                calloc(1, sizeof(CrxBandParam) + sizeof(int32_t) * paramLength + progrDataSize);
1745 
1746   if (!paramBuf)
1747     return -1;
1748 
1749   *param = (CrxBandParam *)paramBuf;
1750 
1751   paramBuf += sizeof(CrxBandParam);
1752 
1753   (*param)->paramData = (int32_t *)paramBuf;
1754   (*param)->nonProgrData = progrDataSize ? (*param)->paramData + paramLength : 0;
1755   (*param)->subbandWidth = subbandWidth;
1756   (*param)->subbandHeight = subbandHeight;
1757   (*param)->roundedBits = 0;
1758   (*param)->curLine = 0;
1759   (*param)->roundedBitsMask = roundedBitsMask;
1760   (*param)->supportsPartial = supportsPartial;
1761   (*param)->bitStream.bitData = 0;
1762   (*param)->bitStream.bitsLeft = 0;
1763   (*param)->bitStream.mdatSize = subbandDataSize;
1764   (*param)->bitStream.curPos = 0;
1765   (*param)->bitStream.curBufSize = 0;
1766   (*param)->bitStream.curBufOffset = subbandMdatOffset;
1767   (*param)->bitStream.input = img->input;
1768 
1769   crxFillBuffer(&(*param)->bitStream);
1770 
1771   return 0;
1772 }
1773 
1774 int crxSetupSubbandData(CrxImage *img, CrxPlaneComp *planeComp, const CrxTile *tile, uint32_t mdatOffset)
1775 {
1776   long compDataSize = 0;
1777   long waveletDataOffset = 0;
1778   long compCoeffDataOffset = 0;
1779   int32_t toSubbands = 3 * img->levels + 1;
1780   int32_t transformWidth = 0;
1781 
1782   CrxSubband *subbands = planeComp->subBands;
1783 
1784   // calculate sizes
1785   for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++)
1786   {
1787     subbands[subbandNum].bandSize = subbands[subbandNum].width * sizeof(int32_t); // 4bytes
1788     compDataSize += subbands[subbandNum].bandSize;
1789   }
1790 
1791   if (img->levels)
1792   {
1793     int32_t encLevels = img->levels ? img->levels : 1;
1794     waveletDataOffset = (compDataSize + 7) & ~7;
1795     compDataSize = (sizeof(CrxWaveletTransform) * encLevels + waveletDataOffset + 7) & ~7;
1796     compCoeffDataOffset = compDataSize;
1797 
1798     // calc wavelet line buffer sizes (always at one level up from current)
1799     for (int level = 0; level < img->levels; ++level)
1800       if (level < img->levels - 1)
1801         compDataSize += 8 * sizeof(int32_t) * planeComp->subBands[3 * (level + 1) + 2].width;
1802       else
1803         compDataSize += 8 * sizeof(int32_t) * tile->width;
1804   }
1805     // buffer allocation
1806     planeComp->compBuf = (uint8_t *)
1807 #ifdef LIBRAW_CR3_MEMPOOL
1808                              img->memmgr.
1809 #endif
1810                          malloc(compDataSize);
1811   if (!planeComp->compBuf)
1812     return -1;
1813 
1814   // subbands buffer and sizes initialisation
1815   uint64_t subbandMdatOffset = img->mdatOffset + mdatOffset;
1816   uint8_t *subbandBuf = planeComp->compBuf;
1817 
1818   for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++)
1819   {
1820     subbands[subbandNum].bandBuf = subbandBuf;
1821     subbandBuf += subbands[subbandNum].bandSize;
1822     subbands[subbandNum].mdatOffset = subbandMdatOffset + subbands[subbandNum].dataOffset;
1823   }
1824 
1825   // wavelet data initialisation
1826   if (img->levels)
1827   {
1828     CrxWaveletTransform *waveletTransforms = (CrxWaveletTransform *)(planeComp->compBuf + waveletDataOffset);
1829     int32_t *paramData = (int32_t *)(planeComp->compBuf + compCoeffDataOffset);
1830 
1831     planeComp->wvltTransform = waveletTransforms;
1832     waveletTransforms[0].subband0Buf = (int32_t *)subbands->bandBuf;
1833 
1834     for (int level = 0; level < img->levels; ++level)
1835     {
1836       int32_t band = 3 * level + 1;
1837 
1838       if (level >= img->levels - 1)
1839       {
1840         waveletTransforms[level].height = tile->height;
1841         transformWidth = tile->width;
1842       }
1843       else
1844       {
1845         waveletTransforms[level].height = subbands[band + 3].height;
1846         transformWidth = subbands[band + 4].width;
1847       }
1848       waveletTransforms[level].width = transformWidth;
1849       waveletTransforms[level].lineBuf[0] = paramData;
1850       waveletTransforms[level].lineBuf[1] = waveletTransforms[level].lineBuf[0] + transformWidth;
1851       waveletTransforms[level].lineBuf[2] = waveletTransforms[level].lineBuf[1] + transformWidth;
1852       waveletTransforms[level].lineBuf[3] = waveletTransforms[level].lineBuf[2] + transformWidth;
1853       waveletTransforms[level].lineBuf[4] = waveletTransforms[level].lineBuf[3] + transformWidth;
1854       waveletTransforms[level].lineBuf[5] = waveletTransforms[level].lineBuf[4] + transformWidth;
1855       waveletTransforms[level].lineBuf[6] = waveletTransforms[level].lineBuf[5] + transformWidth;
1856       waveletTransforms[level].lineBuf[7] = waveletTransforms[level].lineBuf[6] + transformWidth;
1857       waveletTransforms[level].curLine = 0;
1858       waveletTransforms[level].curH = 0;
1859       waveletTransforms[level].fltTapH = 0;
1860       waveletTransforms[level].subband1Buf = (int32_t *)subbands[band].bandBuf;
1861       waveletTransforms[level].subband2Buf = (int32_t *)subbands[band + 1].bandBuf;
1862       waveletTransforms[level].subband3Buf = (int32_t *)subbands[band + 2].bandBuf;
1863 
1864       paramData = waveletTransforms[level].lineBuf[7] + transformWidth;
1865     }
1866   }
1867 
1868   // decoding params and bitstream initialisation
1869   for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++)
1870   {
1871     if (subbands[subbandNum].dataSize)
1872     {
1873       bool supportsPartial = false;
1874       uint32_t roundedBitsMask = 0;
1875 
1876       if (planeComp->supportsPartial && subbandNum == 0)
1877       {
1878         roundedBitsMask = planeComp->roundedBitsMask;
1879         supportsPartial = true;
1880       }
1881       if (crxParamInit(img, &subbands[subbandNum].bandParam, subbands[subbandNum].mdatOffset,
1882                        subbands[subbandNum].dataSize, subbands[subbandNum].width, subbands[subbandNum].height,
1883                        supportsPartial, roundedBitsMask))
1884         return -1;
1885     }
1886   }
1887 
1888   return 0;
1889 }
1890 
1891 int LibRaw::crxDecodePlane(void *p, uint32_t planeNumber)
1892 {
1893   CrxImage *img = (CrxImage *)p;
1894   int imageRow = 0;
1895   for (int tRow = 0; tRow < img->tileRows; tRow++)
1896   {
1897     int imageCol = 0;
1898     for (int tCol = 0; tCol < img->tileCols; tCol++)
1899     {
1900       CrxTile *tile = img->tiles + tRow * img->tileCols + tCol;
1901       CrxPlaneComp *planeComp = tile->comps + planeNumber;
1902       uint64_t tileMdatOffset = tile->dataOffset + tile->mdatQPDataSize + tile->mdatExtraSize + planeComp->dataOffset;
1903 
1904       // decode single tile
1905       if (crxSetupSubbandData(img, planeComp, tile, tileMdatOffset))
1906         return -1;
1907 
1908       if (img->levels)
1909       {
1910         if (crxIdwt53FilterInitialize(planeComp, img->levels, tile->qStep))
1911           return -1;
1912         for (int i = 0; i < tile->height; ++i)
1913         {
1914           if (crxIdwt53FilterDecode(planeComp, img->levels - 1, tile->qStep) ||
1915               crxIdwt53FilterTransform(planeComp, img->levels - 1))
1916             return -1;
1917           int32_t *lineData = crxIdwt53FilterGetLine(planeComp, img->levels - 1);
1918           crxConvertPlaneLine(img, imageRow + i, imageCol, planeNumber, lineData, tile->width);
1919         }
1920       }
1921       else
1922       {
1923         // we have the only subband in this case
1924         if (!planeComp->subBands->dataSize)
1925         {
1926           memset(planeComp->subBands->bandBuf, 0, planeComp->subBands->bandSize);
1927           return 0;
1928         }
1929 
1930         for (int i = 0; i < tile->height; ++i)
1931         {
1932           if (crxDecodeLine(planeComp->subBands->bandParam, planeComp->subBands->bandBuf))
1933             return -1;
1934           int32_t *lineData = (int32_t *)planeComp->subBands->bandBuf;
1935           crxConvertPlaneLine(img, imageRow + i, imageCol, planeNumber, lineData, tile->width);
1936         }
1937       }
1938       imageCol += tile->width;
1939     }
1940     imageRow += img->tiles[tRow * img->tileCols].height;
1941   }
1942 
1943   return 0;
1944 }
1945 
1946 uint32_t crxReadQP(CrxBitstream *bitStrm, int32_t kParam)
1947 {
1948   uint32_t qp = crxBitstreamGetZeros(bitStrm);
1949   if (qp >= 23)
1950     qp = crxBitstreamGetBits(bitStrm, 8);
1951   else if (kParam)
1952     qp = crxBitstreamGetBits(bitStrm, kParam) | (qp << kParam);
1953 
1954   return qp;
1955 }
1956 
1957 void crxDecodeGolombTop(CrxBitstream *bitStrm, int32_t width, int32_t *lineBuf, int32_t *kParam)
1958 {
1959   lineBuf[0] = 0;
1960   while (width-- > 0)
1961   {
1962     lineBuf[1] = lineBuf[0];
1963     uint32_t qp = crxReadQP(bitStrm, *kParam);
1964     lineBuf[1] += -(int32_t)(qp & 1) ^ (int32_t)(qp >> 1);
1965     *kParam = crxPredictKParameter(*kParam, qp, 7);
1966     ++lineBuf;
1967   }
1968   lineBuf[1] = lineBuf[0] + 1;
1969 }
1970 
1971 void crxDecodeGolombNormal(CrxBitstream *bitStrm, int32_t width, int32_t *lineBuf0, int32_t *lineBuf1, int32_t *kParam)
1972 {
1973   lineBuf1[0] = lineBuf0[1];
1974   int32_t deltaH = lineBuf0[1] - lineBuf0[0];
1975   while (width-- > 0)
1976   {
1977     lineBuf1[1] = crxPrediction(lineBuf1[0], lineBuf0[1], deltaH, lineBuf0[0] - lineBuf1[0]);
1978     uint32_t qp = crxReadQP(bitStrm, *kParam);
1979     lineBuf1[1] += -(int32_t)(qp & 1) ^ (int32_t)(qp >> 1);
1980     if (width)
1981     {
1982       deltaH = lineBuf0[2] - lineBuf0[1];
1983       *kParam = crxPredictKParameter(*kParam, (qp + 2 * _abs(deltaH)) >> 1, 7);
1984       ++lineBuf0;
1985     }
1986     else
1987       *kParam = crxPredictKParameter(*kParam, qp, 7);
1988     ++lineBuf1;
1989   }
1990   lineBuf1[1] = lineBuf1[0] + 1;
1991 }
1992 
1993 int crxMakeQStep(CrxImage *img, CrxTile *tile, int32_t *qpTable, uint32_t /*totalQP*/)
1994 {
1995   if (img->levels > 3 || img->levels < 1)
1996     return -1;
1997   int qpWidth = (tile->width >> 3) + ((tile->width & 7) != 0);
1998   int qpHeight = (tile->height >> 1) + (tile->height & 1);
1999   int qpHeight4 = (tile->height >> 2) + ((tile->height & 3) != 0);
2000   int qpHeight8 = (tile->height >> 3) + ((tile->height & 7) != 0);
2001   uint32_t totalHeight = qpHeight;
2002   if (img->levels > 1)
2003     totalHeight += qpHeight4;
2004   if (img->levels > 2)
2005     totalHeight += qpHeight8;
2006     tile->qStep = (CrxQStep *)
2007 #ifdef LIBRAW_CR3_MEMPOOL
2008                       img->memmgr.
2009 #endif
2010                   malloc(totalHeight * qpWidth * sizeof(uint32_t) + img->levels * sizeof(CrxQStep));
2011 
2012   if (!tile->qStep)
2013     return -1;
2014   uint32_t *qStepTbl = (uint32_t *)(tile->qStep + img->levels);
2015   CrxQStep *qStep = tile->qStep;
2016   switch (img->levels)
2017   {
2018   case 3:
2019     qStep->qStepTbl = qStepTbl;
2020     qStep->width = qpWidth;
2021     qStep->height = qpHeight8;
2022     for (int qpRow = 0; qpRow < qpHeight8; ++qpRow)
2023     {
2024       int row0Idx = qpWidth * _min(4 * qpRow, qpHeight - 1);
2025       int row1Idx = qpWidth * _min(4 * qpRow + 1, qpHeight - 1);
2026       int row2Idx = qpWidth * _min(4 * qpRow + 2, qpHeight - 1);
2027       int row3Idx = qpWidth * _min(4 * qpRow + 3, qpHeight - 1);
2028 
2029       for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl)
2030       {
2031         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         quantVal = ((quantVal < 0) * 3 + quantVal) >> 2;
2034         if (quantVal / 6 >= 6)
2035           *qStepTbl = q_step_tbl[quantVal % 6] << ((quantVal / 6 - 6 ) & 0x1f);
2036         else
2037           *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6);
2038       }
2039     }
2040     // continue to the next level - we always decode all levels
2041     ++qStep;
2042   case 2:
2043     qStep->qStepTbl = qStepTbl;
2044     qStep->width = qpWidth;
2045     qStep->height = qpHeight4;
2046     for (int qpRow = 0; qpRow < qpHeight4; ++qpRow)
2047     {
2048       int row0Idx = qpWidth * _min(2 * qpRow, qpHeight - 1);
2049       int row1Idx = qpWidth * _min(2 * qpRow + 1, qpHeight - 1);
2050 
2051       for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl)
2052       {
2053         int32_t quantVal = (qpTable[row0Idx++] + qpTable[row1Idx++]) / 2;
2054         if (quantVal / 6 >= 6)
2055           *qStepTbl = q_step_tbl[quantVal % 6] << ((quantVal / 6 - 6) & 0x1f);
2056         else
2057           *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6);
2058       }
2059     }
2060     // continue to the next level - we always decode all levels
2061     ++qStep;
2062   case 1:
2063     qStep->qStepTbl = qStepTbl;
2064     qStep->width = qpWidth;
2065     qStep->height = qpHeight;
2066     for (int qpRow = 0; qpRow < qpHeight; ++qpRow)
2067       for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl, ++qpTable)
2068         if (*qpTable / 6 >= 6)
2069           *qStepTbl = q_step_tbl[*qpTable % 6] << ((*qpTable / 6 - 6) & 0x1f);
2070         else
2071           *qStepTbl = q_step_tbl[*qpTable % 6] >> (6 - *qpTable / 6);
2072 
2073     break;
2074   }
2075   return 0;
2076 }
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 {
2082   if (hdr->version == 0x200)
2083   {
2084     band->rowStartAddOn = rowStartIdx;
2085     band->rowEndAddOn = bandHeightExCoef;
2086     band->colStartAddOn = colStartIdx;
2087     band->colEndAddOn = bandWidthExCoef;
2088     band->levelShift = 3 - level;
2089   }
2090   else
2091   {
2092     band->rowStartAddOn = 0;
2093     band->rowEndAddOn = 0;
2094     band->colStartAddOn = 0;
2095     band->colEndAddOn = 0;
2096     band->levelShift = 0;
2097   }
2098 }
2099 
2100 int crxProcessSubbands(crx_data_header_t *hdr, CrxImage *img, CrxTile *tile, CrxPlaneComp *comp)
2101 {
2102   CrxSubband *band = comp->subBands + img->subbandCount - 1; // set to last band
2103   uint32_t bandHeight = tile->height;
2104   uint32_t bandWidth = tile->width;
2105   int32_t bandWidthExCoef = 0;
2106   int32_t bandHeightExCoef = 0;
2107   if (img->levels)
2108   {
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     int32_t *rowExCoef = exCoefNumTbl + 0x30 * (img->levels - 1) + 6 * (tile->width & 7);
2115     int32_t *colExCoef = exCoefNumTbl + 0x30 * (img->levels - 1) + 6 * (tile->height & 7);
2116     for (int level = 0; level < img->levels; ++level)
2117     {
2118       int32_t widthOddPixel = bandWidth & 1;
2119       int32_t heightOddPixel = bandHeight & 1;
2120       bandWidth = (widthOddPixel + bandWidth) >> 1;
2121       bandHeight = (heightOddPixel + bandHeight) >> 1;
2122 
2123       int32_t bandWidthExCoef0 = 0;
2124       int32_t bandWidthExCoef1 = 0;
2125       int32_t bandHeightExCoef0 = 0;
2126       int32_t bandHeightExCoef1 = 0;
2127       int32_t colStartIdx = 0;
2128       int32_t rowStartIdx = 0;
2129       if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
2130       {
2131         bandWidthExCoef0 = rowExCoef[2 * level];
2132         bandWidthExCoef1 = rowExCoef[2 * level + 1];
2133       }
2134       if (tile->tileFlag & E_HAS_TILES_ON_THE_LEFT)
2135       {
2136         ++bandWidthExCoef0;
2137         colStartIdx = 1;
2138       }
2139 
2140       if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)
2141       {
2142         bandHeightExCoef0 = colExCoef[2 * level];
2143         bandHeightExCoef1 = colExCoef[2 * level + 1];
2144       }
2145       if (tile->tileFlag & E_HAS_TILES_ON_THE_TOP)
2146       {
2147         ++bandHeightExCoef0;
2148         rowStartIdx = 1;
2149       }
2150 
2151       band[0].width = bandWidth + bandWidthExCoef0 - widthOddPixel;
2152       band[0].height = bandHeight + bandHeightExCoef0 - heightOddPixel;
2153       crxSetupSubbandIdx(hdr, img, band, level + 1, colStartIdx, bandWidthExCoef0 - colStartIdx, rowStartIdx,
2154                          bandHeightExCoef0 - rowStartIdx);
2155 
2156       band[-1].width = bandWidth + bandWidthExCoef1;
2157       band[-1].height = bandHeight + bandHeightExCoef0 - heightOddPixel;
2158 
2159       crxSetupSubbandIdx(hdr, img, band - 1, level + 1, 0, bandWidthExCoef1, rowStartIdx,
2160                          bandHeightExCoef0 - rowStartIdx);
2161 
2162       band[-2].width = bandWidth + bandWidthExCoef0 - widthOddPixel;
2163       band[-2].height = bandHeight + bandHeightExCoef1;
2164       crxSetupSubbandIdx(hdr, img, band - 2, level + 1, colStartIdx, bandWidthExCoef0 - colStartIdx, 0,
2165                          bandHeightExCoef1);
2166 
2167       band -= 3;
2168     }
2169     bandWidthExCoef = bandHeightExCoef = 0;
2170     if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT)
2171       bandWidthExCoef = rowExCoef[2 * img->levels - 1];
2172     if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)
2173       bandHeightExCoef = colExCoef[2 * img->levels - 1];
2174   }
2175   band->width = bandWidthExCoef + bandWidth;
2176   band->height = bandHeightExCoef + bandHeight;
2177   if (img->levels)
2178     crxSetupSubbandIdx(hdr, img, band, img->levels, 0, bandWidthExCoef, 0, bandHeightExCoef);
2179 
2180   return 0;
2181 }
2182 
2183 int crxReadSubbandHeaders(crx_data_header_t * /*hdr*/, CrxImage *img, CrxTile * /*tile*/, CrxPlaneComp *comp,
2184                           uint8_t **subbandMdatPtr, int32_t *mdatSize)
2185 {
2186   if (!img->subbandCount)
2187     return 0;
2188   int32_t subbandOffset = 0;
2189   CrxSubband *band = comp->subBands;
2190   for (int curSubband = 0; curSubband < img->subbandCount; curSubband++, band++)
2191   {
2192     if (*mdatSize < 4)
2193       return -1;
2194 
2195     int hdrSign = LibRaw::sgetn(2, *subbandMdatPtr);
2196     int hdrSize = LibRaw::sgetn(2, *subbandMdatPtr + 2);
2197     if (*mdatSize < hdrSize + 4)
2198       return -1;
2199     if ((hdrSign != 0xFF03 || hdrSize != 8) && (hdrSign != 0xFF13 || hdrSize != 16))
2200       return -1;
2201 
2202     int32_t subbandSize = LibRaw::sgetn(4, *subbandMdatPtr + 4);
2203 
2204     if (curSubband != ((*subbandMdatPtr)[8] & 0xF0) >> 4)
2205     {
2206       band->dataSize = subbandSize;
2207       return -1;
2208     }
2209 
2210     band->dataOffset = subbandOffset;
2211     band->kParam = 0;
2212     band->bandParam = 0;
2213     band->bandBuf = 0;
2214     band->bandSize = 0;
2215 
2216     if (hdrSign == 0xFF03)
2217     {
2218       // old header
2219       uint32_t bitData = LibRaw::sgetn(4, *subbandMdatPtr + 8);
2220       band->dataSize = subbandSize - (bitData & 0x7FFFF);
2221       band->supportsPartial = bitData & 0x8000000;
2222       band->qParam = (bitData >> 19) & 0xFF;
2223       band->qStepBase = 0;
2224       band->qStepMult = 0;
2225     }
2226     else
2227     {
2228       // new header
2229       if (LibRaw::sgetn(2, *subbandMdatPtr + 8) & 0xFFF)
2230         // partial and qParam are not supported
2231         return -1;
2232       if (LibRaw::sgetn(2, *subbandMdatPtr + 18))
2233         // new header terninated by 2 zero bytes
2234         return -1;
2235       band->supportsPartial = false;
2236       band->qParam = 0;
2237       band->dataSize = subbandSize - LibRaw::sgetn(2, *subbandMdatPtr + 16);
2238       band->qStepBase = LibRaw::sgetn(4, *subbandMdatPtr + 12);
2239       ;
2240       band->qStepMult = LibRaw::sgetn(2, *subbandMdatPtr + 10);
2241       ;
2242     }
2243 
2244     subbandOffset += subbandSize;
2245 
2246     *subbandMdatPtr += hdrSize + 4;
2247     *mdatSize -= hdrSize + 4;
2248   }
2249 
2250   return 0;
2251 }
2252 
2253 int crxReadImageHeaders(crx_data_header_t *hdr, CrxImage *img, uint8_t *mdatPtr, int32_t mdatHdrSize)
2254 {
2255   int nTiles = img->tileRows * img->tileCols;
2256 
2257   if (!nTiles)
2258     return -1;
2259 
2260   if (!img->tiles)
2261   {
2262       img->tiles = (CrxTile *)
2263 #ifdef LIBRAW_CR3_MEMPOOL
2264                        img->memmgr.
2265 #endif
2266                    calloc(sizeof(CrxTile) * nTiles + sizeof(CrxPlaneComp) * nTiles * img->nPlanes +
2267                               sizeof(CrxSubband) * nTiles * img->nPlanes * img->subbandCount,
2268                           1);
2269     if (!img->tiles)
2270       return -1;
2271 
2272     // memory areas in allocated chunk
2273     CrxTile *tile = img->tiles;
2274     CrxPlaneComp *comps = (CrxPlaneComp *)(tile + nTiles);
2275     CrxSubband *bands = (CrxSubband *)(comps + img->nPlanes * nTiles);
2276 
2277     for (int curTile = 0; curTile < nTiles; curTile++, tile++)
2278     {
2279       tile->tileFlag = 0; // tile neighbouring flags
2280       tile->tileNumber = curTile;
2281       tile->tileSize = 0;
2282       tile->comps = comps + curTile * img->nPlanes;
2283 
2284       if ((curTile + 1) % img->tileCols)
2285       {
2286         // not the last tile in a tile row
2287         tile->width = hdr->tileWidth;
2288         if (img->tileCols > 1)
2289         {
2290           tile->tileFlag = E_HAS_TILES_ON_THE_RIGHT;
2291           if (curTile % img->tileCols)
2292             // not the first tile in tile row
2293             tile->tileFlag |= E_HAS_TILES_ON_THE_LEFT;
2294         }
2295       }
2296       else
2297       {
2298         // last tile in a tile row
2299         tile->width = img->planeWidth - hdr->tileWidth * (img->tileCols - 1);
2300         if (img->tileCols > 1)
2301           tile->tileFlag = E_HAS_TILES_ON_THE_LEFT;
2302       }
2303       if (curTile < nTiles - img->tileCols)
2304       {
2305         // in first tile row
2306         tile->height = hdr->tileHeight;
2307         if (img->tileRows > 1)
2308         {
2309           tile->tileFlag |= E_HAS_TILES_ON_THE_BOTTOM;
2310           if (curTile >= img->tileCols)
2311             tile->tileFlag |= E_HAS_TILES_ON_THE_TOP;
2312         }
2313       }
2314       else
2315       {
2316         // non first tile row
2317         tile->height = img->planeHeight - hdr->tileHeight * (img->tileRows - 1);
2318         if (img->tileRows > 1)
2319           tile->tileFlag |= E_HAS_TILES_ON_THE_TOP;
2320       }
2321       if (img->nPlanes)
2322       {
2323         CrxPlaneComp *comp = tile->comps;
2324         CrxSubband *band = bands + curTile * img->nPlanes * img->subbandCount;
2325 
2326         for (int curComp = 0; curComp < img->nPlanes; curComp++, comp++)
2327         {
2328           comp->compNumber = curComp;
2329           comp->supportsPartial = true;
2330           comp->tileFlag = tile->tileFlag;
2331           comp->subBands = band;
2332           comp->compBuf = 0;
2333           comp->wvltTransform = 0;
2334           if (img->subbandCount)
2335           {
2336             for (int curBand = 0; curBand < img->subbandCount; curBand++, band++)
2337             {
2338               band->supportsPartial = false;
2339               band->qParam = 4;
2340               band->bandParam = 0;
2341               band->dataSize = 0;
2342             }
2343           }
2344         }
2345       }
2346     }
2347   }
2348 
2349   uint32_t tileOffset = 0;
2350   int32_t dataSize = mdatHdrSize;
2351   uint8_t *dataPtr = mdatPtr;
2352   CrxTile *tile = img->tiles;
2353 
2354   for (int curTile = 0; curTile < nTiles; ++curTile, ++tile)
2355   {
2356     if (dataSize < 4)
2357       return -1;
2358 
2359     int hdrSign = LibRaw::sgetn(2, dataPtr);
2360     int hdrSize = LibRaw::sgetn(2, dataPtr + 2);
2361     if ((hdrSign != 0xFF01 || hdrSize != 8) && (hdrSign != 0xFF11 || (hdrSize != 8 && hdrSize != 16)))
2362       return -1;
2363     if (dataSize < hdrSize + 4)
2364       return -1;
2365     int tailSign = LibRaw::sgetn(2, dataPtr + 10);
2366     if ((hdrSize == 8 && tailSign) || (hdrSize == 16 && tailSign != 0x4000))
2367       return -1;
2368     if (LibRaw::sgetn(2, dataPtr + 8) != (unsigned)curTile)
2369       return -1;
2370 
2371     dataSize -= hdrSize + 4;
2372 
2373     tile->tileSize = LibRaw::sgetn(4, dataPtr + 4);
2374     tile->dataOffset = tileOffset;
2375     tile->qStep = 0;
2376     if (hdrSize == 16)
2377     {
2378       // extended header data - terminated by 0 bytes
2379       if (LibRaw::sgetn(2, dataPtr + 18) != 0)
2380         return -1;
2381       tile->hasQPData = true;
2382       tile->mdatQPDataSize = LibRaw::sgetn(4, dataPtr + 12);
2383       tile->mdatExtraSize = LibRaw::sgetn(2, dataPtr + 16);
2384     }
2385     else
2386     {
2387       tile->hasQPData = false;
2388       tile->mdatQPDataSize = 0;
2389       tile->mdatExtraSize = 0;
2390     }
2391 
2392     dataPtr += hdrSize + 4;
2393     tileOffset += tile->tileSize;
2394 
2395     uint32_t compOffset = 0;
2396     CrxPlaneComp *comp = tile->comps;
2397 
2398     for (int compNum = 0; compNum < img->nPlanes; ++compNum, ++comp)
2399     {
2400       if (dataSize < 0xC)
2401         return -1;
2402       hdrSign = LibRaw::sgetn(2, dataPtr);
2403       hdrSize = LibRaw::sgetn(2, dataPtr + 2);
2404       if ((hdrSign != 0xFF02 && hdrSign != 0xFF12) || hdrSize != 8)
2405         return -1;
2406       if (compNum != dataPtr[8] >> 4)
2407         return -1;
2408       if (LibRaw::sgetn(3, dataPtr + 9) != 0)
2409         return -1;
2410 
2411       comp->compSize = LibRaw::sgetn(4, dataPtr + 4);
2412 
2413       int32_t compHdrRoundedBits = (dataPtr[8] >> 1) & 3;
2414       comp->supportsPartial = (dataPtr[8] & 8) != 0;
2415 
2416       comp->dataOffset = compOffset;
2417       comp->tileFlag = tile->tileFlag;
2418 
2419       compOffset += comp->compSize;
2420       dataSize -= 0xC;
2421       dataPtr += 0xC;
2422 
2423       comp->roundedBitsMask = 0;
2424 
2425       if (compHdrRoundedBits)
2426       {
2427         if (img->levels || !comp->supportsPartial)
2428           return -1;
2429 
2430         comp->roundedBitsMask = 1 << (compHdrRoundedBits - 1);
2431       }
2432 
2433       if (crxReadSubbandHeaders(hdr, img, tile, comp, &dataPtr, &dataSize) || crxProcessSubbands(hdr, img, tile, comp))
2434         return -1;
2435     }
2436   }
2437 
2438   if (hdr->version != 0x200)
2439     return 0;
2440 
2441   tile = img->tiles;
2442   for (int curTile = 0; curTile < nTiles; ++curTile, ++tile)
2443   {
2444     if (tile->hasQPData)
2445     {
2446       CrxBitstream bitStrm;
2447       bitStrm.bitData = 0;
2448       bitStrm.bitsLeft = 0;
2449       bitStrm.curPos = 0;
2450       bitStrm.curBufSize = 0;
2451       bitStrm.mdatSize = tile->mdatQPDataSize;
2452       bitStrm.curBufOffset = img->mdatOffset + tile->dataOffset;
2453       bitStrm.input = img->input;
2454 
2455       crxFillBuffer(&bitStrm);
2456 
2457       unsigned int qpWidth = (tile->width >> 3) + ((tile->width & 7) != 0);
2458       unsigned int qpHeight = (tile->height >> 1) + (tile->height & 1);
2459       unsigned long totalQP = qpHeight * qpWidth;
2460 
2461       try
2462       {
2463         std::vector<int32_t> qpTable(totalQP + 2 * (qpWidth + 2));
2464         int32_t *qpCurElem = qpTable.data();
2465         // 2 lines padded with extra pixels at the start and at the end
2466         int32_t *qpLineBuf = qpTable.data() + totalQP;
2467         int32_t kParam = 0;
2468         for (unsigned qpRow = 0; qpRow < qpHeight; ++qpRow)
2469         {
2470           int32_t *qpLine0 = qpRow & 1 ? qpLineBuf + qpWidth + 2 : qpLineBuf;
2471           int32_t *qpLine1 = qpRow & 1 ? qpLineBuf : qpLineBuf + qpWidth + 2;
2472 
2473           if (qpRow)
2474             crxDecodeGolombNormal(&bitStrm, qpWidth, qpLine0, qpLine1, &kParam);
2475           else
2476             crxDecodeGolombTop(&bitStrm, qpWidth, qpLine1, &kParam);
2477 
2478           for (unsigned qpCol = 0; qpCol < qpWidth; ++qpCol)
2479             *qpCurElem++ = qpLine1[qpCol + 1] + 4;
2480         }
2481 
2482         // now we read QP data - build tile QStep
2483         if (crxMakeQStep(img, tile, qpTable.data(), totalQP))
2484           return -1;
2485       }
2486       catch (...)
2487       {
2488         return -1;
2489       }
2490     }
2491   }
2492 
2493   return 0;
2494 }
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 {
2499   int IncrBitTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0};
2500 
2501   img->planeWidth = hdr->f_width;
2502   img->planeHeight = hdr->f_height;
2503 
2504   if (hdr->tileWidth < 0x16 || hdr->tileHeight < 0x16 || img->planeWidth > 0x7FFF || img->planeHeight > 0x7FFF)
2505     return -1;
2506 
2507   img->tileCols = (img->planeWidth + hdr->tileWidth - 1) / hdr->tileWidth;
2508   img->tileRows = (img->planeHeight + hdr->tileHeight - 1) / hdr->tileHeight;
2509 
2510   if (img->tileCols > 0xFF || img->tileRows > 0xFF || img->planeWidth - hdr->tileWidth * (img->tileCols - 1) < 0x16 ||
2511       img->planeHeight - hdr->tileHeight * (img->tileRows - 1) < 0x16)
2512     return -1;
2513 
2514   img->tiles = 0;
2515   img->levels = hdr->imageLevels;
2516   img->subbandCount = 3 * img->levels + 1; // 3 bands per level + one last LL
2517   img->nPlanes = hdr->nPlanes;
2518   img->nBits = hdr->nBits;
2519   img->encType = hdr->encType;
2520   img->samplePrecision = hdr->nBits + IncrBitTable[4 * hdr->encType + 2] + 1;
2521   img->mdatOffset = mdatOffset + hdr->mdatHdrSize;
2522   img->mdatSize = mdatSize;
2523   img->planeBuf = 0;
2524   img->outBufs[0] = img->outBufs[1] = img->outBufs[2] = img->outBufs[3] = 0;
2525   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   if (img->encType == 3 && img->nPlanes == 4 && img->nBits > 8)
2534   {
2535       img->planeBuf = (int16_t *)
2536 #ifdef LIBRAW_CR3_MEMPOOL
2537                           img->memmgr.
2538 #endif
2539                       malloc(img->planeHeight * img->planeWidth * img->nPlanes * ((img->samplePrecision + 7) >> 3));
2540     if (!img->planeBuf)
2541       return -1;
2542   }
2543 
2544   int32_t rowSize = 2 * img->planeWidth;
2545 
2546   if (img->nPlanes == 1)
2547     img->outBufs[0] = outBuf;
2548   else
2549     switch (hdr->cfaLayout)
2550     {
2551     case 0:
2552       // R G
2553       // G B
2554       img->outBufs[0] = outBuf;
2555       img->outBufs[1] = outBuf + 1;
2556       img->outBufs[2] = outBuf + rowSize;
2557       img->outBufs[3] = img->outBufs[2] + 1;
2558       break;
2559     case 1:
2560       // G R
2561       // B G
2562       img->outBufs[1] = outBuf;
2563       img->outBufs[0] = outBuf + 1;
2564       img->outBufs[3] = outBuf + rowSize;
2565       img->outBufs[2] = img->outBufs[3] + 1;
2566       break;
2567     case 2:
2568       // G B
2569       // R G
2570       img->outBufs[2] = outBuf;
2571       img->outBufs[3] = outBuf + 1;
2572       img->outBufs[0] = outBuf + rowSize;
2573       img->outBufs[1] = img->outBufs[0] + 1;
2574       break;
2575     case 3:
2576       // B G
2577       // G R
2578       img->outBufs[3] = outBuf;
2579       img->outBufs[2] = outBuf + 1;
2580       img->outBufs[1] = outBuf + rowSize;
2581       img->outBufs[0] = img->outBufs[1] + 1;
2582       break;
2583     }
2584 
2585   // read header
2586   return crxReadImageHeaders(hdr, img, mdatHdrPtr, mdatHdrSize);
2587 }
2588 
2589 int crxFreeImageData(CrxImage *img)
2590 {
2591 #ifdef LIBRAW_CR3_MEMPOOL
2592   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   return 0;
2618 }
2619 void LibRaw::crxLoadDecodeLoop(void *img, int nPlanes)
2620 {
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   for (int32_t plane = 0; plane < nPlanes; ++plane)
2636     if (crxDecodePlane(img, plane))
2637       derror();
2638 #endif
2639 }
2640 
2641 void LibRaw::crxConvertPlaneLineDf(void *p, int imageRow) { crxConvertPlaneLine((CrxImage *)p, imageRow); }
2642 
2643 void LibRaw::crxLoadFinalizeLoopE3(void *p, int planeHeight)
2644 {
2645 #ifdef LIBRAW_USE_OPENMP
2646 #pragma omp parallel for
2647 #endif
2648   for (int i = 0; i < planeHeight; ++i)
2649     crxConvertPlaneLineDf(p, i);
2650 }
2651 
2652 void LibRaw::crxLoadRaw()
2653 {
2654   CrxImage img;
2655   if (libraw_internal_data.unpacker_data.crx_track_selected < 0 ||
2656       libraw_internal_data.unpacker_data.crx_track_selected >= LIBRAW_CRXTRACKS_MAXCOUNT)
2657     derror();
2658 
2659   crx_data_header_t hdr =
2660       libraw_internal_data.unpacker_data.crx_header[libraw_internal_data.unpacker_data.crx_track_selected];
2661 
2662   if (libraw_internal_data.unpacker_data.data_size < (unsigned)hdr.mdatHdrSize)
2663     derror();
2664 
2665   img.input = libraw_internal_data.internal_data.input;
2666 
2667   // update sizes for the planes
2668   if (hdr.nPlanes == 4)
2669   {
2670     hdr.f_width >>= 1;
2671     hdr.f_height >>= 1;
2672     hdr.tileWidth >>= 1;
2673     hdr.tileHeight >>= 1;
2674   }
2675 
2676   imgdata.color.maximum = (1 << hdr.nBits) - 1;
2677 
2678   std::vector<uint8_t> hdrBuf(hdr.mdatHdrSize);
2679 
2680   unsigned bytes = 0;
2681   // read image header
2682 #ifdef LIBRAW_USE_OPENMP
2683 #pragma omp critical
2684 #endif
2685   {
2686 #ifndef LIBRAW_USE_OPENMP
2687     libraw_internal_data.internal_data.input->lock();
2688 #endif
2689     libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
2690     bytes = libraw_internal_data.internal_data.input->read(hdrBuf.data(), 1, hdr.mdatHdrSize);
2691 #ifndef LIBRAW_USE_OPENMP
2692     libraw_internal_data.internal_data.input->unlock();
2693 #endif
2694   }
2695 
2696   if (bytes != hdr.mdatHdrSize)
2697     throw LIBRAW_EXCEPTION_IO_EOF;
2698 
2699   // parse and setup the image data
2700   if (crxSetupImageData(&hdr, &img, (int16_t *)imgdata.rawdata.raw_image,
2701       libraw_internal_data.unpacker_data.data_offset, libraw_internal_data.unpacker_data.data_size,
2702       hdrBuf.data(), hdr.mdatHdrSize))
2703     throw LIBRAW_EXCEPTION_IO_CORRUPT;
2704 
2705   crxLoadDecodeLoop(&img, hdr.nPlanes);
2706 
2707   if (img.encType == 3)
2708     crxLoadFinalizeLoopE3(&img, img.planeHeight);
2709 
2710   crxFreeImageData(&img);
2711 }
2712 
2713 int LibRaw::crxParseImageHeader(uchar *cmp1TagData, int nTrack, int size)
2714 {
2715   if (nTrack < 0 || nTrack >= LIBRAW_CRXTRACKS_MAXCOUNT)
2716     return -1;
2717   if (!cmp1TagData)
2718     return -1;
2719 
2720   crx_data_header_t *hdr = &libraw_internal_data.unpacker_data.crx_header[nTrack];
2721 
2722   hdr->version = sgetn(2, cmp1TagData + 4);
2723   hdr->f_width = sgetn(4, cmp1TagData + 8);
2724   hdr->f_height = sgetn(4, cmp1TagData + 12);
2725   hdr->tileWidth = sgetn(4, cmp1TagData + 16);
2726   hdr->tileHeight = sgetn(4, cmp1TagData + 20);
2727   hdr->nBits = cmp1TagData[24];
2728   hdr->nPlanes = cmp1TagData[25] >> 4;
2729   hdr->cfaLayout = cmp1TagData[25] & 0xF;
2730   hdr->encType = cmp1TagData[26] >> 4;
2731   hdr->imageLevels = cmp1TagData[26] & 0xF;
2732   hdr->hasTileCols = cmp1TagData[27] >> 7;
2733   hdr->hasTileRows = (cmp1TagData[27] >> 6) & 1;
2734   hdr->mdatHdrSize = sgetn(4, cmp1TagData + 28);
2735   int extHeader = cmp1TagData[32] >> 7;
2736   int useMedianBits = 0;
2737   hdr->medianBits = hdr->nBits;
2738 
2739   if (extHeader && size >= 56 && hdr->nPlanes == 4)
2740     useMedianBits = cmp1TagData[56] >> 6 & 1;
2741 
2742   if (useMedianBits && size >= 84)
2743     hdr->medianBits = cmp1TagData[84];
2744 
2745   // validation
2746   if ((hdr->version != 0x100 && hdr->version != 0x200) || !hdr->mdatHdrSize)
2747     return -1;
2748   if (hdr->encType == 1)
2749   {
2750     if (hdr->nBits > 15)
2751       return -1;
2752   }
2753   else
2754   {
2755     if (hdr->encType && hdr->encType != 3)
2756       return -1;
2757     if (hdr->nBits > 14)
2758       return -1;
2759   }
2760 
2761   if (hdr->nPlanes == 1)
2762   {
2763     if (hdr->cfaLayout || hdr->encType || hdr->nBits != 8)
2764       return -1;
2765   }
2766   else if (hdr->nPlanes != 4 || hdr->f_width & 1 || hdr->f_height & 1 || hdr->tileWidth & 1 || hdr->tileHeight & 1 ||
2767            hdr->cfaLayout > 3 || hdr->nBits == 8)
2768     return -1;
2769 
2770   if (hdr->tileWidth > hdr->f_width || hdr->tileHeight > hdr->f_height)
2771     return -1;
2772 
2773   if (hdr->imageLevels > 3 || hdr->hasTileCols > 1 || hdr->hasTileRows > 1)
2774     return -1;
2775   return 0;
2776 }
2777 
2778 #undef _abs
2779 #undef _min
2780 #undef _constrain
2781 #undef libraw_inline