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 |