| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "../../fx_zlib.h" | 7 #include "../../fx_zlib.h" |
| 8 #include "../../../include/fxcodec/fx_codec.h" | 8 #include "../../../include/fxcodec/fx_codec.h" |
| 9 #include "codec_int.h" | 9 #include "codec_int.h" |
| 10 extern "C" | 10 extern "C" { |
| 11 { | 11 static void* my_alloc_func(void* opaque, |
| 12 static void* my_alloc_func (void* opaque, unsigned int items, unsigned int s
ize) | 12 unsigned int items, |
| 13 { | 13 unsigned int size) { |
| 14 return FX_Alloc(FX_BYTE, items * size); | 14 return FX_Alloc(FX_BYTE, items * size); |
| 15 } | 15 } |
| 16 static void my_free_func (void* opaque, void* address) | 16 static void my_free_func(void* opaque, void* address) { |
| 17 { | 17 FX_Free(address); |
| 18 FX_Free(address); | 18 } |
| 19 } | 19 void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int), |
| 20 void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned in
t), | 20 void (*free_func)(void*, void*)) { |
| 21 void (*free_func)(void*, void*)) | 21 z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream)); |
| 22 { | 22 if (p == NULL) { |
| 23 z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream)); | 23 return NULL; |
| 24 if (p == NULL) { | 24 } |
| 25 return NULL; | 25 FXSYS_memset32(p, 0, sizeof(z_stream)); |
| 26 } | 26 p->zalloc = alloc_func; |
| 27 FXSYS_memset32(p, 0, sizeof(z_stream)); | 27 p->zfree = free_func; |
| 28 p->zalloc = alloc_func; | 28 inflateInit(p); |
| 29 p->zfree = free_func; | 29 return p; |
| 30 inflateInit(p); | 30 } |
| 31 return p; | 31 void FPDFAPI_FlateInput(void* context, |
| 32 } | 32 const unsigned char* src_buf, |
| 33 void FPDFAPI_FlateInput(void* context, const unsigned char* src_buf, unsigne
d int src_size) | 33 unsigned int src_size) { |
| 34 { | 34 ((z_stream*)context)->next_in = (unsigned char*)src_buf; |
| 35 ((z_stream*)context)->next_in = (unsigned char*)src_buf; | 35 ((z_stream*)context)->avail_in = src_size; |
| 36 ((z_stream*)context)->avail_in = src_size; | 36 } |
| 37 } | 37 int FPDFAPI_FlateGetTotalOut(void* context) { |
| 38 int FPDFAPI_FlateGetTotalOut(void* context) | 38 return ((z_stream*)context)->total_out; |
| 39 { | 39 } |
| 40 return ((z_stream*)context)->total_out; | 40 int FPDFAPI_FlateOutput(void* context, |
| 41 } | 41 unsigned char* dest_buf, |
| 42 int FPDFAPI_FlateOutput(void* context, unsigned char* dest_buf, unsigned int
dest_size) | 42 unsigned int dest_size) { |
| 43 { | 43 ((z_stream*)context)->next_out = dest_buf; |
| 44 ((z_stream*)context)->next_out = dest_buf; | 44 ((z_stream*)context)->avail_out = dest_size; |
| 45 ((z_stream*)context)->avail_out = dest_size; | 45 unsigned int pre_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); |
| 46 unsigned int pre_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); | 46 int ret = inflate((z_stream*)context, Z_SYNC_FLUSH); |
| 47 int ret = inflate((z_stream*)context, Z_SYNC_FLUSH); | 47 unsigned int post_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); |
| 48 unsigned int post_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); | 48 unsigned int written = post_pos - pre_pos; |
| 49 unsigned int written = post_pos - pre_pos; | 49 if (written < dest_size) { |
| 50 if (written < dest_size) { | 50 FXSYS_memset8(dest_buf + written, '\0', dest_size - written); |
| 51 FXSYS_memset8(dest_buf + written, '\0', dest_size - written); | 51 } |
| 52 } | 52 return ret; |
| 53 return ret; | 53 } |
| 54 } | 54 int FPDFAPI_FlateGetTotalIn(void* context) { |
| 55 int FPDFAPI_FlateGetTotalIn(void* context) | 55 return ((z_stream*)context)->total_in; |
| 56 { | 56 } |
| 57 return ((z_stream*)context)->total_in; | 57 int FPDFAPI_FlateGetAvailOut(void* context) { |
| 58 } | 58 return ((z_stream*)context)->avail_out; |
| 59 int FPDFAPI_FlateGetAvailOut(void* context) | 59 } |
| 60 { | 60 int FPDFAPI_FlateGetAvailIn(void* context) { |
| 61 return ((z_stream*)context)->avail_out; | 61 return ((z_stream*)context)->avail_in; |
| 62 } | 62 } |
| 63 int FPDFAPI_FlateGetAvailIn(void* context) | 63 void FPDFAPI_FlateEnd(void* context) { |
| 64 { | 64 inflateEnd((z_stream*)context); |
| 65 return ((z_stream*)context)->avail_in; | 65 ((z_stream*)context)->zfree(0, context); |
| 66 } | 66 } |
| 67 void FPDFAPI_FlateEnd(void* context) | 67 void FPDFAPI_FlateCompress(unsigned char* dest_buf, |
| 68 { | 68 unsigned long* dest_size, |
| 69 inflateEnd((z_stream*)context); | 69 const unsigned char* src_buf, |
| 70 ((z_stream*)context)->zfree(0, context); | 70 unsigned long src_size) { |
| 71 } | 71 compress(dest_buf, dest_size, src_buf, src_size); |
| 72 void FPDFAPI_FlateCompress(unsigned char* dest_buf, unsigned long* dest_size
, const unsigned char* src_buf, unsigned long src_size) | 72 } |
| 73 { | 73 } |
| 74 compress(dest_buf, dest_size, src_buf, src_size); | 74 class CLZWDecoder : public CFX_Object { |
| 75 } | 75 public: |
| 76 } | 76 FX_BOOL Decode(FX_LPBYTE output, |
| 77 class CLZWDecoder : public CFX_Object | 77 FX_DWORD& outlen, |
| 78 { | 78 const FX_BYTE* input, |
| 79 public: | 79 FX_DWORD& size, |
| 80 FX_BOOL Decode(FX_LPBYTE output, FX_DWORD& outlen, const FX_BYTE* input, FX_
DWORD& size, FX_BOOL bEarlyChange); | 80 FX_BOOL bEarlyChange); |
| 81 private: | 81 |
| 82 FX_DWORD» m_InPos; | 82 private: |
| 83 FX_DWORD» m_OutPos; | 83 FX_DWORD m_InPos; |
| 84 FX_LPBYTE» m_pOutput; | 84 FX_DWORD m_OutPos; |
| 85 const FX_BYTE*» m_pInput; | 85 FX_LPBYTE m_pOutput; |
| 86 FX_BOOL» » m_Early; | 86 const FX_BYTE* m_pInput; |
| 87 void» » AddCode(FX_DWORD prefix_code, FX_BYTE append_char); | 87 FX_BOOL m_Early; |
| 88 FX_DWORD» m_CodeArray[5021]; | 88 void AddCode(FX_DWORD prefix_code, FX_BYTE append_char); |
| 89 FX_DWORD» m_nCodes; | 89 FX_DWORD m_CodeArray[5021]; |
| 90 FX_BYTE» » m_DecodeStack[4000]; | 90 FX_DWORD m_nCodes; |
| 91 FX_DWORD» m_StackLen; | 91 FX_BYTE m_DecodeStack[4000]; |
| 92 void» » DecodeString(FX_DWORD code); | 92 FX_DWORD m_StackLen; |
| 93 int»» » m_CodeLen; | 93 void DecodeString(FX_DWORD code); |
| 94 int m_CodeLen; |
| 94 }; | 95 }; |
| 95 void CLZWDecoder::AddCode(FX_DWORD prefix_code, FX_BYTE append_char) | 96 void CLZWDecoder::AddCode(FX_DWORD prefix_code, FX_BYTE append_char) { |
| 96 { | 97 if (m_nCodes + m_Early == 4094) { |
| 97 if (m_nCodes + m_Early == 4094) { | 98 return; |
| 98 return; | 99 } |
| 99 } | 100 m_CodeArray[m_nCodes++] = (prefix_code << 16) | append_char; |
| 100 m_CodeArray[m_nCodes ++] = (prefix_code << 16) | append_char; | 101 if (m_nCodes + m_Early == 512 - 258) { |
| 101 if (m_nCodes + m_Early == 512 - 258) { | 102 m_CodeLen = 10; |
| 102 m_CodeLen = 10; | 103 } else if (m_nCodes + m_Early == 1024 - 258) { |
| 103 } else if (m_nCodes + m_Early == 1024 - 258) { | 104 m_CodeLen = 11; |
| 104 m_CodeLen = 11; | 105 } else if (m_nCodes + m_Early == 2048 - 258) { |
| 105 } else if (m_nCodes + m_Early == 2048 - 258) { | 106 m_CodeLen = 12; |
| 106 m_CodeLen = 12; | 107 } |
| 107 } | 108 } |
| 108 } | 109 void CLZWDecoder::DecodeString(FX_DWORD code) { |
| 109 void CLZWDecoder::DecodeString(FX_DWORD code) | 110 while (1) { |
| 110 { | 111 int index = code - 258; |
| 111 while (1) { | 112 if (index < 0 || index >= (int)m_nCodes) { |
| 112 int index = code - 258; | 113 break; |
| 113 if (index < 0 || index >= (int)m_nCodes) { | 114 } |
| 114 break; | 115 FX_DWORD data = m_CodeArray[index]; |
| 115 } | |
| 116 FX_DWORD data = m_CodeArray[index]; | |
| 117 if (m_StackLen >= sizeof(m_DecodeStack)) { | |
| 118 return; | |
| 119 } | |
| 120 m_DecodeStack[m_StackLen++] = (FX_BYTE)data; | |
| 121 code = data >> 16; | |
| 122 } | |
| 123 if (m_StackLen >= sizeof(m_DecodeStack)) { | 116 if (m_StackLen >= sizeof(m_DecodeStack)) { |
| 124 return; | 117 return; |
| 125 } | 118 } |
| 126 m_DecodeStack[m_StackLen++] = (FX_BYTE)code; | 119 m_DecodeStack[m_StackLen++] = (FX_BYTE)data; |
| 127 } | 120 code = data >> 16; |
| 128 int CLZWDecoder::Decode(FX_LPBYTE dest_buf, FX_DWORD& dest_size, const FX_BYTE*
src_buf, FX_DWORD& src_size, FX_BOOL bEarlyChange) | 121 } |
| 129 { | 122 if (m_StackLen >= sizeof(m_DecodeStack)) { |
| 130 m_CodeLen = 9; | 123 return; |
| 131 m_InPos = 0; | 124 } |
| 132 m_OutPos = 0; | 125 m_DecodeStack[m_StackLen++] = (FX_BYTE)code; |
| 133 m_pInput = src_buf; | 126 } |
| 134 m_pOutput = dest_buf; | 127 int CLZWDecoder::Decode(FX_LPBYTE dest_buf, |
| 135 m_Early = bEarlyChange ? 1 : 0; | 128 FX_DWORD& dest_size, |
| 136 m_nCodes = 0; | 129 const FX_BYTE* src_buf, |
| 137 FX_DWORD old_code = (FX_DWORD) - 1; | 130 FX_DWORD& src_size, |
| 138 FX_BYTE last_char; | 131 FX_BOOL bEarlyChange) { |
| 139 while (1) { | 132 m_CodeLen = 9; |
| 140 if (m_InPos + m_CodeLen > src_size * 8) { | 133 m_InPos = 0; |
| 141 break; | 134 m_OutPos = 0; |
| 142 } | 135 m_pInput = src_buf; |
| 143 int byte_pos = m_InPos / 8; | 136 m_pOutput = dest_buf; |
| 144 int bit_pos = m_InPos % 8, bit_left = m_CodeLen; | 137 m_Early = bEarlyChange ? 1 : 0; |
| 145 FX_DWORD code = 0; | 138 m_nCodes = 0; |
| 146 if (bit_pos) { | 139 FX_DWORD old_code = (FX_DWORD)-1; |
| 147 bit_left -= 8 - bit_pos; | 140 FX_BYTE last_char; |
| 148 code = (m_pInput[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_le
ft; | 141 while (1) { |
| 149 } | 142 if (m_InPos + m_CodeLen > src_size * 8) { |
| 150 if (bit_left < 8) { | 143 break; |
| 151 code |= m_pInput[byte_pos] >> (8 - bit_left); | 144 } |
| 152 } else { | 145 int byte_pos = m_InPos / 8; |
| 153 bit_left -= 8; | 146 int bit_pos = m_InPos % 8, bit_left = m_CodeLen; |
| 154 code |= m_pInput[byte_pos++] << bit_left; | 147 FX_DWORD code = 0; |
| 155 if (bit_left) { | 148 if (bit_pos) { |
| 156 code |= m_pInput[byte_pos] >> (8 - bit_left); | 149 bit_left -= 8 - bit_pos; |
| 157 } | 150 code = (m_pInput[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left; |
| 158 } | 151 } |
| 159 m_InPos += m_CodeLen; | 152 if (bit_left < 8) { |
| 160 if (code < 256) { | 153 code |= m_pInput[byte_pos] >> (8 - bit_left); |
| 161 if (m_OutPos == dest_size) { | 154 } else { |
| 162 return -5; | 155 bit_left -= 8; |
| 163 } | 156 code |= m_pInput[byte_pos++] << bit_left; |
| 164 if (m_pOutput) { | 157 if (bit_left) { |
| 165 m_pOutput[m_OutPos] = (FX_BYTE)code; | 158 code |= m_pInput[byte_pos] >> (8 - bit_left); |
| 166 } | 159 } |
| 167 m_OutPos ++; | 160 } |
| 168 last_char = (FX_BYTE)code; | 161 m_InPos += m_CodeLen; |
| 169 if (old_code != (FX_DWORD) - 1) { | 162 if (code < 256) { |
| 170 AddCode(old_code, last_char); | 163 if (m_OutPos == dest_size) { |
| 171 } | 164 return -5; |
| 172 old_code = code; | 165 } |
| 173 } else if (code == 256) { | 166 if (m_pOutput) { |
| 174 m_CodeLen = 9; | 167 m_pOutput[m_OutPos] = (FX_BYTE)code; |
| 175 m_nCodes = 0; | 168 } |
| 176 old_code = (FX_DWORD) - 1; | 169 m_OutPos++; |
| 177 } else if (code == 257) { | 170 last_char = (FX_BYTE)code; |
| 178 break; | 171 if (old_code != (FX_DWORD)-1) { |
| 179 } else { | 172 AddCode(old_code, last_char); |
| 180 if (old_code == (FX_DWORD) - 1) { | 173 } |
| 181 return 2; | 174 old_code = code; |
| 182 } | 175 } else if (code == 256) { |
| 183 m_StackLen = 0; | 176 m_CodeLen = 9; |
| 184 if (code >= m_nCodes + 258) { | 177 m_nCodes = 0; |
| 185 if (m_StackLen < sizeof(m_DecodeStack)) { | 178 old_code = (FX_DWORD)-1; |
| 186 m_DecodeStack[m_StackLen++] = last_char; | 179 } else if (code == 257) { |
| 187 } | 180 break; |
| 188 DecodeString(old_code); | 181 } else { |
| 189 } else { | 182 if (old_code == (FX_DWORD)-1) { |
| 190 DecodeString(code); | 183 return 2; |
| 191 } | 184 } |
| 192 if (m_OutPos + m_StackLen > dest_size) { | 185 m_StackLen = 0; |
| 193 return -5; | 186 if (code >= m_nCodes + 258) { |
| 194 } | 187 if (m_StackLen < sizeof(m_DecodeStack)) { |
| 195 if (m_pOutput) { | 188 m_DecodeStack[m_StackLen++] = last_char; |
| 196 for (FX_DWORD i = 0; i < m_StackLen; i ++) { | 189 } |
| 197 m_pOutput[m_OutPos + i] = m_DecodeStack[m_StackLen - i - 1]; | 190 DecodeString(old_code); |
| 198 } | 191 } else { |
| 199 } | 192 DecodeString(code); |
| 200 m_OutPos += m_StackLen; | 193 } |
| 201 last_char = m_DecodeStack[m_StackLen - 1]; | 194 if (m_OutPos + m_StackLen > dest_size) { |
| 202 if (old_code < 256) { | 195 return -5; |
| 203 AddCode(old_code, last_char); | 196 } |
| 204 } else if (old_code - 258 >= m_nCodes) { | 197 if (m_pOutput) { |
| 205 dest_size = m_OutPos; | 198 for (FX_DWORD i = 0; i < m_StackLen; i++) { |
| 206 src_size = (m_InPos + 7) / 8; | 199 m_pOutput[m_OutPos + i] = m_DecodeStack[m_StackLen - i - 1]; |
| 207 return 0; | 200 } |
| 208 } else { | 201 } |
| 209 AddCode(old_code, last_char); | 202 m_OutPos += m_StackLen; |
| 210 } | 203 last_char = m_DecodeStack[m_StackLen - 1]; |
| 211 old_code = code; | 204 if (old_code < 256) { |
| 212 } | 205 AddCode(old_code, last_char); |
| 213 } | 206 } else if (old_code - 258 >= m_nCodes) { |
| 214 dest_size = m_OutPos; | 207 dest_size = m_OutPos; |
| 215 src_size = (m_InPos + 7) / 8; | 208 src_size = (m_InPos + 7) / 8; |
| 216 return 0; | 209 return 0; |
| 217 } | 210 } else { |
| 218 static FX_BYTE PaethPredictor(int a, int b, int c) | 211 AddCode(old_code, last_char); |
| 219 { | 212 } |
| 220 int p = a + b - c; | 213 old_code = code; |
| 221 int pa = FXSYS_abs(p - a); | 214 } |
| 222 int pb = FXSYS_abs(p - b); | 215 } |
| 223 int pc = FXSYS_abs(p - c); | 216 dest_size = m_OutPos; |
| 224 if (pa <= pb && pa <= pc) { | 217 src_size = (m_InPos + 7) / 8; |
| 225 return (FX_BYTE)a; | 218 return 0; |
| 226 } | 219 } |
| 227 if (pb <= pc) { | 220 static FX_BYTE PaethPredictor(int a, int b, int c) { |
| 228 return (FX_BYTE)b; | 221 int p = a + b - c; |
| 229 } | 222 int pa = FXSYS_abs(p - a); |
| 230 return (FX_BYTE)c; | 223 int pb = FXSYS_abs(p - b); |
| 231 } | 224 int pc = FXSYS_abs(p - c); |
| 232 static void PNG_PredictorEncode(FX_LPBYTE& data_buf, FX_DWORD& data_size, int pr
edictor, int Colors, int BitsPerComponent, int Columns) | 225 if (pa <= pb && pa <= pc) { |
| 233 { | 226 return (FX_BYTE)a; |
| 234 int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; | 227 } |
| 235 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 228 if (pb <= pc) { |
| 236 int row_count = (data_size + row_size - 1) / row_size; | 229 return (FX_BYTE)b; |
| 237 int last_row_size = data_size % row_size; | 230 } |
| 238 FX_LPBYTE dest_buf = FX_Alloc( FX_BYTE, (row_size + 1) * row_count); | 231 return (FX_BYTE)c; |
| 239 if (dest_buf == NULL) { | 232 } |
| 240 return; | 233 static void PNG_PredictorEncode(FX_LPBYTE& data_buf, |
| 241 } | 234 FX_DWORD& data_size, |
| 242 int byte_cnt = 0; | 235 int predictor, |
| 243 FX_LPBYTE pSrcData = data_buf; | 236 int Colors, |
| 244 FX_LPBYTE pDestData = dest_buf; | 237 int BitsPerComponent, |
| 245 for (int row = 0; row < row_count; row++) { | 238 int Columns) { |
| 246 if (predictor == 10) { | 239 int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; |
| 247 pDestData[0] = 0; | 240 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 248 int move_size = row_size; | 241 int row_count = (data_size + row_size - 1) / row_size; |
| 249 if (move_size * (row + 1) > (int)data_size) { | 242 int last_row_size = data_size % row_size; |
| 250 move_size = data_size - (move_size * row); | 243 FX_LPBYTE dest_buf = FX_Alloc(FX_BYTE, (row_size + 1) * row_count); |
| 251 } | 244 if (dest_buf == NULL) { |
| 252 FXSYS_memmove32(pDestData + 1, pSrcData, move_size); | 245 return; |
| 253 pDestData += (move_size + 1); | 246 } |
| 254 pSrcData += move_size; | 247 int byte_cnt = 0; |
| 255 byte_cnt += move_size; | 248 FX_LPBYTE pSrcData = data_buf; |
| 256 continue; | 249 FX_LPBYTE pDestData = dest_buf; |
| 257 } | 250 for (int row = 0; row < row_count; row++) { |
| 258 for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++)
{ | 251 if (predictor == 10) { |
| 259 switch (predictor) { | 252 pDestData[0] = 0; |
| 260 case 11: { | 253 int move_size = row_size; |
| 261 pDestData[0] = 1; | 254 if (move_size * (row + 1) > (int)data_size) { |
| 262 FX_BYTE left = 0; | 255 move_size = data_size - (move_size * row); |
| 263 if (byte >= BytesPerPixel) { | 256 } |
| 264 left = pSrcData[byte - BytesPerPixel]; | 257 FXSYS_memmove32(pDestData + 1, pSrcData, move_size); |
| 265 } | 258 pDestData += (move_size + 1); |
| 266 pDestData[byte + 1] = pSrcData[byte] - left; | 259 pSrcData += move_size; |
| 267 } | 260 byte_cnt += move_size; |
| 268 break; | 261 continue; |
| 269 case 12: { | 262 } |
| 270 pDestData[0] = 2; | 263 for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) { |
| 271 FX_BYTE up = 0; | 264 switch (predictor) { |
| 272 if (row) { | 265 case 11: { |
| 273 up = pSrcData[byte - row_size]; | 266 pDestData[0] = 1; |
| 274 } | 267 FX_BYTE left = 0; |
| 275 pDestData[byte + 1] = pSrcData[byte] - up; | 268 if (byte >= BytesPerPixel) { |
| 276 } | 269 left = pSrcData[byte - BytesPerPixel]; |
| 277 break; | 270 } |
| 278 case 13: { | 271 pDestData[byte + 1] = pSrcData[byte] - left; |
| 279 pDestData[0] = 3; | 272 } break; |
| 280 FX_BYTE left = 0; | 273 case 12: { |
| 281 if (byte >= BytesPerPixel) { | 274 pDestData[0] = 2; |
| 282 left = pSrcData[byte - BytesPerPixel]; | 275 FX_BYTE up = 0; |
| 283 } | 276 if (row) { |
| 284 FX_BYTE up = 0; | 277 up = pSrcData[byte - row_size]; |
| 285 if (row) { | 278 } |
| 286 up = pSrcData[byte - row_size]; | 279 pDestData[byte + 1] = pSrcData[byte] - up; |
| 287 } | 280 } break; |
| 288 pDestData[byte + 1] = pSrcData[byte] - (left + up) / 2; | 281 case 13: { |
| 289 } | 282 pDestData[0] = 3; |
| 290 break; | 283 FX_BYTE left = 0; |
| 291 case 14: { | 284 if (byte >= BytesPerPixel) { |
| 292 pDestData[0] = 4; | 285 left = pSrcData[byte - BytesPerPixel]; |
| 293 FX_BYTE left = 0; | 286 } |
| 294 if (byte >= BytesPerPixel) { | 287 FX_BYTE up = 0; |
| 295 left = pSrcData[byte - BytesPerPixel]; | 288 if (row) { |
| 296 } | 289 up = pSrcData[byte - row_size]; |
| 297 FX_BYTE up = 0; | 290 } |
| 298 if (row) { | 291 pDestData[byte + 1] = pSrcData[byte] - (left + up) / 2; |
| 299 up = pSrcData[byte - row_size]; | 292 } break; |
| 300 } | 293 case 14: { |
| 301 FX_BYTE upper_left = 0; | 294 pDestData[0] = 4; |
| 302 if (byte >= BytesPerPixel && row) { | 295 FX_BYTE left = 0; |
| 303 upper_left = pSrcData[byte - row_size - BytesPerPixe
l]; | 296 if (byte >= BytesPerPixel) { |
| 304 } | 297 left = pSrcData[byte - BytesPerPixel]; |
| 305 pDestData[byte + 1] = pSrcData[byte] - PaethPredictor(le
ft, up, upper_left); | 298 } |
| 306 } | 299 FX_BYTE up = 0; |
| 307 break; | 300 if (row) { |
| 308 default: { | 301 up = pSrcData[byte - row_size]; |
| 309 pDestData[byte + 1] = pSrcData[byte]; | 302 } |
| 310 } | 303 FX_BYTE upper_left = 0; |
| 311 break; | 304 if (byte >= BytesPerPixel && row) { |
| 312 } | 305 upper_left = pSrcData[byte - row_size - BytesPerPixel]; |
| 313 byte_cnt++; | 306 } |
| 314 } | 307 pDestData[byte + 1] = |
| 315 pDestData += (row_size + 1); | 308 pSrcData[byte] - PaethPredictor(left, up, upper_left); |
| 316 pSrcData += row_size; | 309 } break; |
| 317 } | 310 default: { pDestData[byte + 1] = pSrcData[byte]; } break; |
| 318 FX_Free(data_buf); | 311 } |
| 319 data_buf = dest_buf; | 312 byte_cnt++; |
| 320 data_size = (row_size + 1) * row_count - (last_row_size > 0 ? (row_size - la
st_row_size) : 0); | 313 } |
| 321 } | 314 pDestData += (row_size + 1); |
| 322 static void PNG_PredictLine(FX_LPBYTE pDestData, FX_LPCBYTE pSrcData, FX_LPCBYTE
pLastLine, | 315 pSrcData += row_size; |
| 323 int bpc, int nColors, int nPixels) | 316 } |
| 324 { | 317 FX_Free(data_buf); |
| 325 int row_size = (nPixels * bpc * nColors + 7) / 8; | 318 data_buf = dest_buf; |
| 326 int BytesPerPixel = (bpc * nColors + 7) / 8; | 319 data_size = (row_size + 1) * row_count - |
| 320 (last_row_size > 0 ? (row_size - last_row_size) : 0); |
| 321 } |
| 322 static void PNG_PredictLine(FX_LPBYTE pDestData, |
| 323 FX_LPCBYTE pSrcData, |
| 324 FX_LPCBYTE pLastLine, |
| 325 int bpc, |
| 326 int nColors, |
| 327 int nPixels) { |
| 328 int row_size = (nPixels * bpc * nColors + 7) / 8; |
| 329 int BytesPerPixel = (bpc * nColors + 7) / 8; |
| 330 FX_BYTE tag = pSrcData[0]; |
| 331 if (tag == 0) { |
| 332 FXSYS_memmove32(pDestData, pSrcData + 1, row_size); |
| 333 return; |
| 334 } |
| 335 for (int byte = 0; byte < row_size; byte++) { |
| 336 FX_BYTE raw_byte = pSrcData[byte + 1]; |
| 337 switch (tag) { |
| 338 case 1: { |
| 339 FX_BYTE left = 0; |
| 340 if (byte >= BytesPerPixel) { |
| 341 left = pDestData[byte - BytesPerPixel]; |
| 342 } |
| 343 pDestData[byte] = raw_byte + left; |
| 344 break; |
| 345 } |
| 346 case 2: { |
| 347 FX_BYTE up = 0; |
| 348 if (pLastLine) { |
| 349 up = pLastLine[byte]; |
| 350 } |
| 351 pDestData[byte] = raw_byte + up; |
| 352 break; |
| 353 } |
| 354 case 3: { |
| 355 FX_BYTE left = 0; |
| 356 if (byte >= BytesPerPixel) { |
| 357 left = pDestData[byte - BytesPerPixel]; |
| 358 } |
| 359 FX_BYTE up = 0; |
| 360 if (pLastLine) { |
| 361 up = pLastLine[byte]; |
| 362 } |
| 363 pDestData[byte] = raw_byte + (up + left) / 2; |
| 364 break; |
| 365 } |
| 366 case 4: { |
| 367 FX_BYTE left = 0; |
| 368 if (byte >= BytesPerPixel) { |
| 369 left = pDestData[byte - BytesPerPixel]; |
| 370 } |
| 371 FX_BYTE up = 0; |
| 372 if (pLastLine) { |
| 373 up = pLastLine[byte]; |
| 374 } |
| 375 FX_BYTE upper_left = 0; |
| 376 if (byte >= BytesPerPixel && pLastLine) { |
| 377 upper_left = pLastLine[byte - BytesPerPixel]; |
| 378 } |
| 379 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); |
| 380 break; |
| 381 } |
| 382 default: |
| 383 pDestData[byte] = raw_byte; |
| 384 break; |
| 385 } |
| 386 } |
| 387 } |
| 388 static void PNG_Predictor(FX_LPBYTE& data_buf, |
| 389 FX_DWORD& data_size, |
| 390 int Colors, |
| 391 int BitsPerComponent, |
| 392 int Columns) { |
| 393 int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; |
| 394 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 395 int row_count = (data_size + row_size) / (row_size + 1); |
| 396 int last_row_size = data_size % (row_size + 1); |
| 397 FX_LPBYTE dest_buf = FX_Alloc(FX_BYTE, row_size * row_count); |
| 398 if (dest_buf == NULL) { |
| 399 return; |
| 400 } |
| 401 int byte_cnt = 0; |
| 402 FX_LPBYTE pSrcData = data_buf; |
| 403 FX_LPBYTE pDestData = dest_buf; |
| 404 for (int row = 0; row < row_count; row++) { |
| 327 FX_BYTE tag = pSrcData[0]; | 405 FX_BYTE tag = pSrcData[0]; |
| 328 if (tag == 0) { | 406 if (tag == 0) { |
| 329 FXSYS_memmove32(pDestData, pSrcData + 1, row_size); | 407 int move_size = row_size; |
| 330 return; | 408 if ((row + 1) * (move_size + 1) > (int)data_size) { |
| 331 } | 409 move_size = last_row_size - 1; |
| 332 for (int byte = 0; byte < row_size; byte ++) { | 410 } |
| 333 FX_BYTE raw_byte = pSrcData[byte + 1]; | 411 FXSYS_memmove32(pDestData, pSrcData + 1, move_size); |
| 334 switch (tag) { | 412 pSrcData += move_size + 1; |
| 335 case 1: { | 413 pDestData += move_size; |
| 336 FX_BYTE left = 0; | 414 byte_cnt += move_size + 1; |
| 337 if (byte >= BytesPerPixel) { | 415 continue; |
| 338 left = pDestData[byte - BytesPerPixel]; | 416 } |
| 339 } | 417 for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) { |
| 340 pDestData[byte] = raw_byte + left; | 418 FX_BYTE raw_byte = pSrcData[byte + 1]; |
| 341 break; | 419 switch (tag) { |
| 342 } | 420 case 1: { |
| 343 case 2: { | 421 FX_BYTE left = 0; |
| 344 FX_BYTE up = 0; | 422 if (byte >= BytesPerPixel) { |
| 345 if (pLastLine) { | 423 left = pDestData[byte - BytesPerPixel]; |
| 346 up = pLastLine[byte]; | 424 } |
| 347 } | 425 pDestData[byte] = raw_byte + left; |
| 348 pDestData[byte] = raw_byte + up; | 426 break; |
| 349 break; | 427 } |
| 350 } | 428 case 2: { |
| 351 case 3: { | 429 FX_BYTE up = 0; |
| 352 FX_BYTE left = 0; | 430 if (row) { |
| 353 if (byte >= BytesPerPixel) { | 431 up = pDestData[byte - row_size]; |
| 354 left = pDestData[byte - BytesPerPixel]; | 432 } |
| 355 } | 433 pDestData[byte] = raw_byte + up; |
| 356 FX_BYTE up = 0; | 434 break; |
| 357 if (pLastLine) { | 435 } |
| 358 up = pLastLine[byte]; | 436 case 3: { |
| 359 } | 437 FX_BYTE left = 0; |
| 360 pDestData[byte] = raw_byte + (up + left) / 2; | 438 if (byte >= BytesPerPixel) { |
| 361 break; | 439 left = pDestData[byte - BytesPerPixel]; |
| 362 } | 440 } |
| 363 case 4: { | 441 FX_BYTE up = 0; |
| 364 FX_BYTE left = 0; | 442 if (row) { |
| 365 if (byte >= BytesPerPixel) { | 443 up = pDestData[byte - row_size]; |
| 366 left = pDestData[byte - BytesPerPixel]; | 444 } |
| 367 } | 445 pDestData[byte] = raw_byte + (up + left) / 2; |
| 368 FX_BYTE up = 0; | 446 break; |
| 369 if (pLastLine) { | 447 } |
| 370 up = pLastLine[byte]; | 448 case 4: { |
| 371 } | 449 FX_BYTE left = 0; |
| 372 FX_BYTE upper_left = 0; | 450 if (byte >= BytesPerPixel) { |
| 373 if (byte >= BytesPerPixel && pLastLine) { | 451 left = pDestData[byte - BytesPerPixel]; |
| 374 upper_left = pLastLine[byte - BytesPerPixel]; | 452 } |
| 375 } | 453 FX_BYTE up = 0; |
| 376 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_
left); | 454 if (row) { |
| 377 break; | 455 up = pDestData[byte - row_size]; |
| 378 } | 456 } |
| 379 default: | 457 FX_BYTE upper_left = 0; |
| 380 pDestData[byte] = raw_byte; | 458 if (byte >= BytesPerPixel && row) { |
| 381 break; | 459 upper_left = pDestData[byte - row_size - BytesPerPixel]; |
| 382 } | 460 } |
| 383 } | 461 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); |
| 384 } | 462 break; |
| 385 static void PNG_Predictor(FX_LPBYTE& data_buf, FX_DWORD& data_size, | 463 } |
| 386 int Colors, int BitsPerComponent, int Columns) | 464 default: |
| 387 { | 465 pDestData[byte] = raw_byte; |
| 388 int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; | 466 break; |
| 389 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 467 } |
| 390 int row_count = (data_size + row_size) / (row_size + 1); | 468 byte_cnt++; |
| 391 int last_row_size = data_size % (row_size + 1); | 469 } |
| 392 FX_LPBYTE dest_buf = FX_Alloc( FX_BYTE, row_size * row_count); | 470 pSrcData += row_size + 1; |
| 393 if (dest_buf == NULL) { | 471 pDestData += row_size; |
| 394 return; | 472 byte_cnt++; |
| 395 } | 473 } |
| 396 int byte_cnt = 0; | 474 FX_Free(data_buf); |
| 397 FX_LPBYTE pSrcData = data_buf; | 475 data_buf = dest_buf; |
| 398 FX_LPBYTE pDestData = dest_buf; | 476 data_size = row_size * row_count - |
| 399 for (int row = 0; row < row_count; row ++) { | 477 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); |
| 400 FX_BYTE tag = pSrcData[0]; | 478 } |
| 401 if (tag == 0) { | 479 static void TIFF_PredictorEncodeLine(FX_LPBYTE dest_buf, |
| 402 int move_size = row_size; | 480 int row_size, |
| 403 if ((row + 1) * (move_size + 1) > (int)data_size) { | 481 int BitsPerComponent, |
| 404 move_size = last_row_size - 1; | 482 int Colors, |
| 405 } | 483 int Columns) { |
| 406 FXSYS_memmove32(pDestData, pSrcData + 1, move_size); | 484 int BytesPerPixel = BitsPerComponent * Colors / 8; |
| 407 pSrcData += move_size + 1; | 485 if (BitsPerComponent < 8) { |
| 408 pDestData += move_size; | 486 FX_BYTE mask = 0x01; |
| 409 byte_cnt += move_size + 1; | 487 if (BitsPerComponent == 2) { |
| 410 continue; | 488 mask = 0x03; |
| 411 } | 489 } else if (BitsPerComponent == 4) { |
| 412 for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte ++
) { | 490 mask = 0x0F; |
| 413 FX_BYTE raw_byte = pSrcData[byte + 1]; | 491 } |
| 414 switch (tag) { | 492 int row_bits = Colors * BitsPerComponent * Columns; |
| 415 case 1: { | 493 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; |
| 416 FX_BYTE left = 0; | 494 i -= BitsPerComponent) { |
| 417 if (byte >= BytesPerPixel) { | 495 int col = i % 8; |
| 418 left = pDestData[byte - BytesPerPixel]; | 496 int index = i / 8; |
| 419 } | 497 int col_pre = |
| 420 pDestData[byte] = raw_byte + left; | 498 (col == 0) ? (8 - BitsPerComponent) : (col - BitsPerComponent); |
| 421 break; | 499 int index_pre = (col == 0) ? (index - 1) : index; |
| 422 } | 500 FX_BYTE cur = (dest_buf[index] >> (8 - col - BitsPerComponent)) & mask; |
| 423 case 2: { | 501 FX_BYTE left = |
| 424 FX_BYTE up = 0; | 502 (dest_buf[index_pre] >> (8 - col_pre - BitsPerComponent)) & mask; |
| 425 if (row) { | 503 cur -= left; |
| 426 up = pDestData[byte - row_size]; | 504 cur &= mask; |
| 427 } | 505 cur <<= (8 - col - BitsPerComponent); |
| 428 pDestData[byte] = raw_byte + up; | 506 dest_buf[index] &= ~(mask << ((8 - col - BitsPerComponent))); |
| 429 break; | 507 dest_buf[index] |= cur; |
| 430 } | 508 } |
| 431 case 3: { | 509 } else if (BitsPerComponent == 8) { |
| 432 FX_BYTE left = 0; | 510 for (int i = row_size - 1; i >= BytesPerPixel; i--) { |
| 433 if (byte >= BytesPerPixel) { | 511 dest_buf[i] -= dest_buf[i - BytesPerPixel]; |
| 434 left = pDestData[byte - BytesPerPixel]; | 512 } |
| 435 } | 513 } else { |
| 436 FX_BYTE up = 0; | 514 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; |
| 437 if (row) { | 515 i -= BytesPerPixel) { |
| 438 up = pDestData[byte - row_size]; | 516 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; |
| 439 } | 517 pixel -= |
| 440 pDestData[byte] = raw_byte + (up + left) / 2; | 518 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; |
| 441 break; | 519 dest_buf[i] = pixel >> 8; |
| 442 } | 520 dest_buf[i + 1] = (FX_BYTE)pixel; |
| 443 case 4: { | 521 } |
| 444 FX_BYTE left = 0; | 522 } |
| 445 if (byte >= BytesPerPixel) { | 523 } |
| 446 left = pDestData[byte - BytesPerPixel]; | 524 static void TIFF_PredictorEncode(FX_LPBYTE& data_buf, |
| 447 } | 525 FX_DWORD& data_size, |
| 448 FX_BYTE up = 0; | 526 int Colors, |
| 449 if (row) { | 527 int BitsPerComponent, |
| 450 up = pDestData[byte - row_size]; | 528 int Columns) { |
| 451 } | 529 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 452 FX_BYTE upper_left = 0; | 530 int row_count = (data_size + row_size - 1) / row_size; |
| 453 if (byte >= BytesPerPixel && row) { | 531 int last_row_size = data_size % row_size; |
| 454 upper_left = pDestData[byte - row_size - BytesPerPix
el]; | 532 for (int row = 0; row < row_count; row++) { |
| 455 } | 533 FX_LPBYTE scan_line = data_buf + row * row_size; |
| 456 pDestData[byte] = raw_byte + PaethPredictor(left, up, up
per_left); | 534 if ((row + 1) * row_size > (int)data_size) { |
| 457 break; | 535 row_size = last_row_size; |
| 458 } | 536 } |
| 459 default: | 537 TIFF_PredictorEncodeLine( |
| 460 pDestData[byte] = raw_byte; | 538 scan_line, row_size, BitsPerComponent, Colors, Columns); |
| 461 break; | 539 } |
| 462 } | 540 } |
| 463 byte_cnt++; | 541 static void TIFF_PredictLine(FX_LPBYTE dest_buf, |
| 464 } | 542 int row_size, |
| 465 pSrcData += row_size + 1; | 543 int BitsPerComponent, |
| 466 pDestData += row_size; | 544 int Colors, |
| 467 byte_cnt++; | 545 int Columns) { |
| 468 } | 546 if (BitsPerComponent == 1) { |
| 469 FX_Free(data_buf); | 547 int row_bits = BitsPerComponent * Colors * Columns; |
| 470 data_buf = dest_buf; | 548 for (int i = 1; i < row_bits; i++) { |
| 471 data_size = row_size * row_count - (last_row_size > 0 ? (row_size + 1 - last
_row_size) : 0); | 549 int col = i % 8; |
| 472 } | 550 int index = i / 8; |
| 473 static void TIFF_PredictorEncodeLine(FX_LPBYTE dest_buf, int row_size, int BitsP
erComponent, int Colors, int Columns) | 551 int index_pre = (col == 0) ? (index - 1) : index; |
| 474 { | 552 int col_pre = (col == 0) ? 8 : col; |
| 475 int BytesPerPixel = BitsPerComponent * Colors / 8; | 553 if (((dest_buf[index] >> (7 - col)) & 1) ^ |
| 476 if (BitsPerComponent < 8) { | 554 ((dest_buf[index_pre] >> (8 - col_pre)) & 1)) { |
| 477 FX_BYTE mask = 0x01; | 555 dest_buf[index] |= 1 << (7 - col); |
| 478 if (BitsPerComponent == 2) { | 556 } else { |
| 479 mask = 0x03; | 557 dest_buf[index] &= ~(1 << (7 - col)); |
| 480 } else if (BitsPerComponent == 4) { | 558 } |
| 481 mask = 0x0F; | 559 } |
| 482 } | 560 return; |
| 483 int row_bits = Colors * BitsPerComponent * Columns; | 561 } |
| 484 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; i -= Bi
tsPerComponent) { | 562 int BytesPerPixel = BitsPerComponent * Colors / 8; |
| 485 int col = i % 8; | 563 if (BitsPerComponent == 16) { |
| 486 int index = i / 8; | 564 for (int i = BytesPerPixel; i < row_size; i += 2) { |
| 487 int col_pre = (col == 0) ? (8 - BitsPerComponent) : (col - BitsPerCo
mponent); | 565 FX_WORD pixel = |
| 488 int index_pre = (col == 0) ? (index - 1) : index; | 566 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; |
| 489 FX_BYTE cur = (dest_buf[index] >> (8 - col - BitsPerComponent)) & ma
sk; | 567 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; |
| 490 FX_BYTE left = (dest_buf[index_pre] >> (8 - col_pre - BitsPerCompone
nt)) & mask; | 568 dest_buf[i] = pixel >> 8; |
| 491 cur -= left; | 569 dest_buf[i + 1] = (FX_BYTE)pixel; |
| 492 cur &= mask; | 570 } |
| 493 cur <<= (8 - col - BitsPerComponent); | 571 } else { |
| 494 dest_buf[index] &= ~(mask << ((8 - col - BitsPerComponent))); | 572 for (int i = BytesPerPixel; i < row_size; i++) { |
| 495 dest_buf[index] |= cur; | 573 dest_buf[i] += dest_buf[i - BytesPerPixel]; |
| 496 } | 574 } |
| 497 } else if (BitsPerComponent == 8) { | 575 } |
| 498 for (int i = row_size - 1; i >= BytesPerPixel; i--) { | 576 } |
| 499 dest_buf[i] -= dest_buf[i - BytesPerPixel]; | 577 static void TIFF_Predictor(FX_LPBYTE& data_buf, |
| 500 } | 578 FX_DWORD& data_size, |
| 579 int Colors, |
| 580 int BitsPerComponent, |
| 581 int Columns) { |
| 582 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 583 int row_count = (data_size + row_size - 1) / row_size; |
| 584 int last_row_size = data_size % row_size; |
| 585 for (int row = 0; row < row_count; row++) { |
| 586 FX_LPBYTE scan_line = data_buf + row * row_size; |
| 587 if ((row + 1) * row_size > (int)data_size) { |
| 588 row_size = last_row_size; |
| 589 } |
| 590 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); |
| 591 } |
| 592 } |
| 593 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { |
| 594 public: |
| 595 CCodec_FlateScanlineDecoder(); |
| 596 ~CCodec_FlateScanlineDecoder(); |
| 597 FX_BOOL Create(FX_LPCBYTE src_buf, |
| 598 FX_DWORD src_size, |
| 599 int width, |
| 600 int height, |
| 601 int nComps, |
| 602 int bpc, |
| 603 int predictor, |
| 604 int Colors, |
| 605 int BitsPerComponent, |
| 606 int Columns); |
| 607 virtual void Destroy() { delete this; } |
| 608 virtual void v_DownScale(int dest_width, int dest_height) {} |
| 609 virtual FX_BOOL v_Rewind(); |
| 610 virtual FX_LPBYTE v_GetNextLine(); |
| 611 virtual FX_DWORD GetSrcOffset(); |
| 612 void* m_pFlate; |
| 613 FX_LPCBYTE m_SrcBuf; |
| 614 FX_DWORD m_SrcSize; |
| 615 FX_LPBYTE m_pScanline; |
| 616 FX_LPBYTE m_pLastLine; |
| 617 FX_LPBYTE m_pPredictBuffer; |
| 618 FX_LPBYTE m_pPredictRaw; |
| 619 int m_Predictor; |
| 620 int m_Colors, m_BitsPerComponent, m_Columns, m_PredictPitch, m_LeftOver; |
| 621 }; |
| 622 CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder() { |
| 623 m_pFlate = NULL; |
| 624 m_pScanline = NULL; |
| 625 m_pLastLine = NULL; |
| 626 m_pPredictBuffer = NULL; |
| 627 m_pPredictRaw = NULL; |
| 628 m_LeftOver = 0; |
| 629 } |
| 630 CCodec_FlateScanlineDecoder::~CCodec_FlateScanlineDecoder() { |
| 631 if (m_pScanline) { |
| 632 FX_Free(m_pScanline); |
| 633 } |
| 634 if (m_pLastLine) { |
| 635 FX_Free(m_pLastLine); |
| 636 } |
| 637 if (m_pPredictBuffer) { |
| 638 FX_Free(m_pPredictBuffer); |
| 639 } |
| 640 if (m_pPredictRaw) { |
| 641 FX_Free(m_pPredictRaw); |
| 642 } |
| 643 if (m_pFlate) { |
| 644 FPDFAPI_FlateEnd(m_pFlate); |
| 645 } |
| 646 } |
| 647 FX_BOOL CCodec_FlateScanlineDecoder::Create(FX_LPCBYTE src_buf, |
| 648 FX_DWORD src_size, |
| 649 int width, |
| 650 int height, |
| 651 int nComps, |
| 652 int bpc, |
| 653 int predictor, |
| 654 int Colors, |
| 655 int BitsPerComponent, |
| 656 int Columns) { |
| 657 m_SrcBuf = src_buf; |
| 658 m_SrcSize = src_size; |
| 659 m_OutputWidth = m_OrigWidth = width; |
| 660 m_OutputHeight = m_OrigHeight = height; |
| 661 m_nComps = nComps; |
| 662 m_bpc = bpc; |
| 663 m_bColorTransformed = FALSE; |
| 664 m_Pitch = (width * nComps * bpc + 7) / 8; |
| 665 m_pScanline = FX_Alloc(FX_BYTE, m_Pitch); |
| 666 if (m_pScanline == NULL) { |
| 667 return FALSE; |
| 668 } |
| 669 m_Predictor = 0; |
| 670 if (predictor) { |
| 671 if (predictor >= 10) { |
| 672 m_Predictor = 2; |
| 673 } else if (predictor == 2) { |
| 674 m_Predictor = 1; |
| 675 } |
| 676 if (m_Predictor) { |
| 677 if (BitsPerComponent * Colors * Columns == 0) { |
| 678 BitsPerComponent = m_bpc; |
| 679 Colors = m_nComps; |
| 680 Columns = m_OrigWidth; |
| 681 } |
| 682 m_Colors = Colors; |
| 683 m_BitsPerComponent = BitsPerComponent; |
| 684 m_Columns = Columns; |
| 685 m_PredictPitch = (m_BitsPerComponent * m_Colors * m_Columns + 7) / 8; |
| 686 m_pLastLine = FX_Alloc(FX_BYTE, m_PredictPitch); |
| 687 if (m_pLastLine == NULL) { |
| 688 return FALSE; |
| 689 } |
| 690 m_pPredictRaw = FX_Alloc(FX_BYTE, m_PredictPitch + 1); |
| 691 if (m_pPredictRaw == NULL) { |
| 692 return FALSE; |
| 693 } |
| 694 m_pPredictBuffer = FX_Alloc(FX_BYTE, m_PredictPitch); |
| 695 if (m_pPredictBuffer == NULL) { |
| 696 return FALSE; |
| 697 } |
| 698 } |
| 699 } |
| 700 return TRUE; |
| 701 } |
| 702 FX_BOOL CCodec_FlateScanlineDecoder::v_Rewind() { |
| 703 if (m_pFlate) { |
| 704 FPDFAPI_FlateEnd(m_pFlate); |
| 705 } |
| 706 m_pFlate = FPDFAPI_FlateInit(my_alloc_func, my_free_func); |
| 707 if (m_pFlate == NULL) { |
| 708 return FALSE; |
| 709 } |
| 710 FPDFAPI_FlateInput(m_pFlate, m_SrcBuf, m_SrcSize); |
| 711 m_LeftOver = 0; |
| 712 return TRUE; |
| 713 } |
| 714 FX_LPBYTE CCodec_FlateScanlineDecoder::v_GetNextLine() { |
| 715 if (m_Predictor) { |
| 716 if (m_Pitch == m_PredictPitch) { |
| 717 if (m_Predictor == 2) { |
| 718 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); |
| 719 PNG_PredictLine(m_pScanline, |
| 720 m_pPredictRaw, |
| 721 m_pLastLine, |
| 722 m_BitsPerComponent, |
| 723 m_Colors, |
| 724 m_Columns); |
| 725 FXSYS_memcpy32(m_pLastLine, m_pScanline, m_PredictPitch); |
| 726 } else { |
| 727 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); |
| 728 TIFF_PredictLine( |
| 729 m_pScanline, m_PredictPitch, m_bpc, m_nComps, m_OutputWidth); |
| 730 } |
| 501 } else { | 731 } else { |
| 502 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; i -= BytesPer
Pixel) { | 732 int bytes_to_go = m_Pitch; |
| 503 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; | 733 int read_leftover = m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver; |
| 504 pixel -= (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerP
ixel + 1]; | 734 if (read_leftover) { |
| 505 dest_buf[i] = pixel >> 8; | 735 FXSYS_memcpy32(m_pScanline, |
| 506 dest_buf[i + 1] = (FX_BYTE)pixel; | 736 m_pPredictBuffer + m_PredictPitch - m_LeftOver, |
| 507 } | 737 read_leftover); |
| 508 } | 738 m_LeftOver -= read_leftover; |
| 509 } | 739 bytes_to_go -= read_leftover; |
| 510 static void TIFF_PredictorEncode(FX_LPBYTE& data_buf, FX_DWORD& data_size, | 740 } |
| 511 int Colors, int BitsPerComponent, int Columns) | 741 while (bytes_to_go) { |
| 512 { | 742 if (m_Predictor == 2) { |
| 513 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 743 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); |
| 514 int row_count = (data_size + row_size - 1) / row_size; | 744 PNG_PredictLine(m_pPredictBuffer, |
| 515 int last_row_size = data_size % row_size; | 745 m_pPredictRaw, |
| 516 for (int row = 0; row < row_count; row++) { | 746 m_pLastLine, |
| 517 FX_LPBYTE scan_line = data_buf + row * row_size; | 747 m_BitsPerComponent, |
| 518 if ((row + 1) * row_size > (int)data_size) { | 748 m_Colors, |
| 519 row_size = last_row_size; | 749 m_Columns); |
| 520 } | 750 FXSYS_memcpy32(m_pLastLine, m_pPredictBuffer, m_PredictPitch); |
| 521 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors,
Columns); | 751 } else { |
| 522 } | 752 FPDFAPI_FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch); |
| 523 } | 753 TIFF_PredictLine(m_pPredictBuffer, |
| 524 static void TIFF_PredictLine(FX_LPBYTE dest_buf, int row_size, int BitsPerCompon
ent, int Colors, int Columns) | 754 m_PredictPitch, |
| 525 { | 755 m_BitsPerComponent, |
| 526 if (BitsPerComponent == 1) { | 756 m_Colors, |
| 527 int row_bits = BitsPerComponent * Colors * Columns; | 757 m_Columns); |
| 528 for(int i = 1; i < row_bits; i ++) { | 758 } |
| 529 int col = i % 8; | 759 int read_bytes = |
| 530 int index = i / 8; | 760 m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch; |
| 531 int index_pre = (col == 0) ? (index - 1) : index; | 761 FXSYS_memcpy32( |
| 532 int col_pre = (col == 0) ? 8 : col; | 762 m_pScanline + m_Pitch - bytes_to_go, m_pPredictBuffer, read_bytes); |
| 533 if( ((dest_buf[index] >> (7 - col)) & 1) ^ ((dest_buf[index_pre] >>
(8 - col_pre)) & 1) ) { | 763 m_LeftOver += m_PredictPitch - read_bytes; |
| 534 dest_buf[index] |= 1 << (7 - col); | 764 bytes_to_go -= read_bytes; |
| 535 } else { | 765 } |
| 536 dest_buf[index] &= ~(1 << (7 - col)); | 766 } |
| 537 } | 767 } else { |
| 538 } | 768 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); |
| 539 return; | 769 } |
| 540 } | 770 return m_pScanline; |
| 541 int BytesPerPixel = BitsPerComponent * Colors / 8; | 771 } |
| 542 if (BitsPerComponent == 16) { | 772 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() { |
| 543 for (int i = BytesPerPixel; i < row_size; i += 2) { | 773 return FPDFAPI_FlateGetTotalIn(m_pFlate); |
| 544 FX_WORD pixel = (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - By
tesPerPixel + 1]; | 774 } |
| 545 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; | 775 static void FlateUncompress(FX_LPCBYTE src_buf, |
| 546 dest_buf[i] = pixel >> 8; | 776 FX_DWORD src_size, |
| 547 dest_buf[i + 1] = (FX_BYTE)pixel; | 777 FX_DWORD orig_size, |
| 548 } | 778 FX_LPBYTE& dest_buf, |
| 779 FX_DWORD& dest_size, |
| 780 FX_DWORD& offset) { |
| 781 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; |
| 782 FX_DWORD alloc_step = |
| 783 orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size); |
| 784 static const FX_DWORD kMaxInitialAllocSize = 10000000; |
| 785 if (guess_size > kMaxInitialAllocSize) { |
| 786 guess_size = kMaxInitialAllocSize; |
| 787 alloc_step = kMaxInitialAllocSize; |
| 788 } |
| 789 FX_LPBYTE guess_buf = FX_Alloc(FX_BYTE, guess_size + 1); |
| 790 if (!guess_buf) { |
| 791 dest_buf = NULL; |
| 792 dest_size = 0; |
| 793 return; |
| 794 } |
| 795 guess_buf[guess_size] = '\0'; |
| 796 FX_BOOL useOldImpl = src_size < 10240; |
| 797 void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); |
| 798 if (context == NULL) { |
| 799 dest_buf = NULL; |
| 800 dest_size = 0; |
| 801 return; |
| 802 } |
| 803 FPDFAPI_FlateInput(context, src_buf, src_size); |
| 804 CFX_ArrayTemplate<FX_LPBYTE> result_tmp_bufs; |
| 805 FX_LPBYTE buf = guess_buf; |
| 806 FX_DWORD buf_size = guess_size; |
| 807 FX_DWORD last_buf_size = buf_size; |
| 808 while (1) { |
| 809 FX_INT32 ret = FPDFAPI_FlateOutput(context, buf, buf_size); |
| 810 FX_INT32 avail_buf_size = FPDFAPI_FlateGetAvailOut(context); |
| 811 if (!useOldImpl) { |
| 812 if (ret != Z_OK) { |
| 813 last_buf_size = buf_size - avail_buf_size; |
| 814 result_tmp_bufs.Add(buf); |
| 815 break; |
| 816 } |
| 817 if (avail_buf_size == 0) { |
| 818 result_tmp_bufs.Add(buf); |
| 819 buf = NULL; |
| 820 buf = FX_Alloc(FX_BYTE, buf_size + 1); |
| 821 if (!buf) { |
| 822 dest_buf = NULL; |
| 823 dest_size = 0; |
| 824 return; |
| 825 } |
| 826 buf[buf_size] = '\0'; |
| 827 } else { |
| 828 last_buf_size = buf_size - avail_buf_size; |
| 829 result_tmp_bufs.Add(buf); |
| 830 buf = NULL; |
| 831 break; |
| 832 } |
| 549 } else { | 833 } else { |
| 550 for (int i = BytesPerPixel; i < row_size; i ++) { | 834 if (ret != Z_OK) { |
| 551 dest_buf[i] += dest_buf[i - BytesPerPixel]; | 835 break; |
| 552 } | 836 } |
| 553 } | 837 if (avail_buf_size == 0) { |
| 554 } | 838 FX_DWORD old_size = guess_size; |
| 555 static void TIFF_Predictor(FX_LPBYTE& data_buf, FX_DWORD& data_size, | 839 guess_size += alloc_step; |
| 556 int Colors, int BitsPerComponent, int Columns) | 840 if (guess_size < old_size || guess_size + 1 < guess_size) { |
| 557 { | 841 dest_buf = NULL; |
| 558 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 842 dest_size = 0; |
| 559 int row_count = (data_size + row_size - 1) / row_size; | 843 return; |
| 560 int last_row_size = data_size % row_size; | 844 } |
| 561 for (int row = 0; row < row_count; row ++) { | 845 guess_buf = FX_Realloc(FX_BYTE, guess_buf, guess_size + 1); |
| 562 FX_LPBYTE scan_line = data_buf + row * row_size; | 846 if (!guess_buf) { |
| 563 if ((row + 1) * row_size > (int)data_size) { | 847 dest_buf = NULL; |
| 564 row_size = last_row_size; | 848 dest_size = 0; |
| 565 } | 849 return; |
| 566 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns)
; | 850 } |
| 567 } | 851 guess_buf[guess_size] = '\0'; |
| 568 } | 852 buf = guess_buf + old_size; |
| 569 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder | 853 buf_size = guess_size - old_size; |
| 570 { | 854 } else { |
| 571 public: | 855 break; |
| 572 CCodec_FlateScanlineDecoder(); | 856 } |
| 573 ~CCodec_FlateScanlineDecoder(); | 857 } |
| 574 FX_BOOL» » Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width,
int height, int nComps, int bpc, | 858 } |
| 575 int predictor, int Colors, int BitsPerComponent, int Colu
mns); | 859 dest_size = FPDFAPI_FlateGetTotalOut(context); |
| 576 virtual void» » Destroy() | 860 offset = FPDFAPI_FlateGetTotalIn(context); |
| 577 { | 861 if (!useOldImpl) { |
| 578 delete this; | 862 if (result_tmp_bufs.GetSize() == 1) { |
| 579 } | 863 dest_buf = result_tmp_bufs[0]; |
| 580 virtual void» » v_DownScale(int dest_width, int dest_height) {} | |
| 581 virtual FX_BOOL» » v_Rewind(); | |
| 582 virtual FX_LPBYTE» v_GetNextLine(); | |
| 583 virtual FX_DWORD» GetSrcOffset(); | |
| 584 void*» » » » m_pFlate; | |
| 585 FX_LPCBYTE» » » m_SrcBuf; | |
| 586 FX_DWORD» » » m_SrcSize; | |
| 587 FX_LPBYTE» » » m_pScanline; | |
| 588 FX_LPBYTE» » » m_pLastLine; | |
| 589 FX_LPBYTE» » » m_pPredictBuffer; | |
| 590 FX_LPBYTE» » » m_pPredictRaw; | |
| 591 int»» » » » m_Predictor; | |
| 592 int»» » » » m_Colors, m_BitsPerComponent, m_Columns,
m_PredictPitch, m_LeftOver; | |
| 593 }; | |
| 594 CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder() | |
| 595 { | |
| 596 m_pFlate = NULL; | |
| 597 m_pScanline = NULL; | |
| 598 m_pLastLine = NULL; | |
| 599 m_pPredictBuffer = NULL; | |
| 600 m_pPredictRaw = NULL; | |
| 601 m_LeftOver = 0; | |
| 602 } | |
| 603 CCodec_FlateScanlineDecoder::~CCodec_FlateScanlineDecoder() | |
| 604 { | |
| 605 if (m_pScanline) { | |
| 606 FX_Free(m_pScanline); | |
| 607 } | |
| 608 if (m_pLastLine) { | |
| 609 FX_Free(m_pLastLine); | |
| 610 } | |
| 611 if (m_pPredictBuffer) { | |
| 612 FX_Free(m_pPredictBuffer); | |
| 613 } | |
| 614 if (m_pPredictRaw) { | |
| 615 FX_Free(m_pPredictRaw); | |
| 616 } | |
| 617 if (m_pFlate) { | |
| 618 FPDFAPI_FlateEnd(m_pFlate); | |
| 619 } | |
| 620 } | |
| 621 FX_BOOL CCodec_FlateScanlineDecoder::Create(FX_LPCBYTE src_buf, FX_DWORD src_siz
e, int width, int height, | |
| 622 int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, in
t Columns) | |
| 623 { | |
| 624 m_SrcBuf = src_buf; | |
| 625 m_SrcSize = src_size; | |
| 626 m_OutputWidth = m_OrigWidth = width; | |
| 627 m_OutputHeight = m_OrigHeight = height; | |
| 628 m_nComps = nComps; | |
| 629 m_bpc = bpc; | |
| 630 m_bColorTransformed = FALSE; | |
| 631 m_Pitch = (width * nComps * bpc + 7) / 8; | |
| 632 m_pScanline = FX_Alloc(FX_BYTE, m_Pitch); | |
| 633 if (m_pScanline == NULL) { | |
| 634 return FALSE; | |
| 635 } | |
| 636 m_Predictor = 0; | |
| 637 if (predictor) { | |
| 638 if (predictor >= 10) { | |
| 639 m_Predictor = 2; | |
| 640 } else if (predictor == 2) { | |
| 641 m_Predictor = 1; | |
| 642 } | |
| 643 if (m_Predictor) { | |
| 644 if (BitsPerComponent * Colors * Columns == 0) { | |
| 645 BitsPerComponent = m_bpc; | |
| 646 Colors = m_nComps; | |
| 647 Columns = m_OrigWidth; | |
| 648 } | |
| 649 m_Colors = Colors; | |
| 650 m_BitsPerComponent = BitsPerComponent; | |
| 651 m_Columns = Columns; | |
| 652 m_PredictPitch = (m_BitsPerComponent * m_Colors * m_Columns + 7) / 8
; | |
| 653 m_pLastLine = FX_Alloc(FX_BYTE, m_PredictPitch); | |
| 654 if (m_pLastLine == NULL) { | |
| 655 return FALSE; | |
| 656 } | |
| 657 m_pPredictRaw = FX_Alloc(FX_BYTE, m_PredictPitch + 1); | |
| 658 if (m_pPredictRaw == NULL) { | |
| 659 return FALSE; | |
| 660 } | |
| 661 m_pPredictBuffer = FX_Alloc(FX_BYTE, m_PredictPitch); | |
| 662 if (m_pPredictBuffer == NULL) { | |
| 663 return FALSE; | |
| 664 } | |
| 665 } | |
| 666 } | |
| 667 return TRUE; | |
| 668 } | |
| 669 FX_BOOL CCodec_FlateScanlineDecoder::v_Rewind() | |
| 670 { | |
| 671 if (m_pFlate) { | |
| 672 FPDFAPI_FlateEnd(m_pFlate); | |
| 673 } | |
| 674 m_pFlate = FPDFAPI_FlateInit(my_alloc_func, my_free_func); | |
| 675 if (m_pFlate == NULL) { | |
| 676 return FALSE; | |
| 677 } | |
| 678 FPDFAPI_FlateInput(m_pFlate, m_SrcBuf, m_SrcSize); | |
| 679 m_LeftOver = 0; | |
| 680 return TRUE; | |
| 681 } | |
| 682 FX_LPBYTE CCodec_FlateScanlineDecoder::v_GetNextLine() | |
| 683 { | |
| 684 if (m_Predictor) { | |
| 685 if (m_Pitch == m_PredictPitch) { | |
| 686 if (m_Predictor == 2) { | |
| 687 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1)
; | |
| 688 PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine, m_BitsP
erComponent, m_Colors, m_Columns); | |
| 689 FXSYS_memcpy32(m_pLastLine, m_pScanline, m_PredictPitch); | |
| 690 } else { | |
| 691 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); | |
| 692 TIFF_PredictLine(m_pScanline, m_PredictPitch, m_bpc, m_nComps, m
_OutputWidth); | |
| 693 } | |
| 694 } else { | |
| 695 int bytes_to_go = m_Pitch; | |
| 696 int read_leftover = m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftO
ver; | |
| 697 if (read_leftover) { | |
| 698 FXSYS_memcpy32(m_pScanline, m_pPredictBuffer + m_PredictPitch -
m_LeftOver, read_leftover); | |
| 699 m_LeftOver -= read_leftover; | |
| 700 bytes_to_go -= read_leftover; | |
| 701 } | |
| 702 while (bytes_to_go) { | |
| 703 if (m_Predictor == 2) { | |
| 704 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch
+ 1); | |
| 705 PNG_PredictLine(m_pPredictBuffer, m_pPredictRaw, m_pLastLine
, m_BitsPerComponent, m_Colors, m_Columns); | |
| 706 FXSYS_memcpy32(m_pLastLine, m_pPredictBuffer, m_PredictPitch
); | |
| 707 } else { | |
| 708 FPDFAPI_FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPit
ch); | |
| 709 TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPer
Component, m_Colors, m_Columns); | |
| 710 } | |
| 711 int read_bytes = m_PredictPitch > bytes_to_go ? bytes_to_go : m_
PredictPitch; | |
| 712 FXSYS_memcpy32(m_pScanline + m_Pitch - bytes_to_go, m_pPredictBu
ffer, read_bytes); | |
| 713 m_LeftOver += m_PredictPitch - read_bytes; | |
| 714 bytes_to_go -= read_bytes; | |
| 715 } | |
| 716 } | |
| 717 } else { | 864 } else { |
| 718 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); | 865 FX_LPBYTE result_buf = FX_Alloc(FX_BYTE, dest_size); |
| 719 } | 866 if (!result_buf) { |
| 720 return m_pScanline; | |
| 721 } | |
| 722 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() | |
| 723 { | |
| 724 return FPDFAPI_FlateGetTotalIn(m_pFlate); | |
| 725 } | |
| 726 static void FlateUncompress(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_DWORD orig
_size, | |
| 727 FX_LPBYTE& dest_buf, FX_DWORD& dest_size, FX_DWORD&
offset) | |
| 728 { | |
| 729 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; | |
| 730 FX_DWORD alloc_step = orig_size ? 10240 : (src_size < 10240 ? 10240 : src_si
ze); | |
| 731 static const FX_DWORD kMaxInitialAllocSize = 10000000; | |
| 732 if (guess_size > kMaxInitialAllocSize) { | |
| 733 guess_size = kMaxInitialAllocSize; | |
| 734 alloc_step = kMaxInitialAllocSize; | |
| 735 } | |
| 736 FX_LPBYTE guess_buf = FX_Alloc(FX_BYTE, guess_size + 1); | |
| 737 if (!guess_buf) { | |
| 738 dest_buf = NULL; | 867 dest_buf = NULL; |
| 739 dest_size = 0; | 868 dest_size = 0; |
| 740 return; | 869 return; |
| 741 } | 870 } |
| 742 guess_buf[guess_size] = '\0'; | 871 FX_DWORD result_pos = 0; |
| 743 FX_BOOL useOldImpl = src_size < 10240; | 872 for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { |
| 744 void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); | 873 FX_LPBYTE tmp_buf = result_tmp_bufs[i]; |
| 745 if (context == NULL) { | 874 FX_DWORD tmp_buf_size = buf_size; |
| 875 if (i == result_tmp_bufs.GetSize() - 1) { |
| 876 tmp_buf_size = last_buf_size; |
| 877 } |
| 878 FXSYS_memcpy32(result_buf + result_pos, tmp_buf, tmp_buf_size); |
| 879 result_pos += tmp_buf_size; |
| 880 FX_Free(tmp_buf); |
| 881 tmp_buf = NULL; |
| 882 result_tmp_bufs[i] = NULL; |
| 883 } |
| 884 dest_buf = result_buf; |
| 885 } |
| 886 } else { |
| 887 if (guess_size / 2 > dest_size) { |
| 888 guess_buf = FX_Realloc(FX_BYTE, guess_buf, dest_size + 1); |
| 889 if (!guess_buf) { |
| 746 dest_buf = NULL; | 890 dest_buf = NULL; |
| 747 dest_size = 0; | 891 dest_size = 0; |
| 748 return ; | 892 return; |
| 749 } | 893 } |
| 750 FPDFAPI_FlateInput(context, src_buf, src_size); | 894 guess_size = dest_size; |
| 751 CFX_ArrayTemplate<FX_LPBYTE> result_tmp_bufs; | 895 guess_buf[guess_size] = '\0'; |
| 752 FX_LPBYTE buf = guess_buf; | 896 } |
| 753 FX_DWORD buf_size = guess_size; | 897 dest_buf = guess_buf; |
| 754 FX_DWORD last_buf_size = buf_size; | 898 } |
| 755 while (1) { | 899 FPDFAPI_FlateEnd(context); |
| 756 FX_INT32 ret = FPDFAPI_FlateOutput(context, buf, buf_size); | 900 context = NULL; |
| 757 FX_INT32 avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | 901 } |
| 758 if (!useOldImpl) { | 902 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder(FX_LPCBYTE src_buf, |
| 759 if (ret != Z_OK) { | 903 FX_DWORD src_size, |
| 760 last_buf_size = buf_size - avail_buf_size; | 904 int width, |
| 761 result_tmp_bufs.Add(buf); | 905 int height, |
| 762 break; | 906 int nComps, |
| 763 } | 907 int bpc, |
| 764 if (avail_buf_size == 0) { | 908 int predictor, |
| 765 result_tmp_bufs.Add(buf); | 909 int Colors, |
| 766 buf = NULL; | 910 int BitsPerComponent, |
| 767 buf = FX_Alloc(FX_BYTE, buf_size + 1); | 911 int Columns) { |
| 768 if (!buf) { | 912 CCodec_FlateScanlineDecoder* pDecoder = FX_NEW CCodec_FlateScanlineDecoder; |
| 769 dest_buf = NULL; | 913 if (pDecoder == NULL) { |
| 770 dest_size = 0; | 914 return NULL; |
| 771 return; | 915 } |
| 772 } | 916 pDecoder->Create(src_buf, |
| 773 buf[buf_size] = '\0'; | 917 src_size, |
| 774 } else { | 918 width, |
| 775 last_buf_size = buf_size - avail_buf_size; | 919 height, |
| 776 result_tmp_bufs.Add(buf); | 920 nComps, |
| 777 buf = NULL; | 921 bpc, |
| 778 break; | 922 predictor, |
| 779 } | 923 Colors, |
| 780 } else { | 924 BitsPerComponent, |
| 781 if (ret != Z_OK) { | 925 Columns); |
| 782 break; | 926 return pDecoder; |
| 783 } | 927 } |
| 784 if (avail_buf_size == 0) { | 928 FX_DWORD CCodec_FlateModule::FlateOrLZWDecode(FX_BOOL bLZW, |
| 785 FX_DWORD old_size = guess_size; | 929 const FX_BYTE* src_buf, |
| 786 guess_size += alloc_step; | 930 FX_DWORD src_size, |
| 787 if (guess_size < old_size || guess_size + 1 < guess_size) { | 931 FX_BOOL bEarlyChange, |
| 788 dest_buf = NULL; | 932 int predictor, |
| 789 dest_size = 0; | 933 int Colors, |
| 790 return; | 934 int BitsPerComponent, |
| 791 } | 935 int Columns, |
| 792 guess_buf = FX_Realloc(FX_BYTE, guess_buf, guess_size + 1); | 936 FX_DWORD estimated_size, |
| 793 if (!guess_buf) { | 937 FX_LPBYTE& dest_buf, |
| 794 dest_buf = NULL; | 938 FX_DWORD& dest_size) { |
| 795 dest_size = 0; | 939 CLZWDecoder* pDecoder = NULL; |
| 796 return; | 940 dest_buf = NULL; |
| 797 } | 941 FX_DWORD offset = 0; |
| 798 guess_buf[guess_size] = '\0'; | 942 int predictor_type = 0; |
| 799 buf = guess_buf + old_size; | 943 if (predictor) { |
| 800 buf_size = guess_size - old_size; | 944 if (predictor >= 10) { |
| 801 } else { | 945 predictor_type = 2; |
| 802 break; | 946 } else if (predictor == 2) { |
| 803 } | 947 predictor_type = 1; |
| 804 } | 948 } |
| 805 } | 949 } |
| 806 dest_size = FPDFAPI_FlateGetTotalOut(context); | 950 if (bLZW) { |
| 807 offset = FPDFAPI_FlateGetTotalIn(context); | 951 pDecoder = FX_NEW CLZWDecoder; |
| 808 if (!useOldImpl) { | |
| 809 if (result_tmp_bufs.GetSize() == 1) { | |
| 810 dest_buf = result_tmp_bufs[0]; | |
| 811 } else { | |
| 812 FX_LPBYTE result_buf = FX_Alloc(FX_BYTE, dest_size); | |
| 813 if (!result_buf) { | |
| 814 dest_buf = NULL; | |
| 815 dest_size = 0; | |
| 816 return; | |
| 817 } | |
| 818 FX_DWORD result_pos = 0; | |
| 819 for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { | |
| 820 FX_LPBYTE tmp_buf = result_tmp_bufs[i]; | |
| 821 FX_DWORD tmp_buf_size = buf_size; | |
| 822 if (i == result_tmp_bufs.GetSize() - 1) { | |
| 823 tmp_buf_size = last_buf_size; | |
| 824 } | |
| 825 FXSYS_memcpy32(result_buf + result_pos, tmp_buf, tmp_buf_size); | |
| 826 result_pos += tmp_buf_size; | |
| 827 FX_Free(tmp_buf); | |
| 828 tmp_buf = NULL; | |
| 829 result_tmp_bufs[i] = NULL; | |
| 830 } | |
| 831 dest_buf = result_buf; | |
| 832 } | |
| 833 } else { | |
| 834 if (guess_size / 2 > dest_size) { | |
| 835 guess_buf = FX_Realloc(FX_BYTE, guess_buf, dest_size + 1); | |
| 836 if (!guess_buf) { | |
| 837 dest_buf = NULL; | |
| 838 dest_size = 0; | |
| 839 return; | |
| 840 } | |
| 841 guess_size = dest_size; | |
| 842 guess_buf[guess_size] = '\0'; | |
| 843 } | |
| 844 dest_buf = guess_buf; | |
| 845 } | |
| 846 FPDFAPI_FlateEnd(context); | |
| 847 context = NULL; | |
| 848 } | |
| 849 ICodec_ScanlineDecoder*»CCodec_FlateModule::CreateDecoder(FX_LPCBYTE src_buf, FX
_DWORD src_size, int width, int height, | |
| 850 int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, in
t Columns) | |
| 851 { | |
| 852 CCodec_FlateScanlineDecoder* pDecoder = FX_NEW CCodec_FlateScanlineDecoder; | |
| 853 if (pDecoder == NULL) { | 952 if (pDecoder == NULL) { |
| 854 return NULL; | 953 return -1; |
| 855 } | 954 } |
| 856 pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, C
olors, BitsPerComponent, Columns); | 955 dest_size = (FX_DWORD)-1; |
| 857 return pDecoder; | 956 offset = src_size; |
| 858 } | 957 int err = pDecoder->Decode(NULL, dest_size, src_buf, offset, bEarlyChange); |
| 859 FX_DWORD CCodec_FlateModule::FlateOrLZWDecode(FX_BOOL bLZW, const FX_BYTE* src_b
uf, FX_DWORD src_size, FX_BOOL bEarlyChange, | 958 delete pDecoder; |
| 860 int predictor, int Colors, int BitsPerComponent, int Columns, | 959 if (err || dest_size == 0 || dest_size + 1 < dest_size) { |
| 861 FX_DWORD estimated_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size) | 960 return (FX_DWORD)-1; |
| 862 { | 961 } |
| 863 CLZWDecoder* pDecoder = NULL; | 962 pDecoder = FX_NEW CLZWDecoder; |
| 864 dest_buf = NULL; | 963 if (pDecoder == NULL) { |
| 865 FX_DWORD offset = 0; | 964 return -1; |
| 866 int predictor_type = 0; | 965 } |
| 867 if (predictor) { | 966 dest_buf = FX_Alloc(FX_BYTE, dest_size + 1); |
| 868 if (predictor >= 10) { | 967 if (dest_buf == NULL) { |
| 869 predictor_type = 2; | 968 return -1; |
| 870 } else if (predictor == 2) { | 969 } |
| 871 predictor_type = 1; | 970 dest_buf[dest_size] = '\0'; |
| 872 } | 971 pDecoder->Decode(dest_buf, dest_size, src_buf, offset, bEarlyChange); |
| 873 } | 972 delete pDecoder; |
| 874 if (bLZW) { | 973 } else { |
| 875 pDecoder = FX_NEW CLZWDecoder; | 974 FlateUncompress( |
| 876 if (pDecoder == NULL) { | 975 src_buf, src_size, estimated_size, dest_buf, dest_size, offset); |
| 877 return -1; | 976 } |
| 878 } | 977 if (predictor_type == 0) { |
| 879 dest_size = (FX_DWORD) - 1; | |
| 880 offset = src_size; | |
| 881 int err = pDecoder->Decode(NULL, dest_size, src_buf, offset, bEarlyChang
e); | |
| 882 delete pDecoder; | |
| 883 if (err || dest_size == 0 || dest_size + 1 < dest_size) { | |
| 884 return (FX_DWORD) - 1; | |
| 885 } | |
| 886 pDecoder = FX_NEW CLZWDecoder; | |
| 887 if (pDecoder == NULL) { | |
| 888 return -1; | |
| 889 } | |
| 890 dest_buf = FX_Alloc( FX_BYTE, dest_size + 1); | |
| 891 if (dest_buf == NULL) { | |
| 892 return -1; | |
| 893 } | |
| 894 dest_buf[dest_size] = '\0'; | |
| 895 pDecoder->Decode(dest_buf, dest_size, src_buf, offset, bEarlyChange); | |
| 896 delete pDecoder; | |
| 897 } else { | |
| 898 FlateUncompress(src_buf, src_size, estimated_size, dest_buf, dest_size,
offset); | |
| 899 } | |
| 900 if (predictor_type == 0) { | |
| 901 return offset; | |
| 902 } | |
| 903 if (predictor_type == 2) { | |
| 904 PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); | |
| 905 } else if (predictor_type == 1) { | |
| 906 TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); | |
| 907 } | |
| 908 return offset; | 978 return offset; |
| 909 } | 979 } |
| 910 FX_BOOL CCodec_FlateModule::Encode(const FX_BYTE* src_buf, FX_DWORD src_size, | 980 if (predictor_type == 2) { |
| 911 int predictor, int Colors, int BitsPerCompone
nt, int Columns, | 981 PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); |
| 912 FX_LPBYTE& dest_buf, FX_DWORD& dest_size) | 982 } else if (predictor_type == 1) { |
| 913 { | 983 TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); |
| 914 if (predictor != 2 && predictor < 10) { | 984 } |
| 915 return Encode(src_buf, src_size, dest_buf, dest_size); | 985 return offset; |
| 916 } | 986 } |
| 917 FX_BOOL ret = FALSE; | 987 FX_BOOL CCodec_FlateModule::Encode(const FX_BYTE* src_buf, |
| 918 FX_LPBYTE pSrcBuf = NULL; | 988 FX_DWORD src_size, |
| 919 pSrcBuf = FX_Alloc(FX_BYTE, src_size); | 989 int predictor, |
| 920 if (pSrcBuf == NULL) { | 990 int Colors, |
| 921 return FALSE; | 991 int BitsPerComponent, |
| 922 } | 992 int Columns, |
| 923 FXSYS_memcpy32(pSrcBuf, src_buf, src_size); | 993 FX_LPBYTE& dest_buf, |
| 924 if (predictor == 2) { | 994 FX_DWORD& dest_size) { |
| 925 TIFF_PredictorEncode(pSrcBuf, src_size, Colors, BitsPerComponent, Column
s); | 995 if (predictor != 2 && predictor < 10) { |
| 926 } else if (predictor >= 10) { | 996 return Encode(src_buf, src_size, dest_buf, dest_size); |
| 927 PNG_PredictorEncode(pSrcBuf, src_size, predictor, Colors, BitsPerCompone
nt, Columns); | 997 } |
| 928 } | 998 FX_BOOL ret = FALSE; |
| 929 ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); | 999 FX_LPBYTE pSrcBuf = NULL; |
| 930 FX_Free(pSrcBuf); | 1000 pSrcBuf = FX_Alloc(FX_BYTE, src_size); |
| 931 return ret; | 1001 if (pSrcBuf == NULL) { |
| 932 } | 1002 return FALSE; |
| 933 FX_BOOL CCodec_FlateModule::Encode(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_LPB
YTE& dest_buf, FX_DWORD& dest_size) | 1003 } |
| 934 { | 1004 FXSYS_memcpy32(pSrcBuf, src_buf, src_size); |
| 935 dest_size = src_size + src_size / 1000 + 12; | 1005 if (predictor == 2) { |
| 936 dest_buf = FX_Alloc( FX_BYTE, dest_size); | 1006 TIFF_PredictorEncode(pSrcBuf, src_size, Colors, BitsPerComponent, Columns); |
| 937 if (dest_buf == NULL) { | 1007 } else if (predictor >= 10) { |
| 938 return FALSE; | 1008 PNG_PredictorEncode( |
| 939 } | 1009 pSrcBuf, src_size, predictor, Colors, BitsPerComponent, Columns); |
| 940 unsigned long temp_size = dest_size; | 1010 } |
| 941 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); | 1011 ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); |
| 942 dest_size = (FX_DWORD)temp_size; | 1012 FX_Free(pSrcBuf); |
| 943 return TRUE; | 1013 return ret; |
| 944 } | 1014 } |
| 1015 FX_BOOL CCodec_FlateModule::Encode(FX_LPCBYTE src_buf, |
| 1016 FX_DWORD src_size, |
| 1017 FX_LPBYTE& dest_buf, |
| 1018 FX_DWORD& dest_size) { |
| 1019 dest_size = src_size + src_size / 1000 + 12; |
| 1020 dest_buf = FX_Alloc(FX_BYTE, dest_size); |
| 1021 if (dest_buf == NULL) { |
| 1022 return FALSE; |
| 1023 } |
| 1024 unsigned long temp_size = dest_size; |
| 1025 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); |
| 1026 dest_size = (FX_DWORD)temp_size; |
| 1027 return TRUE; |
| 1028 } |
| OLD | NEW |