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 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |