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 |