OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../../../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" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 } | 68 } |
69 int FPDFAPI_FlateGetAvailOut(void* context) { | 69 int FPDFAPI_FlateGetAvailOut(void* context) { |
70 return ((z_stream*)context)->avail_out; | 70 return ((z_stream*)context)->avail_out; |
71 } | 71 } |
72 void FPDFAPI_FlateEnd(void* context) { | 72 void FPDFAPI_FlateEnd(void* context) { |
73 inflateEnd((z_stream*)context); | 73 inflateEnd((z_stream*)context); |
74 ((z_stream*)context)->zfree(0, context); | 74 ((z_stream*)context)->zfree(0, context); |
75 } | 75 } |
76 } // extern "C" | 76 } // extern "C" |
77 | 77 |
| 78 namespace { |
| 79 |
78 class CLZWDecoder { | 80 class CLZWDecoder { |
79 public: | 81 public: |
80 int Decode(uint8_t* output, | 82 int Decode(uint8_t* output, |
81 FX_DWORD& outlen, | 83 FX_DWORD& outlen, |
82 const uint8_t* input, | 84 const uint8_t* input, |
83 FX_DWORD& size, | 85 FX_DWORD& size, |
84 FX_BOOL bEarlyChange); | 86 FX_BOOL bEarlyChange); |
85 | 87 |
86 private: | 88 private: |
87 void AddCode(FX_DWORD prefix_code, uint8_t append_char); | 89 void AddCode(FX_DWORD prefix_code, uint8_t append_char); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 } else { | 217 } else { |
216 AddCode(old_code, last_char); | 218 AddCode(old_code, last_char); |
217 } | 219 } |
218 old_code = code; | 220 old_code = code; |
219 } | 221 } |
220 } | 222 } |
221 dest_size = m_OutPos; | 223 dest_size = m_OutPos; |
222 src_size = (m_InPos + 7) / 8; | 224 src_size = (m_InPos + 7) / 8; |
223 return 0; | 225 return 0; |
224 } | 226 } |
225 static uint8_t PaethPredictor(int a, int b, int c) { | 227 |
| 228 uint8_t PaethPredictor(int a, int b, int c) { |
226 int p = a + b - c; | 229 int p = a + b - c; |
227 int pa = FXSYS_abs(p - a); | 230 int pa = FXSYS_abs(p - a); |
228 int pb = FXSYS_abs(p - b); | 231 int pb = FXSYS_abs(p - b); |
229 int pc = FXSYS_abs(p - c); | 232 int pc = FXSYS_abs(p - c); |
230 if (pa <= pb && pa <= pc) { | 233 if (pa <= pb && pa <= pc) { |
231 return (uint8_t)a; | 234 return (uint8_t)a; |
232 } | 235 } |
233 if (pb <= pc) { | 236 if (pb <= pc) { |
234 return (uint8_t)b; | 237 return (uint8_t)b; |
235 } | 238 } |
236 return (uint8_t)c; | 239 return (uint8_t)c; |
237 } | 240 } |
238 static FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf, | 241 |
239 FX_DWORD& data_size, | 242 FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf, |
240 int predictor, | 243 FX_DWORD& data_size, |
241 int Colors, | 244 int predictor, |
242 int BitsPerComponent, | 245 int Colors, |
243 int Columns) { | 246 int BitsPerComponent, |
| 247 int Columns) { |
244 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; | 248 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; |
245 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 249 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
246 if (row_size <= 0) | 250 if (row_size <= 0) |
247 return FALSE; | 251 return FALSE; |
248 const int row_count = (data_size + row_size - 1) / row_size; | 252 const int row_count = (data_size + row_size - 1) / row_size; |
249 const int last_row_size = data_size % row_size; | 253 const int last_row_size = data_size % row_size; |
250 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count); | 254 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count); |
251 int byte_cnt = 0; | 255 int byte_cnt = 0; |
252 uint8_t* pSrcData = data_buf; | 256 uint8_t* pSrcData = data_buf; |
253 uint8_t* pDestData = dest_buf; | 257 uint8_t* pDestData = dest_buf; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 } | 321 } |
318 pDestData += (row_size + 1); | 322 pDestData += (row_size + 1); |
319 pSrcData += row_size; | 323 pSrcData += row_size; |
320 } | 324 } |
321 FX_Free(data_buf); | 325 FX_Free(data_buf); |
322 data_buf = dest_buf; | 326 data_buf = dest_buf; |
323 data_size = (row_size + 1) * row_count - | 327 data_size = (row_size + 1) * row_count - |
324 (last_row_size > 0 ? (row_size - last_row_size) : 0); | 328 (last_row_size > 0 ? (row_size - last_row_size) : 0); |
325 return TRUE; | 329 return TRUE; |
326 } | 330 } |
327 static void PNG_PredictLine(uint8_t* pDestData, | 331 |
328 const uint8_t* pSrcData, | 332 void PNG_PredictLine(uint8_t* pDestData, |
329 const uint8_t* pLastLine, | 333 const uint8_t* pSrcData, |
330 int bpc, | 334 const uint8_t* pLastLine, |
331 int nColors, | 335 int bpc, |
332 int nPixels) { | 336 int nColors, |
| 337 int nPixels) { |
333 int row_size = (nPixels * bpc * nColors + 7) / 8; | 338 int row_size = (nPixels * bpc * nColors + 7) / 8; |
334 int BytesPerPixel = (bpc * nColors + 7) / 8; | 339 int BytesPerPixel = (bpc * nColors + 7) / 8; |
335 uint8_t tag = pSrcData[0]; | 340 uint8_t tag = pSrcData[0]; |
336 if (tag == 0) { | 341 if (tag == 0) { |
337 FXSYS_memmove(pDestData, pSrcData + 1, row_size); | 342 FXSYS_memmove(pDestData, pSrcData + 1, row_size); |
338 return; | 343 return; |
339 } | 344 } |
340 for (int byte = 0; byte < row_size; byte++) { | 345 for (int byte = 0; byte < row_size; byte++) { |
341 uint8_t raw_byte = pSrcData[byte + 1]; | 346 uint8_t raw_byte = pSrcData[byte + 1]; |
342 switch (tag) { | 347 switch (tag) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 } | 388 } |
384 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); | 389 pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); |
385 break; | 390 break; |
386 } | 391 } |
387 default: | 392 default: |
388 pDestData[byte] = raw_byte; | 393 pDestData[byte] = raw_byte; |
389 break; | 394 break; |
390 } | 395 } |
391 } | 396 } |
392 } | 397 } |
393 static FX_BOOL PNG_Predictor(uint8_t*& data_buf, | 398 |
394 FX_DWORD& data_size, | 399 FX_BOOL PNG_Predictor(uint8_t*& data_buf, |
395 int Colors, | 400 FX_DWORD& data_size, |
396 int BitsPerComponent, | 401 int Colors, |
397 int Columns) { | 402 int BitsPerComponent, |
| 403 int Columns) { |
398 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; | 404 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; |
399 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 405 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
400 if (row_size <= 0) | 406 if (row_size <= 0) |
401 return FALSE; | 407 return FALSE; |
402 const int row_count = (data_size + row_size) / (row_size + 1); | 408 const int row_count = (data_size + row_size) / (row_size + 1); |
403 if (row_count <= 0) | 409 if (row_count <= 0) |
404 return FALSE; | 410 return FALSE; |
405 const int last_row_size = data_size % (row_size + 1); | 411 const int last_row_size = data_size % (row_size + 1); |
406 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); | 412 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); |
407 int byte_cnt = 0; | 413 int byte_cnt = 0; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 } | 482 } |
477 pSrcData += row_size + 1; | 483 pSrcData += row_size + 1; |
478 pDestData += row_size; | 484 pDestData += row_size; |
479 } | 485 } |
480 FX_Free(data_buf); | 486 FX_Free(data_buf); |
481 data_buf = dest_buf; | 487 data_buf = dest_buf; |
482 data_size = row_size * row_count - | 488 data_size = row_size * row_count - |
483 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); | 489 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); |
484 return TRUE; | 490 return TRUE; |
485 } | 491 } |
486 static void TIFF_PredictorEncodeLine(uint8_t* dest_buf, | 492 |
487 int row_size, | 493 void TIFF_PredictorEncodeLine(uint8_t* dest_buf, |
488 int BitsPerComponent, | 494 int row_size, |
489 int Colors, | 495 int BitsPerComponent, |
490 int Columns) { | 496 int Colors, |
| 497 int Columns) { |
491 int BytesPerPixel = BitsPerComponent * Colors / 8; | 498 int BytesPerPixel = BitsPerComponent * Colors / 8; |
492 if (BitsPerComponent < 8) { | 499 if (BitsPerComponent < 8) { |
493 uint8_t mask = 0x01; | 500 uint8_t mask = 0x01; |
494 if (BitsPerComponent == 2) { | 501 if (BitsPerComponent == 2) { |
495 mask = 0x03; | 502 mask = 0x03; |
496 } else if (BitsPerComponent == 4) { | 503 } else if (BitsPerComponent == 4) { |
497 mask = 0x0F; | 504 mask = 0x0F; |
498 } | 505 } |
499 int row_bits = Colors * BitsPerComponent * Columns; | 506 int row_bits = Colors * BitsPerComponent * Columns; |
500 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; | 507 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; |
(...skipping 20 matching lines...) Expand all Loading... |
521 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; | 528 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; |
522 i -= BytesPerPixel) { | 529 i -= BytesPerPixel) { |
523 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; | 530 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; |
524 pixel -= | 531 pixel -= |
525 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; | 532 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; |
526 dest_buf[i] = pixel >> 8; | 533 dest_buf[i] = pixel >> 8; |
527 dest_buf[i + 1] = (uint8_t)pixel; | 534 dest_buf[i + 1] = (uint8_t)pixel; |
528 } | 535 } |
529 } | 536 } |
530 } | 537 } |
531 static FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, | 538 |
532 FX_DWORD& data_size, | 539 FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, |
533 int Colors, | 540 FX_DWORD& data_size, |
534 int BitsPerComponent, | 541 int Colors, |
535 int Columns) { | 542 int BitsPerComponent, |
| 543 int Columns) { |
536 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 544 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
537 if (row_size == 0) | 545 if (row_size == 0) |
538 return FALSE; | 546 return FALSE; |
539 const int row_count = (data_size + row_size - 1) / row_size; | 547 const int row_count = (data_size + row_size - 1) / row_size; |
540 const int last_row_size = data_size % row_size; | 548 const int last_row_size = data_size % row_size; |
541 for (int row = 0; row < row_count; row++) { | 549 for (int row = 0; row < row_count; row++) { |
542 uint8_t* scan_line = data_buf + row * row_size; | 550 uint8_t* scan_line = data_buf + row * row_size; |
543 if ((row + 1) * row_size > (int)data_size) { | 551 if ((row + 1) * row_size > (int)data_size) { |
544 row_size = last_row_size; | 552 row_size = last_row_size; |
545 } | 553 } |
546 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, | 554 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, |
547 Columns); | 555 Columns); |
548 } | 556 } |
549 return TRUE; | 557 return TRUE; |
550 } | 558 } |
551 static void TIFF_PredictLine(uint8_t* dest_buf, | 559 |
552 int row_size, | 560 void TIFF_PredictLine(uint8_t* dest_buf, |
553 int BitsPerComponent, | 561 int row_size, |
554 int Colors, | 562 int BitsPerComponent, |
555 int Columns) { | 563 int Colors, |
| 564 int Columns) { |
556 if (BitsPerComponent == 1) { | 565 if (BitsPerComponent == 1) { |
557 int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8); | 566 int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8); |
558 int index_pre = 0; | 567 int index_pre = 0; |
559 int col_pre = 0; | 568 int col_pre = 0; |
560 for (int i = 1; i < row_bits; i++) { | 569 for (int i = 1; i < row_bits; i++) { |
561 int col = i % 8; | 570 int col = i % 8; |
562 int index = i / 8; | 571 int index = i / 8; |
563 if (((dest_buf[index] >> (7 - col)) & 1) ^ | 572 if (((dest_buf[index] >> (7 - col)) & 1) ^ |
564 ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) { | 573 ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) { |
565 dest_buf[index] |= 1 << (7 - col); | 574 dest_buf[index] |= 1 << (7 - col); |
(...skipping 13 matching lines...) Expand all Loading... |
579 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; | 588 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; |
580 dest_buf[i] = pixel >> 8; | 589 dest_buf[i] = pixel >> 8; |
581 dest_buf[i + 1] = (uint8_t)pixel; | 590 dest_buf[i + 1] = (uint8_t)pixel; |
582 } | 591 } |
583 } else { | 592 } else { |
584 for (int i = BytesPerPixel; i < row_size; i++) { | 593 for (int i = BytesPerPixel; i < row_size; i++) { |
585 dest_buf[i] += dest_buf[i - BytesPerPixel]; | 594 dest_buf[i] += dest_buf[i - BytesPerPixel]; |
586 } | 595 } |
587 } | 596 } |
588 } | 597 } |
589 static FX_BOOL TIFF_Predictor(uint8_t*& data_buf, | 598 |
590 FX_DWORD& data_size, | 599 FX_BOOL TIFF_Predictor(uint8_t*& data_buf, |
591 int Colors, | 600 FX_DWORD& data_size, |
592 int BitsPerComponent, | 601 int Colors, |
593 int Columns) { | 602 int BitsPerComponent, |
| 603 int Columns) { |
594 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 604 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
595 if (row_size == 0) | 605 if (row_size == 0) |
596 return FALSE; | 606 return FALSE; |
597 const int row_count = (data_size + row_size - 1) / row_size; | 607 const int row_count = (data_size + row_size - 1) / row_size; |
598 const int last_row_size = data_size % row_size; | 608 const int last_row_size = data_size % row_size; |
599 for (int row = 0; row < row_count; row++) { | 609 for (int row = 0; row < row_count; row++) { |
600 uint8_t* scan_line = data_buf + row * row_size; | 610 uint8_t* scan_line = data_buf + row * row_size; |
601 if ((row + 1) * row_size > (int)data_size) { | 611 if ((row + 1) * row_size > (int)data_size) { |
602 row_size = last_row_size; | 612 row_size = last_row_size; |
603 } | 613 } |
604 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); | 614 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); |
605 } | 615 } |
606 return TRUE; | 616 return TRUE; |
607 } | 617 } |
608 | 618 |
| 619 void FlateUncompress(const uint8_t* src_buf, |
| 620 FX_DWORD src_size, |
| 621 FX_DWORD orig_size, |
| 622 uint8_t*& dest_buf, |
| 623 FX_DWORD& dest_size, |
| 624 FX_DWORD& offset) { |
| 625 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; |
| 626 const FX_DWORD kStepSize = 10240; |
| 627 FX_DWORD alloc_step = orig_size ? kStepSize : std::min(src_size, kStepSize); |
| 628 static const FX_DWORD kMaxInitialAllocSize = 10000000; |
| 629 if (guess_size > kMaxInitialAllocSize) { |
| 630 guess_size = kMaxInitialAllocSize; |
| 631 alloc_step = kMaxInitialAllocSize; |
| 632 } |
| 633 FX_DWORD buf_size = guess_size; |
| 634 FX_DWORD last_buf_size = buf_size; |
| 635 |
| 636 dest_buf = nullptr; |
| 637 dest_size = 0; |
| 638 void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); |
| 639 if (!context) |
| 640 return; |
| 641 |
| 642 nonstd::unique_ptr<uint8_t, FxFreeDeleter> guess_buf( |
| 643 FX_Alloc(uint8_t, guess_size + 1)); |
| 644 guess_buf.get()[guess_size] = '\0'; |
| 645 |
| 646 FPDFAPI_FlateInput(context, src_buf, src_size); |
| 647 |
| 648 if (src_size < kStepSize) { |
| 649 // This is the old implementation. |
| 650 uint8_t* cur_buf = guess_buf.get(); |
| 651 while (1) { |
| 652 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); |
| 653 if (ret != Z_OK) |
| 654 break; |
| 655 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); |
| 656 if (avail_buf_size != 0) |
| 657 break; |
| 658 |
| 659 FX_DWORD old_size = guess_size; |
| 660 guess_size += alloc_step; |
| 661 if (guess_size < old_size || guess_size + 1 < guess_size) { |
| 662 FPDFAPI_FlateEnd(context); |
| 663 return; |
| 664 } |
| 665 |
| 666 { |
| 667 uint8_t* new_buf = |
| 668 FX_Realloc(uint8_t, guess_buf.release(), guess_size + 1); |
| 669 guess_buf.reset(new_buf); |
| 670 } |
| 671 guess_buf.get()[guess_size] = '\0'; |
| 672 cur_buf = guess_buf.get() + old_size; |
| 673 buf_size = guess_size - old_size; |
| 674 } |
| 675 dest_size = FPDFAPI_FlateGetTotalOut(context); |
| 676 offset = FPDFAPI_FlateGetTotalIn(context); |
| 677 if (guess_size / 2 > dest_size) { |
| 678 { |
| 679 uint8_t* new_buf = |
| 680 FX_Realloc(uint8_t, guess_buf.release(), dest_size + 1); |
| 681 guess_buf.reset(new_buf); |
| 682 } |
| 683 guess_size = dest_size; |
| 684 guess_buf.get()[guess_size] = '\0'; |
| 685 } |
| 686 dest_buf = guess_buf.release(); |
| 687 } else { |
| 688 CFX_ArrayTemplate<uint8_t*> result_tmp_bufs; |
| 689 uint8_t* cur_buf = guess_buf.release(); |
| 690 while (1) { |
| 691 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); |
| 692 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); |
| 693 if (ret != Z_OK) { |
| 694 last_buf_size = buf_size - avail_buf_size; |
| 695 result_tmp_bufs.Add(cur_buf); |
| 696 break; |
| 697 } |
| 698 if (avail_buf_size != 0) { |
| 699 last_buf_size = buf_size - avail_buf_size; |
| 700 result_tmp_bufs.Add(cur_buf); |
| 701 break; |
| 702 } |
| 703 |
| 704 result_tmp_bufs.Add(cur_buf); |
| 705 cur_buf = FX_Alloc(uint8_t, buf_size + 1); |
| 706 cur_buf[buf_size] = '\0'; |
| 707 } |
| 708 dest_size = FPDFAPI_FlateGetTotalOut(context); |
| 709 offset = FPDFAPI_FlateGetTotalIn(context); |
| 710 if (result_tmp_bufs.GetSize() == 1) { |
| 711 dest_buf = result_tmp_bufs[0]; |
| 712 } else { |
| 713 uint8_t* result_buf = FX_Alloc(uint8_t, dest_size); |
| 714 FX_DWORD result_pos = 0; |
| 715 for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) { |
| 716 uint8_t* tmp_buf = result_tmp_bufs[i]; |
| 717 FX_DWORD tmp_buf_size = buf_size; |
| 718 if (i == result_tmp_bufs.GetSize() - 1) { |
| 719 tmp_buf_size = last_buf_size; |
| 720 } |
| 721 FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size); |
| 722 result_pos += tmp_buf_size; |
| 723 FX_Free(result_tmp_bufs[i]); |
| 724 } |
| 725 dest_buf = result_buf; |
| 726 } |
| 727 } |
| 728 FPDFAPI_FlateEnd(context); |
| 729 } |
| 730 |
| 731 } // namespace |
| 732 |
609 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { | 733 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { |
610 public: | 734 public: |
611 CCodec_FlateScanlineDecoder(); | 735 CCodec_FlateScanlineDecoder(); |
612 ~CCodec_FlateScanlineDecoder() override; | 736 ~CCodec_FlateScanlineDecoder() override; |
613 | 737 |
614 void Create(const uint8_t* src_buf, | 738 void Create(const uint8_t* src_buf, |
615 FX_DWORD src_size, | 739 FX_DWORD src_size, |
616 int width, | 740 int width, |
617 int height, | 741 int height, |
618 int nComps, | 742 int nComps, |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 } | 878 } |
755 } | 879 } |
756 } else { | 880 } else { |
757 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); | 881 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); |
758 } | 882 } |
759 return m_pScanline; | 883 return m_pScanline; |
760 } | 884 } |
761 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() { | 885 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() { |
762 return FPDFAPI_FlateGetTotalIn(m_pFlate); | 886 return FPDFAPI_FlateGetTotalIn(m_pFlate); |
763 } | 887 } |
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 | 888 |
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) { | |
791 while (1) { | |
792 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); | |
793 if (ret != Z_OK) | |
794 break; | |
795 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | |
796 if (avail_buf_size != 0) | |
797 break; | |
798 | |
799 // |avail_buf_size| == 0 case. | |
800 FX_DWORD old_size = guess_size; | |
801 guess_size += alloc_step; | |
802 if (guess_size < old_size || guess_size + 1 < guess_size) | |
803 goto fail; | |
804 guess_buf = FX_Realloc(uint8_t, guess_buf, guess_size + 1); | |
805 if (!guess_buf) | |
806 goto fail; | |
807 guess_buf[guess_size] = '\0'; | |
808 cur_buf = guess_buf + old_size; | |
809 buf_size = guess_size - old_size; | |
810 } | |
811 dest_size = FPDFAPI_FlateGetTotalOut(context); | |
812 offset = FPDFAPI_FlateGetTotalIn(context); | |
813 if (guess_size / 2 > dest_size) { | |
814 guess_buf = FX_Realloc(uint8_t, guess_buf, dest_size + 1); | |
815 if (!guess_buf) | |
816 goto fail; | |
817 guess_size = dest_size; | |
818 guess_buf[guess_size] = '\0'; | |
819 } | |
820 dest_buf = guess_buf; | |
821 } else { | |
822 CFX_ArrayTemplate<uint8_t*> result_tmp_bufs; | |
823 while (1) { | |
824 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); | |
825 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | |
826 if (ret != Z_OK) { | |
827 last_buf_size = buf_size - avail_buf_size; | |
828 result_tmp_bufs.Add(cur_buf); | |
829 break; | |
830 } | |
831 if (avail_buf_size != 0) { | |
832 last_buf_size = buf_size - avail_buf_size; | |
833 result_tmp_bufs.Add(cur_buf); | |
834 break; | |
835 } | |
836 | |
837 // |avail_buf_size| == 0 case. | |
838 result_tmp_bufs.Add(cur_buf); | |
839 cur_buf = FX_Alloc(uint8_t, buf_size + 1); | |
840 cur_buf[buf_size] = '\0'; | |
841 } | |
842 dest_size = FPDFAPI_FlateGetTotalOut(context); | |
843 offset = FPDFAPI_FlateGetTotalIn(context); | |
844 if (result_tmp_bufs.GetSize() == 1) { | |
845 dest_buf = result_tmp_bufs[0]; | |
846 } else { | |
847 uint8_t* result_buf = FX_Alloc(uint8_t, dest_size); | |
848 FX_DWORD result_pos = 0; | |
849 for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) { | |
850 uint8_t* tmp_buf = result_tmp_bufs[i]; | |
851 FX_DWORD tmp_buf_size = buf_size; | |
852 if (i == result_tmp_bufs.GetSize() - 1) { | |
853 tmp_buf_size = last_buf_size; | |
854 } | |
855 FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size); | |
856 result_pos += tmp_buf_size; | |
857 FX_Free(result_tmp_bufs[i]); | |
858 } | |
859 dest_buf = result_buf; | |
860 } | |
861 } | |
862 FPDFAPI_FlateEnd(context); | |
863 return; | |
864 | |
865 fail: | |
866 FX_Free(guess_buf); | |
867 dest_buf = nullptr; | |
868 dest_size = 0; | |
869 return; | |
870 } | |
871 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder( | 889 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder( |
872 const uint8_t* src_buf, | 890 const uint8_t* src_buf, |
873 FX_DWORD src_size, | 891 FX_DWORD src_size, |
874 int width, | 892 int width, |
875 int height, | 893 int height, |
876 int nComps, | 894 int nComps, |
877 int bpc, | 895 int bpc, |
878 int predictor, | 896 int predictor, |
879 int Colors, | 897 int Colors, |
880 int BitsPerComponent, | 898 int BitsPerComponent, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 FX_DWORD src_size, | 986 FX_DWORD src_size, |
969 uint8_t*& dest_buf, | 987 uint8_t*& dest_buf, |
970 FX_DWORD& dest_size) { | 988 FX_DWORD& dest_size) { |
971 dest_size = src_size + src_size / 1000 + 12; | 989 dest_size = src_size + src_size / 1000 + 12; |
972 dest_buf = FX_Alloc(uint8_t, dest_size); | 990 dest_buf = FX_Alloc(uint8_t, dest_size); |
973 unsigned long temp_size = dest_size; | 991 unsigned long temp_size = dest_size; |
974 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); | 992 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); |
975 dest_size = (FX_DWORD)temp_size; | 993 dest_size = (FX_DWORD)temp_size; |
976 return TRUE; | 994 return TRUE; |
977 } | 995 } |
OLD | NEW |