| 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) |
| 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) { |
| 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) { |
| 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++) { |
| 818 FX_Free(result_tmp_bufs[i]); |
| 819 } |
| 820 goto fail; |
| 799 } | 821 } |
| 800 if (avail_buf_size == 0) { | 822 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 } | 823 } |
| 821 } | 824 dest_size = FPDFAPI_FlateGetTotalOut(context); |
| 822 dest_size = FPDFAPI_FlateGetTotalOut(context); | 825 offset = FPDFAPI_FlateGetTotalIn(context); |
| 823 offset = FPDFAPI_FlateGetTotalIn(context); | |
| 824 if (!useOldImpl) { | |
| 825 if (result_tmp_bufs.GetSize() == 1) { | 826 if (result_tmp_bufs.GetSize() == 1) { |
| 826 dest_buf = result_tmp_bufs[0]; | 827 dest_buf = result_tmp_bufs[0]; |
| 827 } else { | 828 } else { |
| 828 FX_LPBYTE result_buf = FX_Alloc(FX_BYTE, dest_size); | 829 FX_LPBYTE result_buf = FX_Alloc(FX_BYTE, dest_size); |
| 829 if (!result_buf) { | 830 if (!result_buf) { |
| 830 dest_buf = NULL; | 831 for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { |
| 831 dest_size = 0; | 832 FX_Free(result_tmp_bufs[i]); |
| 832 return; | 833 } |
| 834 goto fail; |
| 833 } | 835 } |
| 834 FX_DWORD result_pos = 0; | 836 FX_DWORD result_pos = 0; |
| 835 for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { | 837 for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { |
| 836 FX_LPBYTE tmp_buf = result_tmp_bufs[i]; | 838 FX_LPBYTE tmp_buf = result_tmp_bufs[i]; |
| 837 FX_DWORD tmp_buf_size = buf_size; | 839 FX_DWORD tmp_buf_size = buf_size; |
| 838 if (i == result_tmp_bufs.GetSize() - 1) { | 840 if (i == result_tmp_bufs.GetSize() - 1) { |
| 839 tmp_buf_size = last_buf_size; | 841 tmp_buf_size = last_buf_size; |
| 840 } | 842 } |
| 841 FXSYS_memcpy32(result_buf + result_pos, tmp_buf, tmp_buf_size); | 843 FXSYS_memcpy32(result_buf + result_pos, tmp_buf, tmp_buf_size); |
| 842 result_pos += tmp_buf_size; | 844 result_pos += tmp_buf_size; |
| 843 FX_Free(tmp_buf); | 845 FX_Free(result_tmp_bufs[i]); |
| 844 tmp_buf = NULL; | |
| 845 result_tmp_bufs[i] = NULL; | |
| 846 } | 846 } |
| 847 dest_buf = result_buf; | 847 dest_buf = result_buf; |
| 848 } | 848 } |
| 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 } | 849 } |
| 862 FPDFAPI_FlateEnd(context); | 850 FPDFAPI_FlateEnd(context); |
| 863 context = NULL; | 851 return; |
| 852 |
| 853 fail: |
| 854 FX_Free(guess_buf); |
| 855 dest_buf = nullptr; |
| 856 dest_size = 0; |
| 857 return; |
| 864 } | 858 } |
| 865 ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder(FX_LPCBYTE src_buf, FX
_DWORD src_size, int width, int height, | 859 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) | 860 int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, in
t Columns) |
| 867 { | 861 { |
| 868 CCodec_FlateScanlineDecoder* pDecoder = new CCodec_FlateScanlineDecoder; | 862 CCodec_FlateScanlineDecoder* pDecoder = new CCodec_FlateScanlineDecoder; |
| 869 pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, C
olors, BitsPerComponent, Columns); | 863 pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, C
olors, BitsPerComponent, Columns); |
| 870 return pDecoder; | 864 return pDecoder; |
| 871 } | 865 } |
| 872 FX_DWORD CCodec_FlateModule::FlateOrLZWDecode(FX_BOOL bLZW, const FX_BYTE* src_b
uf, FX_DWORD src_size, FX_BOOL bEarlyChange, | 866 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, | 867 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; | 944 dest_size = src_size + src_size / 1000 + 12; |
| 951 dest_buf = FX_Alloc( FX_BYTE, dest_size); | 945 dest_buf = FX_Alloc( FX_BYTE, dest_size); |
| 952 if (dest_buf == NULL) { | 946 if (dest_buf == NULL) { |
| 953 return FALSE; | 947 return FALSE; |
| 954 } | 948 } |
| 955 unsigned long temp_size = dest_size; | 949 unsigned long temp_size = dest_size; |
| 956 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); | 950 FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); |
| 957 dest_size = (FX_DWORD)temp_size; | 951 dest_size = (FX_DWORD)temp_size; |
| 958 return TRUE; | 952 return TRUE; |
| 959 } | 953 } |
| OLD | NEW |