Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: core/src/fxcodec/codec/fx_codec_flate.cpp

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

Powered by Google App Engine
This is Rietveld 408576698