1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved. 2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Use of this source code is governed by a BSD-style license that can be 3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// found in the LICENSE file. 4ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcodec/codec/codec_int.h" 8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <algorithm> 10ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include <memory> 114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <utility> 124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <vector> 13ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcodec/fx_codec.h" 154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcrt/fx_ext.h" 164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "third_party/base/ptr_util.h" 17ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "third_party/zlib_v128/zlib.h" 18ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 19ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannextern "C" { 20ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannstatic void* my_alloc_func(void* opaque, 21ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned int items, 22ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned int size) { 23ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return FX_Alloc2D(uint8_t, items, size); 24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 25ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannstatic void my_free_func(void* opaque, void* address) { 26ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(address); 27ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 28ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannstatic int FPDFAPI_FlateGetTotalOut(void* context) { 29ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return ((z_stream*)context)->total_out; 30ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 31ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannstatic int FPDFAPI_FlateGetTotalIn(void* context) { 32ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return ((z_stream*)context)->total_in; 33ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic bool FPDFAPI_FlateCompress(unsigned char* dest_buf, 36ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned long* dest_size, 37ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const unsigned char* src_buf, 38ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned long src_size) { 394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return compress(dest_buf, dest_size, src_buf, src_size) == Z_OK; 40e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 42ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int), 43ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann void (*free_func)(void*, void*)) { 44ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream)); 454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!p) 464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 48ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memset(p, 0, sizeof(z_stream)); 49ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann p->zalloc = alloc_func; 50ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann p->zfree = free_func; 51ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inflateInit(p); 52ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return p; 53ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 55ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid FPDFAPI_FlateInput(void* context, 56ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const unsigned char* src_buf, 57ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned int src_size) { 58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ((z_stream*)context)->next_in = (unsigned char*)src_buf; 59ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ((z_stream*)context)->avail_in = src_size; 60ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 62ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannint FPDFAPI_FlateOutput(void* context, 63ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned char* dest_buf, 64ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned int dest_size) { 65ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ((z_stream*)context)->next_out = dest_buf; 66ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ((z_stream*)context)->avail_out = dest_size; 67ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned int pre_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); 68ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int ret = inflate((z_stream*)context, Z_SYNC_FLUSH); 69ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned int post_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); 70ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann unsigned int written = post_pos - pre_pos; 71ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (written < dest_size) { 72ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memset(dest_buf + written, '\0', dest_size - written); 73ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 74ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return ret; 75ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 77ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannint FPDFAPI_FlateGetAvailIn(void* context) { 78ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return ((z_stream*)context)->avail_in; 79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 81ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannint FPDFAPI_FlateGetAvailOut(void* context) { 82ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return ((z_stream*)context)->avail_out; 83ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 85ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid FPDFAPI_FlateEnd(void* context) { 86ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann inflateEnd((z_stream*)context); 87ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ((z_stream*)context)->zfree(0, context); 88ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 90ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} // extern "C" 91ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 92ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannnamespace { 93ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 94ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannclass CLZWDecoder { 95ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann public: 96ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Decode(uint8_t* output, 974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t& outlen, 98ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* input, 994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t& size, 1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool bEarlyChange); 101ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 102ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann private: 1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann void AddCode(uint32_t prefix_code, uint8_t append_char); 1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann void DecodeString(uint32_t code); 105ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t m_InPos; 1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t m_OutPos; 108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* m_pOutput; 109ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* m_pInput; 1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool m_Early; 1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t m_CodeArray[5021]; 1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t m_nCodes; 113ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t m_DecodeStack[4000]; 1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t m_StackLen; 115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int m_CodeLen; 116e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}; 1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CLZWDecoder::AddCode(uint32_t prefix_code, uint8_t append_char) { 119ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_nCodes + m_Early == 4094) { 120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 122ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_CodeArray[m_nCodes++] = (prefix_code << 16) | append_char; 123ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_nCodes + m_Early == 512 - 258) { 124ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_CodeLen = 10; 125ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (m_nCodes + m_Early == 1024 - 258) { 126ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_CodeLen = 11; 127ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (m_nCodes + m_Early == 2048 - 258) { 128ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_CodeLen = 12; 129ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 130e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CLZWDecoder::DecodeString(uint32_t code) { 132ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 133ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int index = code - 258; 134ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (index < 0 || index >= (int)m_nCodes) { 135ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 136e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t data = m_CodeArray[index]; 138e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (m_StackLen >= sizeof(m_DecodeStack)) { 139ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 140e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 141ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_DecodeStack[m_StackLen++] = (uint8_t)data; 142ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann code = data >> 16; 143ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 144ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_StackLen >= sizeof(m_DecodeStack)) { 145ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 146ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 147ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_DecodeStack[m_StackLen++] = (uint8_t)code; 148e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 149ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannint CLZWDecoder::Decode(uint8_t* dest_buf, 1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t& dest_size, 151ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* src_buf, 1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t& src_size, 1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool bEarlyChange) { 154ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_CodeLen = 9; 155ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_InPos = 0; 156ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_OutPos = 0; 157ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pInput = src_buf; 158ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pOutput = dest_buf; 159ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_Early = bEarlyChange ? 1 : 0; 160ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_nCodes = 0; 1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t old_code = (uint32_t)-1; 1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t last_char = 0; 163ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 164ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_InPos + m_CodeLen > src_size * 8) { 165ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 166ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 167ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int byte_pos = m_InPos / 8; 168ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int bit_pos = m_InPos % 8, bit_left = m_CodeLen; 1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t code = 0; 170ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (bit_pos) { 171ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bit_left -= 8 - bit_pos; 172ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann code = (m_pInput[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left; 173ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 174ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (bit_left < 8) { 175ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann code |= m_pInput[byte_pos] >> (8 - bit_left); 176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else { 177ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bit_left -= 8; 178ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann code |= m_pInput[byte_pos++] << bit_left; 179ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (bit_left) { 180ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann code |= m_pInput[byte_pos] >> (8 - bit_left); 181ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 182ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 183ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_InPos += m_CodeLen; 184ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (code < 256) { 185ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_OutPos == dest_size) { 186ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return -5; 187ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 188ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_pOutput) { 189ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pOutput[m_OutPos] = (uint8_t)code; 190ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 191ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_OutPos++; 192ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann last_char = (uint8_t)code; 1934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (old_code != (uint32_t)-1) { 194ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann AddCode(old_code, last_char); 195ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 196ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann old_code = code; 197ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (code == 256) { 198ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_CodeLen = 9; 199ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_nCodes = 0; 2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann old_code = (uint32_t)-1; 201ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (code == 257) { 202ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 203ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (old_code == (uint32_t)-1) { 205ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 2; 206ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 207ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_StackLen = 0; 208ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (code >= m_nCodes + 258) { 209ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_StackLen < sizeof(m_DecodeStack)) { 210ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_DecodeStack[m_StackLen++] = last_char; 211ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 212ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann DecodeString(old_code); 213ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 214ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann DecodeString(code); 215ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 216ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_OutPos + m_StackLen > dest_size) { 217ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return -5; 218ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 219ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_pOutput) { 2204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (uint32_t i = 0; i < m_StackLen; i++) { 221ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pOutput[m_OutPos + i] = m_DecodeStack[m_StackLen - i - 1]; 222ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 223ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 224ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_OutPos += m_StackLen; 225ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann last_char = m_DecodeStack[m_StackLen - 1]; 226ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (old_code < 256) { 227ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann AddCode(old_code, last_char); 228ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (old_code - 258 >= m_nCodes) { 229ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_size = m_OutPos; 230ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann src_size = (m_InPos + 7) / 8; 231ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 232ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 233ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann AddCode(old_code, last_char); 234ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 235ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann old_code = code; 236ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 237ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 238ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_size = m_OutPos; 239ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann src_size = (m_InPos + 7) / 8; 240ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 241e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 242ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannuint8_t PathPredictor(int a, int b, int c) { 244ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int p = a + b - c; 245ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int pa = FXSYS_abs(p - a); 246ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int pb = FXSYS_abs(p - b); 247ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int pc = FXSYS_abs(p - c); 2484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (pa <= pb && pa <= pc) 249ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return (uint8_t)a; 2504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (pb <= pc) 251ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return (uint8_t)b; 252ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return (uint8_t)c; 253ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 254ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNG_PredictorEncode(uint8_t** data_buf, uint32_t* data_size) { 2564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int row_size = 7; 2574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int row_count = (*data_size + row_size - 1) / row_size; 2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int last_row_size = *data_size % row_size; 259ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count); 260ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int byte_cnt = 0; 2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* pSrcData = *data_buf; 262ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* pDestData = dest_buf; 263ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (int row = 0; row < row_count; row++) { 2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int byte = 0; byte < row_size && byte_cnt < (int)*data_size; byte++) { 2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pDestData[0] = 2; 2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t up = 0; 2674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row) 2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann up = pSrcData[byte - row_size]; 2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pDestData[byte + 1] = pSrcData[byte] - up; 2704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++byte_cnt; 271ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 272ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData += (row_size + 1); 273ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pSrcData += row_size; 274ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 2754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FX_Free(*data_buf); 2764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *data_buf = dest_buf; 2774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *data_size = (row_size + 1) * row_count - 2784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (last_row_size > 0 ? (row_size - last_row_size) : 0); 279ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 280ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 281ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid PNG_PredictLine(uint8_t* pDestData, 282ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* pSrcData, 283ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* pLastLine, 284ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int bpc, 285ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int nColors, 286ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int nPixels) { 287ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int row_size = (nPixels * bpc * nColors + 7) / 8; 288ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int BytesPerPixel = (bpc * nColors + 7) / 8; 289ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t tag = pSrcData[0]; 290ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (tag == 0) { 291ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memmove(pDestData, pSrcData + 1, row_size); 292ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 293ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 294ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (int byte = 0; byte < row_size; byte++) { 295ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t raw_byte = pSrcData[byte + 1]; 296ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann switch (tag) { 297ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 1: { 298ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t left = 0; 299ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (byte >= BytesPerPixel) { 300ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann left = pDestData[byte - BytesPerPixel]; 301ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 302ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData[byte] = raw_byte + left; 303ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 304ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 305ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 2: { 306ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t up = 0; 307ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (pLastLine) { 308ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann up = pLastLine[byte]; 309ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 310ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData[byte] = raw_byte + up; 311ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 312ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 313ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 3: { 314ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t left = 0; 315ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (byte >= BytesPerPixel) { 316ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann left = pDestData[byte - BytesPerPixel]; 317ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 318ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t up = 0; 319ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (pLastLine) { 320ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann up = pLastLine[byte]; 321ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 322ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData[byte] = raw_byte + (up + left) / 2; 323ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 324ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 325ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 4: { 326ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t left = 0; 327ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (byte >= BytesPerPixel) { 328ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann left = pDestData[byte - BytesPerPixel]; 329ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 330ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t up = 0; 331ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (pLastLine) { 332ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann up = pLastLine[byte]; 333ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 334ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t upper_left = 0; 335ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (byte >= BytesPerPixel && pLastLine) { 336ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann upper_left = pLastLine[byte - BytesPerPixel]; 337ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left); 339ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 340ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 341ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann default: 342ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData[byte] = raw_byte; 343ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 344ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 345ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 346ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 347ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 3484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool PNG_Predictor(uint8_t*& data_buf, 3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t& data_size, 3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int Colors, 3514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int BitsPerComponent, 3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int Columns) { 353ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; 354ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; 355ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (row_size <= 0) 3564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 357ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const int row_count = (data_size + row_size) / (row_size + 1); 358ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (row_count <= 0) 3594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 360ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const int last_row_size = data_size % (row_size + 1); 361ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); 362ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int byte_cnt = 0; 363ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* pSrcData = data_buf; 364ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* pDestData = dest_buf; 365ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (int row = 0; row < row_count; row++) { 366ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t tag = pSrcData[0]; 367ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann byte_cnt++; 368ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (tag == 0) { 369ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int move_size = row_size; 370ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ((row + 1) * (move_size + 1) > (int)data_size) { 371ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann move_size = last_row_size - 1; 372ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 373ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memmove(pDestData, pSrcData + 1, move_size); 374ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pSrcData += move_size + 1; 375ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData += move_size; 376ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann byte_cnt += move_size; 377ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 378ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 379ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) { 380ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t raw_byte = pSrcData[byte + 1]; 381ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann switch (tag) { 382ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 1: { 383ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t left = 0; 384ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (byte >= BytesPerPixel) { 385ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann left = pDestData[byte - BytesPerPixel]; 386ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 387ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData[byte] = raw_byte + left; 388ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 389ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 390ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 2: { 391ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t up = 0; 392ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (row) { 393ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann up = pDestData[byte - row_size]; 394ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 395ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData[byte] = raw_byte + up; 396ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 397ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 398ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 3: { 399ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t left = 0; 400ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (byte >= BytesPerPixel) { 401ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann left = pDestData[byte - BytesPerPixel]; 402ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 403ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t up = 0; 404ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (row) { 405ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann up = pDestData[byte - row_size]; 406ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 407ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData[byte] = raw_byte + (up + left) / 2; 408ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 409ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 410ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann case 4: { 411ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t left = 0; 412ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (byte >= BytesPerPixel) { 413ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann left = pDestData[byte - BytesPerPixel]; 414ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 415ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t up = 0; 416ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (row) { 417ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann up = pDestData[byte - row_size]; 418ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 419ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t upper_left = 0; 420ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (byte >= BytesPerPixel && row) { 421ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann upper_left = pDestData[byte - row_size - BytesPerPixel]; 422ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 4234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left); 424ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 425ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 426ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann default: 427ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData[byte] = raw_byte; 428ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 429ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 430ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann byte_cnt++; 431ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 432ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pSrcData += row_size + 1; 433ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDestData += row_size; 434ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 435ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(data_buf); 436ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann data_buf = dest_buf; 437ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann data_size = row_size * row_count - 438ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); 4394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 440ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 441ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 442ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid TIFF_PredictLine(uint8_t* dest_buf, 4434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t row_size, 444ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int BitsPerComponent, 445ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Colors, 446ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Columns) { 447ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (BitsPerComponent == 1) { 4484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int row_bits = std::min(BitsPerComponent * Colors * Columns, 4494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pdfium::base::checked_cast<int>(row_size * 8)); 450ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int index_pre = 0; 451ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int col_pre = 0; 452ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (int i = 1; i < row_bits; i++) { 453ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int col = i % 8; 454ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int index = i / 8; 455ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (((dest_buf[index] >> (7 - col)) & 1) ^ 456ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) { 457ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf[index] |= 1 << (7 - col); 458ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 459ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf[index] &= ~(1 << (7 - col)); 460ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 461ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann index_pre = index; 462ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann col_pre = col; 463e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 464ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 465ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 466ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int BytesPerPixel = BitsPerComponent * Colors / 8; 467ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (BitsPerComponent == 16) { 4684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (uint32_t i = BytesPerPixel; i < row_size; i += 2) { 4694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint16_t pixel = 470ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; 471ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; 472ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf[i] = pixel >> 8; 473ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf[i + 1] = (uint8_t)pixel; 474ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 475ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 4764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (uint32_t i = BytesPerPixel; i < row_size; i++) { 477ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf[i] += dest_buf[i - BytesPerPixel]; 478ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 479ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 480ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 481ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 4824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool TIFF_Predictor(uint8_t*& data_buf, 4834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t& data_size, 4844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int Colors, 4854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int BitsPerComponent, 4864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int Columns) { 487ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; 488ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (row_size == 0) 4894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 490ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const int row_count = (data_size + row_size - 1) / row_size; 491ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const int last_row_size = data_size % row_size; 492ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for (int row = 0; row < row_count; row++) { 493ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* scan_line = data_buf + row * row_size; 494ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ((row + 1) * row_size > (int)data_size) { 495ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann row_size = last_row_size; 496ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 497ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); 498ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 4994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 500ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 501ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 502ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid FlateUncompress(const uint8_t* src_buf, 5034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 5044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t orig_size, 505ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t*& dest_buf, 5064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t& dest_size, 5074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t& offset) { 5084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t guess_size = orig_size ? orig_size : src_size * 2; 5094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const uint32_t kStepSize = 10240; 5104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t alloc_step = orig_size ? kStepSize : std::min(src_size, kStepSize); 5114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann static const uint32_t kMaxInitialAllocSize = 10000000; 512ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (guess_size > kMaxInitialAllocSize) { 513ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann guess_size = kMaxInitialAllocSize; 514ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann alloc_step = kMaxInitialAllocSize; 515ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 5164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t buf_size = guess_size; 5174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t last_buf_size = buf_size; 518ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 519ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf = nullptr; 520ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_size = 0; 521ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); 522ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!context) 523ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 524ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 525ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann std::unique_ptr<uint8_t, FxFreeDeleter> guess_buf( 526ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Alloc(uint8_t, guess_size + 1)); 527ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann guess_buf.get()[guess_size] = '\0'; 528ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 529ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDFAPI_FlateInput(context, src_buf, src_size); 530ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 531ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (src_size < kStepSize) { 532ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // This is the old implementation. 533ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* cur_buf = guess_buf.get(); 534ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 535ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); 536ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (ret != Z_OK) 537ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 538ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); 539ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (avail_buf_size != 0) 540ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 541ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 5424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t old_size = guess_size; 543ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann guess_size += alloc_step; 544ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (guess_size < old_size || guess_size + 1 < guess_size) { 545ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDFAPI_FlateEnd(context); 546e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 547ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 548ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 549ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 550ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* new_buf = 551ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Realloc(uint8_t, guess_buf.release(), guess_size + 1); 552ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann guess_buf.reset(new_buf); 553ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 554ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann guess_buf.get()[guess_size] = '\0'; 555ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cur_buf = guess_buf.get() + old_size; 556ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann buf_size = guess_size - old_size; 557ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 558ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_size = FPDFAPI_FlateGetTotalOut(context); 559ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann offset = FPDFAPI_FlateGetTotalIn(context); 560ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (guess_size / 2 > dest_size) { 561ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 562ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* new_buf = 563ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Realloc(uint8_t, guess_buf.release(), dest_size + 1); 564ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann guess_buf.reset(new_buf); 565ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 566ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann guess_size = dest_size; 567ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann guess_buf.get()[guess_size] = '\0'; 568ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 569ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf = guess_buf.release(); 570ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 5714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<uint8_t*> result_tmp_bufs; 572ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* cur_buf = guess_buf.release(); 573ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (1) { 574ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); 575ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); 576ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (ret != Z_OK) { 577ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann last_buf_size = buf_size - avail_buf_size; 5784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result_tmp_bufs.push_back(cur_buf); 579ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 580ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 581ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (avail_buf_size != 0) { 582ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann last_buf_size = buf_size - avail_buf_size; 5834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result_tmp_bufs.push_back(cur_buf); 584ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 585ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 5864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result_tmp_bufs.push_back(cur_buf); 587ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cur_buf = FX_Alloc(uint8_t, buf_size + 1); 588ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cur_buf[buf_size] = '\0'; 589ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 590ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_size = FPDFAPI_FlateGetTotalOut(context); 591ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann offset = FPDFAPI_FlateGetTotalIn(context); 5924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (result_tmp_bufs.size() == 1) { 593ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf = result_tmp_bufs[0]; 594e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else { 595ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* result_buf = FX_Alloc(uint8_t, dest_size); 5964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t result_pos = 0; 5974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (size_t i = 0; i < result_tmp_bufs.size(); i++) { 598ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* tmp_buf = result_tmp_bufs[i]; 5994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t tmp_buf_size = buf_size; 6004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (i == result_tmp_bufs.size() - 1) { 601ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann tmp_buf_size = last_buf_size; 602ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 603ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size); 604ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann result_pos += tmp_buf_size; 605ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(result_tmp_bufs[i]); 606ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 607ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf = result_buf; 608ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 609ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 610ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDFAPI_FlateEnd(context); 611e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 612ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 613ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} // namespace 614ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 615ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannclass CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { 616ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann public: 617ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann CCodec_FlateScanlineDecoder(); 618ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ~CCodec_FlateScanlineDecoder() override; 619ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 620ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann void Create(const uint8_t* src_buf, 6214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 622ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int width, 623ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int height, 624ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int nComps, 625ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int bpc, 626ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int predictor, 627ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Colors, 628ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int BitsPerComponent, 629ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Columns); 630ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 631ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann // CCodec_ScanlineDecoder 6324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool v_Rewind() override; 633ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* v_GetNextLine() override; 6344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t GetSrcOffset() override; 635ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 636ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann void* m_pFlate; 637ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* m_SrcBuf; 6384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t m_SrcSize; 639ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* m_pScanline; 640ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* m_pLastLine; 641ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* m_pPredictBuffer; 642ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t* m_pPredictRaw; 643ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int m_Predictor; 644ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int m_Colors; 645ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int m_BitsPerComponent; 646ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int m_Columns; 6474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t m_PredictPitch; 648ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann size_t m_LeftOver; 649e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}; 650ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 651ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder() { 6524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pFlate = nullptr; 6534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pScanline = nullptr; 6544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pLastLine = nullptr; 6554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pPredictBuffer = nullptr; 6564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pPredictRaw = nullptr; 657ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_LeftOver = 0; 658e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 659ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCCodec_FlateScanlineDecoder::~CCodec_FlateScanlineDecoder() { 660ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(m_pScanline); 661ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(m_pLastLine); 662ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(m_pPredictBuffer); 663ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(m_pPredictRaw); 664ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_pFlate) { 665ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDFAPI_FlateEnd(m_pFlate); 666ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 667e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 668ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CCodec_FlateScanlineDecoder::Create(const uint8_t* src_buf, 6694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 670ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int width, 671ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int height, 672ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int nComps, 673ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int bpc, 674ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int predictor, 675ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Colors, 676ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int BitsPerComponent, 677ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Columns) { 678ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_SrcBuf = src_buf; 679ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_SrcSize = src_size; 680ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_OutputWidth = m_OrigWidth = width; 681ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_OutputHeight = m_OrigHeight = height; 682ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_nComps = nComps; 683ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_bpc = bpc; 6844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_Pitch = (static_cast<uint32_t>(width) * nComps * bpc + 7) / 8; 685ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pScanline = FX_Alloc(uint8_t, m_Pitch); 686ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_Predictor = 0; 687ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (predictor) { 688ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (predictor >= 10) { 689ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_Predictor = 2; 690ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (predictor == 2) { 691ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_Predictor = 1; 692e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 693e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (m_Predictor) { 694ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (BitsPerComponent * Colors * Columns == 0) { 695ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann BitsPerComponent = m_bpc; 696ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Colors = m_nComps; 697ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Columns = m_OrigWidth; 698ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 699ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_Colors = Colors; 700ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_BitsPerComponent = BitsPerComponent; 701ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_Columns = Columns; 702ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_PredictPitch = 7034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (static_cast<uint32_t>(m_BitsPerComponent) * m_Colors * m_Columns + 704ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 7) / 705ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 8; 706ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pLastLine = FX_Alloc(uint8_t, m_PredictPitch); 707ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPredictRaw = FX_Alloc(uint8_t, m_PredictPitch + 1); 708ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPredictBuffer = FX_Alloc(uint8_t, m_PredictPitch); 709ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 710ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 711ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 7124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_FlateScanlineDecoder::v_Rewind() { 713ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_pFlate) { 714ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDFAPI_FlateEnd(m_pFlate); 715ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 716ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pFlate = FPDFAPI_FlateInit(my_alloc_func, my_free_func); 717ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (!m_pFlate) { 7184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 719ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 720ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDFAPI_FlateInput(m_pFlate, m_SrcBuf, m_SrcSize); 721ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_LeftOver = 0; 7224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 723ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 724ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannuint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() { 725ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_Predictor) { 726ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_Pitch == m_PredictPitch) { 727ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_Predictor == 2) { 728ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); 729ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine, 730ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_BitsPerComponent, m_Colors, m_Columns); 731ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memcpy(m_pLastLine, m_pScanline, m_PredictPitch); 732ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 733e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); 734ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann TIFF_PredictLine(m_pScanline, m_PredictPitch, m_bpc, m_nComps, 735ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_OutputWidth); 736ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 737e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else { 738ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann size_t bytes_to_go = m_Pitch; 739ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann size_t read_leftover = 740ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver; 741ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (read_leftover) { 742ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memcpy(m_pScanline, 743ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPredictBuffer + m_PredictPitch - m_LeftOver, 744ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann read_leftover); 745ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_LeftOver -= read_leftover; 746ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bytes_to_go -= read_leftover; 747ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 748ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (bytes_to_go) { 749ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_Predictor == 2) { 750ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); 751ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann PNG_PredictLine(m_pPredictBuffer, m_pPredictRaw, m_pLastLine, 752ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_BitsPerComponent, m_Colors, m_Columns); 753ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memcpy(m_pLastLine, m_pPredictBuffer, m_PredictPitch); 754e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else { 755ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDFAPI_FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch); 756ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPerComponent, 757ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_Colors, m_Columns); 758ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 759ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann size_t read_bytes = 760ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch; 761ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memcpy(m_pScanline + m_Pitch - bytes_to_go, m_pPredictBuffer, 762ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann read_bytes); 763ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_LeftOver += m_PredictPitch - read_bytes; 764ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bytes_to_go -= read_bytes; 765ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 766ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 767ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 768ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); 769ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 770ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return m_pScanline; 771ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 7724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannuint32_t CCodec_FlateScanlineDecoder::GetSrcOffset() { 773ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return FPDFAPI_FlateGetTotalIn(m_pFlate); 774ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 775e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 7764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstd::unique_ptr<CCodec_ScanlineDecoder> CCodec_FlateModule::CreateDecoder( 777ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* src_buf, 7784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 779ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int width, 780ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int height, 781ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int nComps, 782ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int bpc, 783ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int predictor, 784ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Colors, 785ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int BitsPerComponent, 786ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Columns) { 7874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann auto pDecoder = pdfium::MakeUnique<CCodec_FlateScanlineDecoder>(); 788ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, 789ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Colors, BitsPerComponent, Columns); 7904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return std::move(pDecoder); 791e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 7924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannuint32_t CCodec_FlateModule::FlateOrLZWDecode(bool bLZW, 794ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const uint8_t* src_buf, 7954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 7964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool bEarlyChange, 797ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int predictor, 798ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Colors, 799ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int BitsPerComponent, 800ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int Columns, 8014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t estimated_size, 802ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann uint8_t*& dest_buf, 8034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t& dest_size) { 8044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_buf = nullptr; 8054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t offset = 0; 806ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int predictor_type = 0; 807ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (predictor) { 808ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (predictor >= 10) { 809ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann predictor_type = 2; 810ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (predictor == 2) { 811ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann predictor_type = 1; 812ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 813ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 814ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (bLZW) { 815ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 816ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann std::unique_ptr<CLZWDecoder> decoder(new CLZWDecoder); 8174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dest_size = (uint32_t)-1; 818ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann offset = src_size; 8194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int err = 8204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann decoder->Decode(nullptr, dest_size, src_buf, offset, bEarlyChange); 821ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (err || dest_size == 0 || dest_size + 1 < dest_size) { 8224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return FX_INVALID_OFFSET; 823ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 824e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 825ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 826ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann std::unique_ptr<CLZWDecoder> decoder(new CLZWDecoder); 827ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf = FX_Alloc(uint8_t, dest_size + 1); 828ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann dest_buf[dest_size] = '\0'; 829ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann decoder->Decode(dest_buf, dest_size, src_buf, offset, bEarlyChange); 830ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 831ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 832ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FlateUncompress(src_buf, src_size, estimated_size, dest_buf, dest_size, 833ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann offset); 834ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 835ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (predictor_type == 0) { 836ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return offset; 837ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 8384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool ret = true; 839ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (predictor_type == 2) { 840ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ret = PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); 841ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else if (predictor_type == 1) { 842ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ret = 843ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); 844ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 8454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return ret ? offset : FX_INVALID_OFFSET; 846ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 8474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_FlateModule::Encode(const uint8_t* src_buf, 8494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 8504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t** dest_buf, 8514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t* dest_size) { 8524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_size = src_size + src_size / 1000 + 12; 8534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_buf = FX_Alloc(uint8_t, *dest_size); 8544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned long temp_size = *dest_size; 8554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!FPDFAPI_FlateCompress(*dest_buf, &temp_size, src_buf, src_size)) 8564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 8574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *dest_size = (uint32_t)temp_size; 8594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 8604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 8614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CCodec_FlateModule::PngEncode(const uint8_t* src_buf, 8634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t src_size, 8644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t** dest_buf, 8654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t* dest_size) { 8664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* pSrcBuf = FX_Alloc(uint8_t, src_size); 867ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memcpy(pSrcBuf, src_buf, src_size); 8684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_PredictorEncode(&pSrcBuf, &src_size); 8694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); 870ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_Free(pSrcBuf); 871ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return ret; 872ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 873