Chromium Code Reviews| 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 "../../../include/fxcodec/fx_codec.h" | 8 #include "../../../include/fxcodec/fx_codec.h" |
| 9 #include "../../fx_zlib.h" | 9 #include "../../fx_zlib.h" |
| 10 #include "codec_int.h" | 10 #include "codec_int.h" |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 735 } | 735 } |
| 736 return m_pScanline; | 736 return m_pScanline; |
| 737 } | 737 } |
| 738 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() | 738 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() |
| 739 { | 739 { |
| 740 return FPDFAPI_FlateGetTotalIn(m_pFlate); | 740 return FPDFAPI_FlateGetTotalIn(m_pFlate); |
| 741 } | 741 } |
| 742 static void FlateUncompress(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_DWORD orig _size, | 742 static void FlateUncompress(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_DWORD orig _size, |
| 743 FX_LPBYTE& dest_buf, FX_DWORD& dest_size, FX_DWORD& offset) | 743 FX_LPBYTE& dest_buf, FX_DWORD& dest_size, FX_DWORD& offset) |
| 744 { | 744 { |
| 745 const FX_BOOL useOldImpl = src_size < 10240; | |
| 745 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; | 746 FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; |
| 746 FX_DWORD alloc_step = orig_size ? 10240 : (src_size < 10240 ? 10240 : src_si ze); | 747 FX_DWORD alloc_step = orig_size ? 10240 : (src_size < 10240 ? 10240 : src_si ze); |
| 747 static const FX_DWORD kMaxInitialAllocSize = 10000000; | 748 static const FX_DWORD kMaxInitialAllocSize = 10000000; |
| 748 if (guess_size > kMaxInitialAllocSize) { | 749 if (guess_size > kMaxInitialAllocSize) { |
| 749 guess_size = kMaxInitialAllocSize; | 750 guess_size = kMaxInitialAllocSize; |
| 750 alloc_step = kMaxInitialAllocSize; | 751 alloc_step = kMaxInitialAllocSize; |
| 751 } | 752 } |
| 752 FX_LPBYTE guess_buf = FX_Alloc(FX_BYTE, guess_size + 1); | |
| 753 if (!guess_buf) { | |
| 754 dest_buf = NULL; | |
| 755 dest_size = 0; | |
| 756 return; | |
| 757 } | |
| 758 guess_buf[guess_size] = '\0'; | |
| 759 FX_BOOL useOldImpl = src_size < 10240; | |
| 760 void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); | |
| 761 if (context == NULL) { | |
| 762 dest_buf = NULL; | |
| 763 dest_size = 0; | |
| 764 return ; | |
| 765 } | |
| 766 FPDFAPI_FlateInput(context, src_buf, src_size); | |
| 767 CFX_ArrayTemplate<FX_LPBYTE> result_tmp_bufs; | |
| 768 FX_LPBYTE buf = guess_buf; | |
| 769 FX_DWORD buf_size = guess_size; | 753 FX_DWORD buf_size = guess_size; |
| 770 FX_DWORD last_buf_size = buf_size; | 754 FX_DWORD last_buf_size = buf_size; |
| 771 while (1) { | 755 void* context = nullptr; |
| 772 FX_INT32 ret = FPDFAPI_FlateOutput(context, buf, buf_size); | 756 |
| 773 FX_INT32 avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | 757 FX_LPBYTE guess_buf = FX_Alloc(FX_BYTE, guess_size + 1); |
| 774 if (!useOldImpl) { | 758 FX_LPBYTE cur_buf = guess_buf; |
| 759 if (!guess_buf) | |
|
Tom Sepez
2015/05/15 15:23:38
nit: I'd expect this one line earlier, with line 7
Lei Zhang
2015/05/15 22:29:49
Compiler says, "crosses initialization of ‘unsigne
| |
| 760 goto fail; | |
| 761 guess_buf[guess_size] = '\0'; | |
| 762 context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); | |
| 763 if (!context) | |
| 764 goto fail; | |
| 765 FPDFAPI_FlateInput(context, src_buf, src_size); | |
| 766 if (useOldImpl) { | |
|
Lei Zhang
2015/05/15 06:46:46
I took the original code and make 2 copies, then r
| |
| 767 while (1) { | |
| 768 FX_INT32 ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); | |
| 769 if (ret != Z_OK) | |
| 770 break; | |
| 771 FX_INT32 avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | |
| 772 if (avail_buf_size != 0) | |
| 773 break; | |
| 774 | |
| 775 // |avail_buf_size| == 0 case. | |
| 776 FX_DWORD old_size = guess_size; | |
| 777 guess_size += alloc_step; | |
| 778 if (guess_size < old_size || guess_size + 1 < guess_size) | |
| 779 goto fail; | |
| 780 guess_buf = FX_Realloc(FX_BYTE, guess_buf, guess_size + 1); | |
| 781 if (!guess_buf) | |
| 782 goto fail; | |
| 783 guess_buf[guess_size] = '\0'; | |
| 784 cur_buf = guess_buf + old_size; | |
| 785 buf_size = guess_size - old_size; | |
| 786 } | |
| 787 dest_size = FPDFAPI_FlateGetTotalOut(context); | |
| 788 offset = FPDFAPI_FlateGetTotalIn(context); | |
| 789 if (guess_size / 2 > dest_size) { | |
| 790 guess_buf = FX_Realloc(FX_BYTE, guess_buf, dest_size + 1); | |
| 791 if (!guess_buf) | |
| 792 goto fail; | |
| 793 guess_size = dest_size; | |
| 794 guess_buf[guess_size] = '\0'; | |
| 795 } | |
| 796 dest_buf = guess_buf; | |
| 797 } else { | |
| 798 CFX_ArrayTemplate<FX_LPBYTE> result_tmp_bufs; | |
| 799 while (1) { | |
| 800 FX_INT32 ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); | |
| 801 FX_INT32 avail_buf_size = FPDFAPI_FlateGetAvailOut(context); | |
| 775 if (ret != Z_OK) { | 802 if (ret != Z_OK) { |
|
Tom Sepez
2015/05/15 15:23:38
check for error before FlateGetAvailOut? as in lin
Lei Zhang
2015/05/15 22:29:49
The error handling code uses |avail_buf_size|, so
| |
| 776 last_buf_size = buf_size - avail_buf_size; | 803 last_buf_size = buf_size - avail_buf_size; |
| 777 result_tmp_bufs.Add(buf); | 804 result_tmp_bufs.Add(cur_buf); |
| 778 break; | 805 break; |
| 779 } | 806 } |
| 780 if (avail_buf_size == 0) { | 807 if (avail_buf_size != 0) { |
| 781 result_tmp_bufs.Add(buf); | |
| 782 buf = NULL; | |
| 783 buf = FX_Alloc(FX_BYTE, buf_size + 1); | |
| 784 if (!buf) { | |
| 785 dest_buf = NULL; | |
| 786 dest_size = 0; | |
| 787 return; | |
| 788 } | |
| 789 buf[buf_size] = '\0'; | |
| 790 } else { | |
| 791 last_buf_size = buf_size - avail_buf_size; | 808 last_buf_size = buf_size - avail_buf_size; |
| 792 result_tmp_bufs.Add(buf); | 809 result_tmp_bufs.Add(cur_buf); |
| 793 buf = NULL; | |
| 794 break; | 810 break; |
| 795 } | 811 } |
| 796 } else { | 812 |
| 797 if (ret != Z_OK) { | 813 // |avail_buf_size| == 0 case. |
| 798 break; | 814 result_tmp_bufs.Add(cur_buf); |
| 815 cur_buf = FX_Alloc(FX_BYTE, buf_size + 1); | |
| 816 if (!cur_buf) { | |
| 817 for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) | |
|
Tom Sepez
2015/05/15 15:23:38
nit: would like { } despite the one-line body. I
Lei Zhang
2015/05/15 22:29:48
Done.
| |
| 818 FX_Free(result_tmp_bufs[i]); | |
| 819 goto fail; | |
| 799 } | 820 } |
| 800 if (avail_buf_size == 0) { | 821 cur_buf[buf_size] = '\0'; |
| 801 FX_DWORD old_size = guess_size; | |
| 802 guess_size += alloc_step; | |
| 803 if (guess_size < old_size || guess_size + 1 < guess_size) { | |
| 804 dest_buf = NULL; | |
| 805 dest_size = 0; | |
| 806 return; | |
| 807 } | |
| 808 guess_buf = FX_Realloc(FX_BYTE, guess_buf, guess_size + 1); | |
| 809 if (!guess_buf) { | |
| 810 dest_buf = NULL; | |
| 811 dest_size = 0; | |
| 812 return; | |
| 813 } | |
| 814 guess_buf[guess_size] = '\0'; | |
| 815 buf = guess_buf + old_size; | |
| 816 buf_size = guess_size - old_size; | |
| 817 } else { | |
| 818 break; | |
| 819 } | |
| 820 } | 822 } |
| 821 } | 823 dest_size = FPDFAPI_FlateGetTotalOut(context); |
| 822 dest_size = FPDFAPI_FlateGetTotalOut(context); | 824 offset = FPDFAPI_FlateGetTotalIn(context); |
| 823 offset = FPDFAPI_FlateGetTotalIn(context); | |
| 824 if (!useOldImpl) { | |
| 825 if (result_tmp_bufs.GetSize() == 1) { | 825 if (result_tmp_bufs.GetSize() == 1) { |
| 826 dest_buf = result_tmp_bufs[0]; | 826 dest_buf = result_tmp_bufs[0]; |
| 827 } else { | 827 } else { |
| 828 FX_LPBYTE result_buf = FX_Alloc(FX_BYTE, dest_size); | 828 FX_LPBYTE result_buf = FX_Alloc(FX_BYTE, dest_size); |
| 829 if (!result_buf) { | 829 if (!result_buf) { |
| 830 dest_buf = NULL; | 830 for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) |
|
Tom Sepez
2015/05/15 15:23:38
ditto
Lei Zhang
2015/05/15 22:29:48
Done.
| |
| 831 dest_size = 0; | 831 FX_Free(result_tmp_bufs[i]); |
| 832 return; | 832 goto fail; |
| 833 } | 833 } |
| 834 FX_DWORD result_pos = 0; | 834 FX_DWORD result_pos = 0; |
| 835 for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { | 835 for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { |
| 836 FX_LPBYTE tmp_buf = result_tmp_bufs[i]; | 836 FX_LPBYTE tmp_buf = result_tmp_bufs[i]; |
| 837 FX_DWORD tmp_buf_size = buf_size; | 837 FX_DWORD tmp_buf_size = buf_size; |
| 838 if (i == result_tmp_bufs.GetSize() - 1) { | 838 if (i == result_tmp_bufs.GetSize() - 1) { |
| 839 tmp_buf_size = last_buf_size; | 839 tmp_buf_size = last_buf_size; |
| 840 } | 840 } |
| 841 FXSYS_memcpy32(result_buf + result_pos, tmp_buf, tmp_buf_size); | 841 FXSYS_memcpy32(result_buf + result_pos, tmp_buf, tmp_buf_size); |
| 842 result_pos += tmp_buf_size; | 842 result_pos += tmp_buf_size; |
| 843 FX_Free(tmp_buf); | 843 FX_Free(result_tmp_bufs[i]); |
| 844 tmp_buf = NULL; | |
| 845 result_tmp_bufs[i] = NULL; | |
| 846 } | 844 } |
| 847 dest_buf = result_buf; | 845 dest_buf = result_buf; |
| 848 } | 846 } |
| 849 } else { | |
| 850 if (guess_size / 2 > dest_size) { | |
| 851 guess_buf = FX_Realloc(FX_BYTE, guess_buf, dest_size + 1); | |
| 852 if (!guess_buf) { | |
| 853 dest_buf = NULL; | |
| 854 dest_size = 0; | |
| 855 return; | |
| 856 } | |
| 857 guess_size = dest_size; | |
| 858 guess_buf[guess_size] = '\0'; | |
| 859 } | |
| 860 dest_buf = guess_buf; | |
| 861 } | 847 } |
| 862 FPDFAPI_FlateEnd(context); | 848 FPDFAPI_FlateEnd(context); |
| 863 context = NULL; | 849 return; |
| 850 | |
| 851 fail: | |
| 852 FX_Free(guess_buf); | |
| 853 dest_buf = nullptr; | |
| 854 dest_size = 0; | |
| 855 return; | |
| 864 } | 856 } |
| 865 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder(FX_LPCBYTE src_buf, FX _DWORD src_size, int width, int height, | 857 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder(FX_LPCBYTE src_buf, FX _DWORD src_size, int width, int height, |
| 866 int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, in t Columns) | 858 int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, in t Columns) |
| 867 { | 859 { |
| 868 CCodec_FlateScanlineDecoder* pDecoder = new CCodec_FlateScanlineDecoder; | 860 CCodec_FlateScanlineDecoder* pDecoder = new CCodec_FlateScanlineDecoder; |
| 869 pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, C olors, BitsPerComponent, Columns); | 861 pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, C olors, BitsPerComponent, Columns); |
| 870 return pDecoder; | 862 return pDecoder; |
| 871 } | 863 } |
| 872 FX_DWORD CCodec_FlateModule::FlateOrLZWDecode(FX_BOOL bLZW, const FX_BYTE* src_b uf, FX_DWORD src_size, FX_BOOL bEarlyChange, | 864 FX_DWORD CCodec_FlateModule::FlateOrLZWDecode(FX_BOOL bLZW, const FX_BYTE* src_b uf, FX_DWORD src_size, FX_BOOL bEarlyChange, |
| 873 int predictor, int Colors, int BitsPerComponent, int Columns, | 865 int predictor, int Colors, int BitsPerComponent, int Columns, |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 950 dest_size = src_size + src_size / 1000 + 12; | 942 dest_size = src_size + src_size / 1000 + 12; |
| 951 dest_buf = FX_Alloc( FX_BYTE, dest_size); | 943 dest_buf = FX_Alloc( FX_BYTE, dest_size); |
| 952 if (dest_buf == NULL) { | 944 if (dest_buf == NULL) { |
| 953 return FALSE; | 945 return FALSE; |
| 954 } | 946 } |
| 955 unsigned long temp_size = dest_size; | 947 unsigned long temp_size = dest_size; |
| 956 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); | 948 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); |
| 957 dest_size = (FX_DWORD)temp_size; | 949 dest_size = (FX_DWORD)temp_size; |
| 958 return TRUE; | 950 return TRUE; |
| 959 } | 951 } |
| OLD | NEW |