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

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
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 const int last_row_size = data_size % (row_size + 1); 409 const int last_row_size = data_size % (row_size + 1);
404 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); 410 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count);
405 int byte_cnt = 0; 411 int byte_cnt = 0;
406 uint8_t* pSrcData = data_buf; 412 uint8_t* pSrcData = data_buf;
407 uint8_t* pDestData = dest_buf; 413 uint8_t* pDestData = dest_buf;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 } 480 }
475 pSrcData += row_size + 1; 481 pSrcData += row_size + 1;
476 pDestData += row_size; 482 pDestData += row_size;
477 } 483 }
478 FX_Free(data_buf); 484 FX_Free(data_buf);
479 data_buf = dest_buf; 485 data_buf = dest_buf;
480 data_size = row_size * row_count - 486 data_size = row_size * row_count -
481 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); 487 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0);
482 return TRUE; 488 return TRUE;
483 } 489 }
484 static void TIFF_PredictorEncodeLine(uint8_t* dest_buf, 490
485 int row_size, 491 void TIFF_PredictorEncodeLine(uint8_t* dest_buf,
486 int BitsPerComponent, 492 int row_size,
487 int Colors, 493 int BitsPerComponent,
488 int Columns) { 494 int Colors,
495 int Columns) {
489 int BytesPerPixel = BitsPerComponent * Colors / 8; 496 int BytesPerPixel = BitsPerComponent * Colors / 8;
490 if (BitsPerComponent < 8) { 497 if (BitsPerComponent < 8) {
491 uint8_t mask = 0x01; 498 uint8_t mask = 0x01;
492 if (BitsPerComponent == 2) { 499 if (BitsPerComponent == 2) {
493 mask = 0x03; 500 mask = 0x03;
494 } else if (BitsPerComponent == 4) { 501 } else if (BitsPerComponent == 4) {
495 mask = 0x0F; 502 mask = 0x0F;
496 } 503 }
497 int row_bits = Colors * BitsPerComponent * Columns; 504 int row_bits = Colors * BitsPerComponent * Columns;
498 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; 505 for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent;
(...skipping 20 matching lines...) Expand all
519 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; 526 for (int i = row_size - BytesPerPixel; i >= BytesPerPixel;
520 i -= BytesPerPixel) { 527 i -= BytesPerPixel) {
521 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; 528 FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1];
522 pixel -= 529 pixel -=
523 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; 530 (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1];
524 dest_buf[i] = pixel >> 8; 531 dest_buf[i] = pixel >> 8;
525 dest_buf[i + 1] = (uint8_t)pixel; 532 dest_buf[i + 1] = (uint8_t)pixel;
526 } 533 }
527 } 534 }
528 } 535 }
529 static FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, 536
530 FX_DWORD& data_size, 537 FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf,
531 int Colors, 538 FX_DWORD& data_size,
532 int BitsPerComponent, 539 int Colors,
533 int Columns) { 540 int BitsPerComponent,
541 int Columns) {
534 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; 542 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
535 if (row_size == 0) 543 if (row_size == 0)
536 return FALSE; 544 return FALSE;
537 const int row_count = (data_size + row_size - 1) / row_size; 545 const int row_count = (data_size + row_size - 1) / row_size;
538 const int last_row_size = data_size % row_size; 546 const int last_row_size = data_size % row_size;
539 for (int row = 0; row < row_count; row++) { 547 for (int row = 0; row < row_count; row++) {
540 uint8_t* scan_line = data_buf + row * row_size; 548 uint8_t* scan_line = data_buf + row * row_size;
541 if ((row + 1) * row_size > (int)data_size) { 549 if ((row + 1) * row_size > (int)data_size) {
542 row_size = last_row_size; 550 row_size = last_row_size;
543 } 551 }
544 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, 552 TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors,
545 Columns); 553 Columns);
546 } 554 }
547 return TRUE; 555 return TRUE;
548 } 556 }
549 static void TIFF_PredictLine(uint8_t* dest_buf, 557
550 int row_size, 558 void TIFF_PredictLine(uint8_t* dest_buf,
551 int BitsPerComponent, 559 int row_size,
552 int Colors, 560 int BitsPerComponent,
553 int Columns) { 561 int Colors,
562 int Columns) {
554 if (BitsPerComponent == 1) { 563 if (BitsPerComponent == 1) {
555 int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8); 564 int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8);
556 int index_pre = 0; 565 int index_pre = 0;
557 int col_pre = 0; 566 int col_pre = 0;
558 for (int i = 1; i < row_bits; i++) { 567 for (int i = 1; i < row_bits; i++) {
559 int col = i % 8; 568 int col = i % 8;
560 int index = i / 8; 569 int index = i / 8;
561 if (((dest_buf[index] >> (7 - col)) & 1) ^ 570 if (((dest_buf[index] >> (7 - col)) & 1) ^
562 ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) { 571 ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) {
563 dest_buf[index] |= 1 << (7 - col); 572 dest_buf[index] |= 1 << (7 - col);
(...skipping 13 matching lines...) Expand all
577 pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; 586 pixel += (dest_buf[i] << 8) | dest_buf[i + 1];
578 dest_buf[i] = pixel >> 8; 587 dest_buf[i] = pixel >> 8;
579 dest_buf[i + 1] = (uint8_t)pixel; 588 dest_buf[i + 1] = (uint8_t)pixel;
580 } 589 }
581 } else { 590 } else {
582 for (int i = BytesPerPixel; i < row_size; i++) { 591 for (int i = BytesPerPixel; i < row_size; i++) {
583 dest_buf[i] += dest_buf[i - BytesPerPixel]; 592 dest_buf[i] += dest_buf[i - BytesPerPixel];
584 } 593 }
585 } 594 }
586 } 595 }
587 static FX_BOOL TIFF_Predictor(uint8_t*& data_buf, 596
588 FX_DWORD& data_size, 597 FX_BOOL TIFF_Predictor(uint8_t*& data_buf,
589 int Colors, 598 FX_DWORD& data_size,
590 int BitsPerComponent, 599 int Colors,
591 int Columns) { 600 int BitsPerComponent,
601 int Columns) {
592 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; 602 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
593 if (row_size == 0) 603 if (row_size == 0)
594 return FALSE; 604 return FALSE;
595 const int row_count = (data_size + row_size - 1) / row_size; 605 const int row_count = (data_size + row_size - 1) / row_size;
596 const int last_row_size = data_size % row_size; 606 const int last_row_size = data_size % row_size;
597 for (int row = 0; row < row_count; row++) { 607 for (int row = 0; row < row_count; row++) {
598 uint8_t* scan_line = data_buf + row * row_size; 608 uint8_t* scan_line = data_buf + row * row_size;
599 if ((row + 1) * row_size > (int)data_size) { 609 if ((row + 1) * row_size > (int)data_size) {
600 row_size = last_row_size; 610 row_size = last_row_size;
601 } 611 }
602 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); 612 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns);
603 } 613 }
604 return TRUE; 614 return TRUE;
605 } 615 }
606 616
617 void FlateUncompress(const uint8_t* src_buf,
Lei Zhang 2015/09/23 19:22:28 A bit harder to see what I changed since I moved t
618 FX_DWORD src_size,
619 FX_DWORD orig_size,
620 uint8_t*& dest_buf,
621 FX_DWORD& dest_size,
622 FX_DWORD& offset) {
623 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2;
624 FX_DWORD alloc_step =
625 orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size);
Tom Sepez 2015/09/23 21:48:41 nit: maybe std::min(src_size, 10240) maybe a const
Lei Zhang 2015/09/25 09:33:49 Done.
626 static const FX_DWORD kMaxInitialAllocSize = 10000000;
627 if (guess_size > kMaxInitialAllocSize) {
628 guess_size = kMaxInitialAllocSize;
629 alloc_step = kMaxInitialAllocSize;
630 }
631 FX_DWORD buf_size = guess_size;
632 FX_DWORD last_buf_size = buf_size;
633
634 void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
635 if (!context) {
636 dest_buf = nullptr;
Tom Sepez 2015/09/23 21:48:41 how about we set these to null/0 initially, and th
Lei Zhang 2015/09/25 09:33:48 Done.
637 dest_size = 0;
638 return;
639 }
640
641 nonstd::unique_ptr<uint8_t, FxFreeDeleter> guess_buf(
642 FX_Alloc(uint8_t, guess_size + 1));
643 guess_buf.get()[guess_size] = '\0';
Tom Sepez 2015/09/23 21:48:41 The real std::unique_ptr has operator[]. do we wan
Lei Zhang 2015/09/25 09:33:48 There's no new equivalent to FX_Realloc(), right?
Tom Sepez 2015/09/25 16:25:34 ah.
644
645 FPDFAPI_FlateInput(context, src_buf, src_size);
646
647 if (src_size < 10240) {
648 // This is the old implementation.
649 uint8_t* cur_buf = guess_buf.get();
650 while (1) {
651 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
652 if (ret != Z_OK)
653 break;
654 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
655 if (avail_buf_size != 0)
656 break;
657
658 // |avail_buf_size| == 0 case.
Tom Sepez 2015/09/23 21:48:41 nit: not sure this comment adds value.
Lei Zhang 2015/09/25 09:33:48 Done.
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 dest_buf = nullptr;
664 dest_size = 0;
665 return;
666 }
667
668 {
669 uint8_t* new_buf =
670 FX_Realloc(uint8_t, guess_buf.release(), guess_size + 1);
671 guess_buf.reset(new_buf);
Tom Sepez 2015/09/23 21:48:41 nit: how about guess_buf.reset(FX_Realloc(...)); a
Lei Zhang 2015/09/25 09:33:48 No, we get in trouble doing guess_buf.reset() and
Tom Sepez 2015/09/25 16:25:34 Acknowledged.
672 }
673 guess_buf.get()[guess_size] = '\0';
674 cur_buf = guess_buf.get() + old_size;
675 buf_size = guess_size - old_size;
676 }
677 dest_size = FPDFAPI_FlateGetTotalOut(context);
678 offset = FPDFAPI_FlateGetTotalIn(context);
679 if (guess_size / 2 > dest_size) {
680 {
681 uint8_t* new_buf =
Tom Sepez 2015/09/23 21:48:41 ditto
Lei Zhang 2015/09/25 09:33:48 Acknowledged.
682 FX_Realloc(uint8_t, guess_buf.release(), dest_size + 1);
683 guess_buf.reset(new_buf);
684 }
685 guess_size = dest_size;
686 guess_buf.get()[guess_size] = '\0';
687 }
688 dest_buf = guess_buf.release();
689 } else {
690 CFX_ArrayTemplate<uint8_t*> result_tmp_bufs;
691 uint8_t* cur_buf = guess_buf.release();
692 while (1) {
693 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
694 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
695 if (ret != Z_OK) {
696 last_buf_size = buf_size - avail_buf_size;
697 result_tmp_bufs.Add(cur_buf);
698 break;
699 }
700 if (avail_buf_size != 0) {
701 last_buf_size = buf_size - avail_buf_size;
702 result_tmp_bufs.Add(cur_buf);
703 break;
704 }
705
706 // |avail_buf_size| == 0 case.
Tom Sepez 2015/09/23 21:48:41 ditto
Lei Zhang 2015/09/25 09:33:48 Done.
707 result_tmp_bufs.Add(cur_buf);
708 cur_buf = FX_Alloc(uint8_t, buf_size + 1);
709 cur_buf[buf_size] = '\0';
710 }
711 dest_size = FPDFAPI_FlateGetTotalOut(context);
712 offset = FPDFAPI_FlateGetTotalIn(context);
713 if (result_tmp_bufs.GetSize() == 1) {
714 dest_buf = result_tmp_bufs[0];
715 } else {
716 uint8_t* result_buf = FX_Alloc(uint8_t, dest_size);
717 FX_DWORD result_pos = 0;
718 for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) {
719 uint8_t* tmp_buf = result_tmp_bufs[i];
720 FX_DWORD tmp_buf_size = buf_size;
721 if (i == result_tmp_bufs.GetSize() - 1) {
722 tmp_buf_size = last_buf_size;
723 }
724 FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size);
725 result_pos += tmp_buf_size;
726 FX_Free(result_tmp_bufs[i]);
727 }
728 dest_buf = result_buf;
729 }
730 }
731 FPDFAPI_FlateEnd(context);
732 }
733
734 } // namespace
735
607 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { 736 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder {
608 public: 737 public:
609 CCodec_FlateScanlineDecoder(); 738 CCodec_FlateScanlineDecoder();
610 ~CCodec_FlateScanlineDecoder() override; 739 ~CCodec_FlateScanlineDecoder() override;
611 740
612 void Create(const uint8_t* src_buf, 741 void Create(const uint8_t* src_buf,
613 FX_DWORD src_size, 742 FX_DWORD src_size,
614 int width, 743 int width,
615 int height, 744 int height,
616 int nComps, 745 int nComps,
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 } 881 }
753 } 882 }
754 } else { 883 } else {
755 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); 884 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch);
756 } 885 }
757 return m_pScanline; 886 return m_pScanline;
758 } 887 }
759 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() { 888 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() {
760 return FPDFAPI_FlateGetTotalIn(m_pFlate); 889 return FPDFAPI_FlateGetTotalIn(m_pFlate);
761 } 890 }
762 static void FlateUncompress(const uint8_t* src_buf,
763 FX_DWORD src_size,
764 FX_DWORD orig_size,
765 uint8_t*& dest_buf,
766 FX_DWORD& dest_size,
767 FX_DWORD& offset) {
768 const FX_BOOL useOldImpl = src_size < 10240;
769 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2;
770 FX_DWORD alloc_step =
771 orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size);
772 static const FX_DWORD kMaxInitialAllocSize = 10000000;
773 if (guess_size > kMaxInitialAllocSize) {
774 guess_size = kMaxInitialAllocSize;
775 alloc_step = kMaxInitialAllocSize;
776 }
777 FX_DWORD buf_size = guess_size;
778 FX_DWORD last_buf_size = buf_size;
779 void* context = nullptr;
780 891
781 uint8_t* guess_buf = FX_Alloc(uint8_t, guess_size + 1);
782 uint8_t* cur_buf = guess_buf;
783 guess_buf[guess_size] = '\0';
784 context = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
785 if (!context)
786 goto fail;
787 FPDFAPI_FlateInput(context, src_buf, src_size);
788 if (useOldImpl) {
789 while (1) {
790 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
791 if (ret != Z_OK)
792 break;
793 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
794 if (avail_buf_size != 0)
795 break;
796
797 // |avail_buf_size| == 0 case.
798 FX_DWORD old_size = guess_size;
799 guess_size += alloc_step;
800 if (guess_size < old_size || guess_size + 1 < guess_size)
801 goto fail;
802 guess_buf = FX_Realloc(uint8_t, guess_buf, guess_size + 1);
803 if (!guess_buf)
804 goto fail;
805 guess_buf[guess_size] = '\0';
806 cur_buf = guess_buf + old_size;
807 buf_size = guess_size - old_size;
808 }
809 dest_size = FPDFAPI_FlateGetTotalOut(context);
810 offset = FPDFAPI_FlateGetTotalIn(context);
811 if (guess_size / 2 > dest_size) {
812 guess_buf = FX_Realloc(uint8_t, guess_buf, dest_size + 1);
813 if (!guess_buf)
814 goto fail;
815 guess_size = dest_size;
816 guess_buf[guess_size] = '\0';
817 }
818 dest_buf = guess_buf;
819 } else {
820 CFX_ArrayTemplate<uint8_t*> result_tmp_bufs;
821 while (1) {
822 int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
823 int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
824 if (ret != Z_OK) {
825 last_buf_size = buf_size - avail_buf_size;
826 result_tmp_bufs.Add(cur_buf);
827 break;
828 }
829 if (avail_buf_size != 0) {
830 last_buf_size = buf_size - avail_buf_size;
831 result_tmp_bufs.Add(cur_buf);
832 break;
833 }
834
835 // |avail_buf_size| == 0 case.
836 result_tmp_bufs.Add(cur_buf);
837 cur_buf = FX_Alloc(uint8_t, buf_size + 1);
838 cur_buf[buf_size] = '\0';
839 }
840 dest_size = FPDFAPI_FlateGetTotalOut(context);
841 offset = FPDFAPI_FlateGetTotalIn(context);
842 if (result_tmp_bufs.GetSize() == 1) {
843 dest_buf = result_tmp_bufs[0];
844 } else {
845 uint8_t* result_buf = FX_Alloc(uint8_t, dest_size);
846 FX_DWORD result_pos = 0;
847 for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) {
848 uint8_t* tmp_buf = result_tmp_bufs[i];
849 FX_DWORD tmp_buf_size = buf_size;
850 if (i == result_tmp_bufs.GetSize() - 1) {
851 tmp_buf_size = last_buf_size;
852 }
853 FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size);
854 result_pos += tmp_buf_size;
855 FX_Free(result_tmp_bufs[i]);
856 }
857 dest_buf = result_buf;
858 }
859 }
860 FPDFAPI_FlateEnd(context);
861 return;
862
863 fail:
864 FX_Free(guess_buf);
865 dest_buf = nullptr;
866 dest_size = 0;
867 return;
868 }
869 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder( 892 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder(
870 const uint8_t* src_buf, 893 const uint8_t* src_buf,
871 FX_DWORD src_size, 894 FX_DWORD src_size,
872 int width, 895 int width,
873 int height, 896 int height,
874 int nComps, 897 int nComps,
875 int bpc, 898 int bpc,
876 int predictor, 899 int predictor,
877 int Colors, 900 int Colors,
878 int BitsPerComponent, 901 int BitsPerComponent,
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 FX_DWORD src_size, 989 FX_DWORD src_size,
967 uint8_t*& dest_buf, 990 uint8_t*& dest_buf,
968 FX_DWORD& dest_size) { 991 FX_DWORD& dest_size) {
969 dest_size = src_size + src_size / 1000 + 12; 992 dest_size = src_size + src_size / 1000 + 12;
970 dest_buf = FX_Alloc(uint8_t, dest_size); 993 dest_buf = FX_Alloc(uint8_t, dest_size);
971 unsigned long temp_size = dest_size; 994 unsigned long temp_size = dest_size;
972 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); 995 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size);
973 dest_size = (FX_DWORD)temp_size; 996 dest_size = (FX_DWORD)temp_size;
974 return TRUE; 997 return TRUE;
975 } 998 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698