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 |