PCL XL Delta Row Compression Method (eDeltaRowCompression) c++实现
FX_BOOL Encode(FX_BYTE* inPut, FX_INT32 width, FX_INT32 height, FX_BYTE*& outPut, FX_INT32& encodeLength) { AllocProxy<FX_BYTE> pResult((width * 2 + 4) * height); AllocProxy<FX_INT16> pLength(height); AllocProxy<FX_BYTE> pFirstSeed(width); memset(pFirstSeed, 0, width); FX_BYTE* pSeed = pFirstSeed; for (int i = 0; i < height; i++) { FX_INT32 rowLength = 0; FX_BYTE* pOut = pResult + (width * 2 + 4) * i; if (i == 1) { pOut[rowLength++] = 0; pOut[rowLength++] = 0; } rowLength += 2; if (i >= 1) { pSeed = inPut + (i - 1) * width; } FX_BYTE* rowInput = inPut + (width * i); CompressRow(pSeed, rowInput, width, pOut, rowLength); if (i == 1) { pOut[2] = rowLength - 4; pOut[3] = (rowLength - 4) >> 8; } else { pOut[0] = rowLength - 2; pOut[1] = (rowLength - 2) >> 8; } if (rowLength >= 65535) return FALSE; pLength[i] = rowLength; } for (int i = 0; i < height; i++) { encodeLength += pLength[i]; } outPut = FX_Alloc(FX_BYTE, encodeLength); FX_INT32 copyOffSet = 0; for (int i = 0; i < height; i++) { memcpy(outPut + copyOffSet, pResult + (width * 2 + 4) * i, pLength[i]); copyOffSet += pLength[i]; } return TRUE; } void SetCommand(FX_BYTE* inPut, FX_BYTE* outPut, FX_INT32& index, FX_INT32 offSet, FX_INT32 replaceNum) { if (offSet <= 30) { outPut[index++] = offSet | ((replaceNum - 1) << 5); } else { outPut[index++] = 0x1f | ((replaceNum - 1) << 5); offSet -= 31; while (offSet >= 255) { outPut[index++] = 0xff; offSet -= 255; } outPut[index++] = offSet; } for (FX_INT32 i = 0; i < replaceNum; i++) { outPut[index++] = inPut[i]; } } void CompressRow(FX_BYTE* seed, FX_BYTE* inPut, FX_INT32 inLength, FX_BYTE* outPut, FX_INT32& outLength) { FX_INT32 offSet = 0; FX_INT32 replaceNum = 0; FX_BYTE replaceValue = 0; for (FX_INT32 i = 0; i < inLength; i++) { if (inPut[i] == seed[i]) offSet++; else { replaceNum = 0; while ((i + replaceNum) < inLength && replaceNum < 9 && inPut[i + replaceNum] != seed[i + replaceNum]) { replaceNum++; } if (replaceNum >= 9) replaceNum = 8; SetCommand(inPut + i, outPut, outLength, offSet, replaceNum); i += replaceNum - 1; offSet = 0; } } }