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(¶m->bitStream); 0348 if (bitCode >= 41) 0349 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0350 else if (param->kParam) 0351 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream, 1)) 0385 { 0386 nSyms = 1; 0387 while (crxBitstreamGetBits(¶m->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(¶m->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(¶m->bitStream); 0454 if (bitCode >= 41) 0455 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0456 else if (param->kParam) 0457 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream, 1)) 0502 { 0503 nSyms = 1; 0504 while (crxBitstreamGetBits(¶m->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(¶m->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(¶m->bitStream); 0566 if (bitCode >= 41) 0567 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0568 else if (param->kParam) 0569 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream, 1)) 0584 { 0585 nSyms = 1; 0586 if (i != param->subbandWidth - 1) 0587 { 0588 while (crxBitstreamGetBits(¶m->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(¶m->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(¶m->bitStream); 0627 if (bitCode >= 41) 0628 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0629 else if (param->kParam) 0630 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream); 0640 if (bitCode >= 41) 0641 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0642 else if (param->kParam) 0643 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream); 0660 if (bitCode >= 41) 0661 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0662 else if (param->kParam) 0663 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream, 1)) 0687 { 0688 nSyms = 1; 0689 while (crxBitstreamGetBits(¶m->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(¶m->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(¶m->bitStream); 0729 if (bitCode >= 41) 0730 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0731 else if (param->kParam) 0732 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream); 0742 if (bitCode >= 41) 0743 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0744 else if (param->kParam) 0745 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream, 1)) 0771 { 0772 nSyms = 1; 0773 while (crxBitstreamGetBits(¶m->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(¶m->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(¶m->bitStream); 0813 if (bitCode >= 41) 0814 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0815 else if (param->kParam) 0816 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream); 0827 if (bitCode >= 41) 0828 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0829 else if (param->kParam) 0830 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream); 0852 if (bitCode >= 41) 0853 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0854 else if (param->kParam) 0855 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream, 1)) 0863 { 0864 nSyms = 1; 0865 while (crxBitstreamGetBits(¶m->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(¶m->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(¶m->bitStream); 0903 if (bitCode >= 41) 0904 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0905 else if (param->kParam) 0906 bitCode = crxBitstreamGetBits(¶m->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(¶m->bitStream); 0918 if (bitCode >= 41) 0919 bitCode = crxBitstreamGetBits(¶m->bitStream, 21); 0920 else if (param->kParam) 0921 bitCode = crxBitstreamGetBits(¶m->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