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