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