diff options
Diffstat (limited to 'core/fxcodec/codec/fx_codec_flate.cpp')
-rw-r--r-- | core/fxcodec/codec/fx_codec_flate.cpp | 248 |
1 files changed, 56 insertions, 192 deletions
diff --git a/core/fxcodec/codec/fx_codec_flate.cpp b/core/fxcodec/codec/fx_codec_flate.cpp index c23de277fb..cd24b6624c 100644 --- a/core/fxcodec/codec/fx_codec_flate.cpp +++ b/core/fxcodec/codec/fx_codec_flate.cpp @@ -29,30 +29,34 @@ static int FPDFAPI_FlateGetTotalOut(void* context) { static int FPDFAPI_FlateGetTotalIn(void* context) { return ((z_stream*)context)->total_in; } -static void FPDFAPI_FlateCompress(unsigned char* dest_buf, + +static bool FPDFAPI_FlateCompress(unsigned char* dest_buf, unsigned long* dest_size, const unsigned char* src_buf, unsigned long src_size) { - compress(dest_buf, dest_size, src_buf, src_size); + return compress(dest_buf, dest_size, src_buf, src_size) == Z_OK; } + void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int), void (*free_func)(void*, void*)) { z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream)); - if (!p) { - return NULL; - } + if (!p) + return nullptr; + FXSYS_memset(p, 0, sizeof(z_stream)); p->zalloc = alloc_func; p->zfree = free_func; inflateInit(p); return p; } + void FPDFAPI_FlateInput(void* context, const unsigned char* src_buf, unsigned int src_size) { ((z_stream*)context)->next_in = (unsigned char*)src_buf; ((z_stream*)context)->avail_in = src_size; } + int FPDFAPI_FlateOutput(void* context, unsigned char* dest_buf, unsigned int dest_size) { @@ -67,16 +71,20 @@ int FPDFAPI_FlateOutput(void* context, } return ret; } + int FPDFAPI_FlateGetAvailIn(void* context) { return ((z_stream*)context)->avail_in; } + int FPDFAPI_FlateGetAvailOut(void* context) { return ((z_stream*)context)->avail_out; } + void FPDFAPI_FlateEnd(void* context) { inflateEnd((z_stream*)context); ((z_stream*)context)->zfree(0, context); } + } // extern "C" namespace { @@ -104,6 +112,7 @@ class CLZWDecoder { uint32_t m_StackLen; int m_CodeLen; }; + void CLZWDecoder::AddCode(uint32_t prefix_code, uint8_t append_char) { if (m_nCodes + m_Early == 4094) { return; @@ -229,108 +238,42 @@ int CLZWDecoder::Decode(uint8_t* dest_buf, return 0; } -uint8_t PaethPredictor(int a, int b, int c) { +uint8_t PathPredictor(int a, int b, int c) { int p = a + b - c; int pa = FXSYS_abs(p - a); int pb = FXSYS_abs(p - b); int pc = FXSYS_abs(p - c); - if (pa <= pb && pa <= pc) { + if (pa <= pb && pa <= pc) return (uint8_t)a; - } - if (pb <= pc) { + if (pb <= pc) return (uint8_t)b; - } return (uint8_t)c; } -FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf, - uint32_t& data_size, - int predictor, - int Colors, - int BitsPerComponent, - int Columns) { - const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; - const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; - if (row_size <= 0) - return FALSE; - const int row_count = (data_size + row_size - 1) / row_size; - const int last_row_size = data_size % row_size; +void PNG_PredictorEncode(uint8_t** data_buf, uint32_t* data_size) { + const int row_size = 7; + const int row_count = (*data_size + row_size - 1) / row_size; + const int last_row_size = *data_size % row_size; uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count); int byte_cnt = 0; - uint8_t* pSrcData = data_buf; + uint8_t* pSrcData = *data_buf; uint8_t* pDestData = dest_buf; for (int row = 0; row < row_count; row++) { - if (predictor == 10) { - pDestData[0] = 0; - int move_size = row_size; - if (move_size * (row + 1) > (int)data_size) { - move_size = data_size - (move_size * row); - } - FXSYS_memmove(pDestData + 1, pSrcData, move_size); - pDestData += (move_size + 1); - pSrcData += move_size; - byte_cnt += move_size; - continue; - } - for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) { - switch (predictor) { - case 11: { - pDestData[0] = 1; - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pSrcData[byte - BytesPerPixel]; - } - pDestData[byte + 1] = pSrcData[byte] - left; - } break; - case 12: { - pDestData[0] = 2; - uint8_t up = 0; - if (row) { - up = pSrcData[byte - row_size]; - } - pDestData[byte + 1] = pSrcData[byte] - up; - } break; - case 13: { - pDestData[0] = 3; - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pSrcData[byte - BytesPerPixel]; - } - uint8_t up = 0; - if (row) { - up = pSrcData[byte - row_size]; - } - pDestData[byte + 1] = pSrcData[byte] - (left + up) / 2; - } break; - case 14: { - pDestData[0] = 4; - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pSrcData[byte - BytesPerPixel]; - } - uint8_t up = 0; - if (row) { - up = pSrcData[byte - row_size]; - } - uint8_t upper_left = 0; - if (byte >= BytesPerPixel && row) { - upper_left = pSrcData[byte - row_size - BytesPerPixel]; - } - pDestData[byte + 1] = - pSrcData[byte] - PaethPredictor(left, up, upper_left); - } break; - default: { pDestData[byte + 1] = pSrcData[byte]; } break; - } - byte_cnt++; + for (int byte = 0; byte < row_size && byte_cnt < (int)*data_size; byte++) { + pDestData[0] = 2; + uint8_t up = 0; + if (row) + up = pSrcData[byte - row_size]; + pDestData[byte + 1] = pSrcData[byte] - up; + ++byte_cnt; } pDestData += (row_size + 1); pSrcData += row_size; } - FX_Free(data_buf); - data_buf = dest_buf; - data_size = (row_size + 1) * row_count - - (last_row_size > 0 ? (row_size - last_row_size) : 0); - return TRUE; + FX_Free(*data_buf); + *data_buf = dest_buf; + *data_size = (row_size + 1) * row_count - + (last_row_size > 0 ? (row_size - last_row_size) : 0); } void PNG_PredictLine(uint8_t* pDestData, @@ -390,7 +333,7 @@ void PNG_PredictLine(uint8_t* pDestData, if (byte >= BytesPerPixel && pLastLine) { upper_left = pLastLine[byte - BytesPerPixel]; } - pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); + pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left); break; } default: @@ -475,7 +418,7 @@ FX_BOOL PNG_Predictor(uint8_t*& data_buf, if (byte >= BytesPerPixel && row) { upper_left = pDestData[byte - row_size - BytesPerPixel]; } - pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); + pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left); break; } default: @@ -494,73 +437,6 @@ FX_BOOL PNG_Predictor(uint8_t*& data_buf, return TRUE; } -void TIFF_PredictorEncodeLine(uint8_t* dest_buf, - int row_size, - int BitsPerComponent, - int Colors, - int Columns) { - int BytesPerPixel = BitsPerComponent * Colors / 8; - if (BitsPerComponent < 8) { - uint8_t mask = 0x01; - if (BitsPerComponent == 2) { - mask = 0x03; - } else if (BitsPerComponent == 4) { - mask = 0x0F; - } - int row_bits = Colors * BitsPerComponent * Columns; - for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; - i -= BitsPerComponent) { - int col = i % 8; - int index = i / 8; - int col_pre = - (col == 0) ? (8 - BitsPerComponent) : (col - BitsPerComponent); - int index_pre = (col == 0) ? (index - 1) : index; - uint8_t cur = (dest_buf[index] >> (8 - col - BitsPerComponent)) & mask; - uint8_t left = - (dest_buf[index_pre] >> (8 - col_pre - BitsPerComponent)) & mask; - cur -= left; - cur &= mask; - cur <<= (8 - col - BitsPerComponent); - dest_buf[index] &= ~(mask << ((8 - col - BitsPerComponent))); - dest_buf[index] |= cur; - } - } else if (BitsPerComponent == 8) { - for (int i = row_size - 1; i >= BytesPerPixel; i--) { - dest_buf[i] -= dest_buf[i - BytesPerPixel]; - } - } else { - for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; - i -= BytesPerPixel) { - uint16_t pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; - pixel -= - (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; - dest_buf[i] = pixel >> 8; - dest_buf[i + 1] = (uint8_t)pixel; - } - } -} - -FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, - uint32_t& data_size, - int Colors, - int BitsPerComponent, - int Columns) { - int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; - if (row_size == 0) - return FALSE; - const int row_count = (data_size + row_size - 1) / row_size; - const int last_row_size = data_size % row_size; - for (int row = 0; row < row_count; row++) { - uint8_t* scan_line = data_buf + row * row_size; - if ((row + 1) * row_size > (int)data_size) { - row_size = last_row_size; - } - TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, - Columns); - } - return TRUE; -} - void TIFF_PredictLine(uint8_t* dest_buf, uint32_t row_size, int BitsPerComponent, @@ -965,41 +841,29 @@ uint32_t CCodec_FlateModule::FlateOrLZWDecode(FX_BOOL bLZW, } return ret ? offset : FX_INVALID_OFFSET; } -FX_BOOL CCodec_FlateModule::Encode(const uint8_t* src_buf, + +bool CCodec_FlateModule::Encode(const uint8_t* src_buf, + uint32_t src_size, + uint8_t** dest_buf, + uint32_t* dest_size) { + *dest_size = src_size + src_size / 1000 + 12; + *dest_buf = FX_Alloc(uint8_t, *dest_size); + unsigned long temp_size = *dest_size; + if (!FPDFAPI_FlateCompress(*dest_buf, &temp_size, src_buf, src_size)) + return false; + + *dest_size = (uint32_t)temp_size; + return true; +} + +bool CCodec_FlateModule::PngEncode(const uint8_t* src_buf, uint32_t src_size, - int predictor, - int Colors, - int BitsPerComponent, - int Columns, - uint8_t*& dest_buf, - uint32_t& dest_size) { - if (predictor != 2 && predictor < 10) { - return Encode(src_buf, src_size, dest_buf, dest_size); - } - uint8_t* pSrcBuf = NULL; - pSrcBuf = FX_Alloc(uint8_t, src_size); + uint8_t** dest_buf, + uint32_t* dest_size) { + uint8_t* pSrcBuf = FX_Alloc(uint8_t, src_size); FXSYS_memcpy(pSrcBuf, src_buf, src_size); - FX_BOOL ret = TRUE; - if (predictor == 2) { - ret = TIFF_PredictorEncode(pSrcBuf, src_size, Colors, BitsPerComponent, - Columns); - } else if (predictor >= 10) { - ret = PNG_PredictorEncode(pSrcBuf, src_size, predictor, Colors, - BitsPerComponent, Columns); - } - if (ret) - ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); + PNG_PredictorEncode(&pSrcBuf, &src_size); + bool ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); FX_Free(pSrcBuf); return ret; } -FX_BOOL CCodec_FlateModule::Encode(const uint8_t* src_buf, - uint32_t src_size, - uint8_t*& dest_buf, - uint32_t& dest_size) { - dest_size = src_size + src_size / 1000 + 12; - dest_buf = FX_Alloc(uint8_t, dest_size); - unsigned long temp_size = dest_size; - FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); - dest_size = (uint32_t)temp_size; - return TRUE; -} |