bool Lerc::Convert(const CntZImage& zImg, T* arr, BitMask* pBitMask) const { if (!arr || !zImg.getSize()) return false; const bool fltPnt = (typeid(*arr) == typeid(double)) || (typeid(*arr) == typeid(float)); int h = zImg.getHeight(); int w = zImg.getWidth(); if (pBitMask) { pBitMask->SetSize(w, h); pBitMask->SetAllValid(); } const CntZ* srcPtr = zImg.getData(); T* dstPtr = arr; int num = w * h; for (int k = 0; k < num; k++) { if (srcPtr->cnt > 0) *dstPtr = fltPnt ? (T)srcPtr->z : (T)floor(srcPtr->z + 0.5); else if (pBitMask) pBitMask->SetInvalid(k); srcPtr++; dstPtr++; } return true; }
bool Lerc::DecodeTempl(T* pData, // outgoing data bands const Byte* pLercBlob, size_t numBytesBlob, int nCols, int nRows, int nBands, BitMask* pBitMask) const // gets filled if not 0, even if all valid { if (!pLercBlob || !pData) return false; const Byte* pByte = pLercBlob; Byte* pByte1 = const_cast<Byte*>(pLercBlob); Lerc2 lerc2; CntZImage zImg; for (int iBand = 0; iBand < nBands; iBand++) { // first try Lerc2 unsigned int numBytesHeader = lerc2.ComputeNumBytesHeader(); Lerc2::HeaderInfo hdInfo; if (((size_t)(pByte - pLercBlob) + numBytesHeader <= numBytesBlob) && lerc2.GetHeaderInfo(pByte, hdInfo)) { if (hdInfo.nCols != nCols || hdInfo.nRows != nRows) return false; if ((pByte - pLercBlob) + (size_t)hdInfo.blobSize > numBytesBlob) return false; // init bitMask if (pBitMask && iBand == 0) pBitMask->SetSize(nCols, nRows); T* arr = pData + nCols * nRows * iBand; if (!lerc2.Decode(&pByte, arr, (pBitMask && iBand == 0) ? pBitMask->Bits() : 0)) return false; } else // then try Lerc1 { unsigned int numBytesHeader = CntZImage::computeNumBytesNeededToReadHeader(); if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob) return false; bool onlyZPart = iBand > 0; if (!zImg.read(&pByte1, 1e12, false, onlyZPart)) return false; if (zImg.getWidth() != nCols || zImg.getHeight() != nRows) return false; T* arr = pData + nCols * nRows * iBand; if (!Convert(zImg, arr, pBitMask)) return false; } } // iBand return true; }
// Unload a zImg into a buffer template <typename T> void CntZImgUFill(CntZImage &zImg, T *dst, const ILImage &img) { int h = static_cast<int>(zImg.getHeight()); int w = static_cast<int>(zImg.getWidth()); T *ptr = dst; T ndv = (T)(img.NoDataValue); // Use 0 if nodata is not defined if (!img.hasNoData) ndv = 0; for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) *ptr++ = (zImg(i, j).cnt == 0) ? ndv : (T)(zImg(i, j).z); }