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

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

Issue 1360103002: Get rid of gotos in CPDF_SyntaxParser and FlateUncompress(). (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: Created 5 years, 2 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
« no previous file with comments | « core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698