| 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 "core/fxcodec/codec/codec_int.h" | 7 #include "core/fxcodec/codec/codec_int.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 } // extern "C" | 87 } // extern "C" |
| 88 | 88 |
| 89 namespace { | 89 namespace { |
| 90 | 90 |
| 91 class CLZWDecoder { | 91 class CLZWDecoder { |
| 92 public: | 92 public: |
| 93 int Decode(uint8_t* output, | 93 int Decode(uint8_t* output, |
| 94 uint32_t& outlen, | 94 uint32_t& outlen, |
| 95 const uint8_t* input, | 95 const uint8_t* input, |
| 96 uint32_t& size, | 96 uint32_t& size, |
| 97 FX_BOOL bEarlyChange); | 97 bool bEarlyChange); |
| 98 | 98 |
| 99 private: | 99 private: |
| 100 void AddCode(uint32_t prefix_code, uint8_t append_char); | 100 void AddCode(uint32_t prefix_code, uint8_t append_char); |
| 101 void DecodeString(uint32_t code); | 101 void DecodeString(uint32_t code); |
| 102 | 102 |
| 103 uint32_t m_InPos; | 103 uint32_t m_InPos; |
| 104 uint32_t m_OutPos; | 104 uint32_t m_OutPos; |
| 105 uint8_t* m_pOutput; | 105 uint8_t* m_pOutput; |
| 106 const uint8_t* m_pInput; | 106 const uint8_t* m_pInput; |
| 107 FX_BOOL m_Early; | 107 bool m_Early; |
| 108 uint32_t m_CodeArray[5021]; | 108 uint32_t m_CodeArray[5021]; |
| 109 uint32_t m_nCodes; | 109 uint32_t m_nCodes; |
| 110 uint8_t m_DecodeStack[4000]; | 110 uint8_t m_DecodeStack[4000]; |
| 111 uint32_t m_StackLen; | 111 uint32_t m_StackLen; |
| 112 int m_CodeLen; | 112 int m_CodeLen; |
| 113 }; | 113 }; |
| 114 | 114 |
| 115 void CLZWDecoder::AddCode(uint32_t prefix_code, uint8_t append_char) { | 115 void CLZWDecoder::AddCode(uint32_t prefix_code, uint8_t append_char) { |
| 116 if (m_nCodes + m_Early == 4094) { | 116 if (m_nCodes + m_Early == 4094) { |
| 117 return; | 117 return; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 140 } | 140 } |
| 141 if (m_StackLen >= sizeof(m_DecodeStack)) { | 141 if (m_StackLen >= sizeof(m_DecodeStack)) { |
| 142 return; | 142 return; |
| 143 } | 143 } |
| 144 m_DecodeStack[m_StackLen++] = (uint8_t)code; | 144 m_DecodeStack[m_StackLen++] = (uint8_t)code; |
| 145 } | 145 } |
| 146 int CLZWDecoder::Decode(uint8_t* dest_buf, | 146 int CLZWDecoder::Decode(uint8_t* dest_buf, |
| 147 uint32_t& dest_size, | 147 uint32_t& dest_size, |
| 148 const uint8_t* src_buf, | 148 const uint8_t* src_buf, |
| 149 uint32_t& src_size, | 149 uint32_t& src_size, |
| 150 FX_BOOL bEarlyChange) { | 150 bool bEarlyChange) { |
| 151 m_CodeLen = 9; | 151 m_CodeLen = 9; |
| 152 m_InPos = 0; | 152 m_InPos = 0; |
| 153 m_OutPos = 0; | 153 m_OutPos = 0; |
| 154 m_pInput = src_buf; | 154 m_pInput = src_buf; |
| 155 m_pOutput = dest_buf; | 155 m_pOutput = dest_buf; |
| 156 m_Early = bEarlyChange ? 1 : 0; | 156 m_Early = bEarlyChange ? 1 : 0; |
| 157 m_nCodes = 0; | 157 m_nCodes = 0; |
| 158 uint32_t old_code = (uint32_t)-1; | 158 uint32_t old_code = (uint32_t)-1; |
| 159 uint8_t last_char = 0; | 159 uint8_t last_char = 0; |
| 160 while (1) { | 160 while (1) { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left); | 335 pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left); |
| 336 break; | 336 break; |
| 337 } | 337 } |
| 338 default: | 338 default: |
| 339 pDestData[byte] = raw_byte; | 339 pDestData[byte] = raw_byte; |
| 340 break; | 340 break; |
| 341 } | 341 } |
| 342 } | 342 } |
| 343 } | 343 } |
| 344 | 344 |
| 345 FX_BOOL PNG_Predictor(uint8_t*& data_buf, | 345 bool PNG_Predictor(uint8_t*& data_buf, |
| 346 uint32_t& data_size, | 346 uint32_t& data_size, |
| 347 int Colors, | 347 int Colors, |
| 348 int BitsPerComponent, | 348 int BitsPerComponent, |
| 349 int Columns) { | 349 int Columns) { |
| 350 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; | 350 const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; |
| 351 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 351 const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 352 if (row_size <= 0) | 352 if (row_size <= 0) |
| 353 return FALSE; | 353 return false; |
| 354 const int row_count = (data_size + row_size) / (row_size + 1); | 354 const int row_count = (data_size + row_size) / (row_size + 1); |
| 355 if (row_count <= 0) | 355 if (row_count <= 0) |
| 356 return FALSE; | 356 return false; |
| 357 const int last_row_size = data_size % (row_size + 1); | 357 const int last_row_size = data_size % (row_size + 1); |
| 358 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); | 358 uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); |
| 359 int byte_cnt = 0; | 359 int byte_cnt = 0; |
| 360 uint8_t* pSrcData = data_buf; | 360 uint8_t* pSrcData = data_buf; |
| 361 uint8_t* pDestData = dest_buf; | 361 uint8_t* pDestData = dest_buf; |
| 362 for (int row = 0; row < row_count; row++) { | 362 for (int row = 0; row < row_count; row++) { |
| 363 uint8_t tag = pSrcData[0]; | 363 uint8_t tag = pSrcData[0]; |
| 364 byte_cnt++; | 364 byte_cnt++; |
| 365 if (tag == 0) { | 365 if (tag == 0) { |
| 366 int move_size = row_size; | 366 int move_size = row_size; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 } | 426 } |
| 427 byte_cnt++; | 427 byte_cnt++; |
| 428 } | 428 } |
| 429 pSrcData += row_size + 1; | 429 pSrcData += row_size + 1; |
| 430 pDestData += row_size; | 430 pDestData += row_size; |
| 431 } | 431 } |
| 432 FX_Free(data_buf); | 432 FX_Free(data_buf); |
| 433 data_buf = dest_buf; | 433 data_buf = dest_buf; |
| 434 data_size = row_size * row_count - | 434 data_size = row_size * row_count - |
| 435 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); | 435 (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); |
| 436 return TRUE; | 436 return true; |
| 437 } | 437 } |
| 438 | 438 |
| 439 void TIFF_PredictLine(uint8_t* dest_buf, | 439 void TIFF_PredictLine(uint8_t* dest_buf, |
| 440 uint32_t row_size, | 440 uint32_t row_size, |
| 441 int BitsPerComponent, | 441 int BitsPerComponent, |
| 442 int Colors, | 442 int Colors, |
| 443 int Columns) { | 443 int Columns) { |
| 444 if (BitsPerComponent == 1) { | 444 if (BitsPerComponent == 1) { |
| 445 int row_bits = std::min(BitsPerComponent * Colors * Columns, | 445 int row_bits = std::min(BitsPerComponent * Colors * Columns, |
| 446 pdfium::base::checked_cast<int>(row_size * 8)); | 446 pdfium::base::checked_cast<int>(row_size * 8)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 469 dest_buf[i] = pixel >> 8; | 469 dest_buf[i] = pixel >> 8; |
| 470 dest_buf[i + 1] = (uint8_t)pixel; | 470 dest_buf[i + 1] = (uint8_t)pixel; |
| 471 } | 471 } |
| 472 } else { | 472 } else { |
| 473 for (uint32_t i = BytesPerPixel; i < row_size; i++) { | 473 for (uint32_t i = BytesPerPixel; i < row_size; i++) { |
| 474 dest_buf[i] += dest_buf[i - BytesPerPixel]; | 474 dest_buf[i] += dest_buf[i - BytesPerPixel]; |
| 475 } | 475 } |
| 476 } | 476 } |
| 477 } | 477 } |
| 478 | 478 |
| 479 FX_BOOL TIFF_Predictor(uint8_t*& data_buf, | 479 bool TIFF_Predictor(uint8_t*& data_buf, |
| 480 uint32_t& data_size, | 480 uint32_t& data_size, |
| 481 int Colors, | 481 int Colors, |
| 482 int BitsPerComponent, | 482 int BitsPerComponent, |
| 483 int Columns) { | 483 int Columns) { |
| 484 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; | 484 int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; |
| 485 if (row_size == 0) | 485 if (row_size == 0) |
| 486 return FALSE; | 486 return false; |
| 487 const int row_count = (data_size + row_size - 1) / row_size; | 487 const int row_count = (data_size + row_size - 1) / row_size; |
| 488 const int last_row_size = data_size % row_size; | 488 const int last_row_size = data_size % row_size; |
| 489 for (int row = 0; row < row_count; row++) { | 489 for (int row = 0; row < row_count; row++) { |
| 490 uint8_t* scan_line = data_buf + row * row_size; | 490 uint8_t* scan_line = data_buf + row * row_size; |
| 491 if ((row + 1) * row_size > (int)data_size) { | 491 if ((row + 1) * row_size > (int)data_size) { |
| 492 row_size = last_row_size; | 492 row_size = last_row_size; |
| 493 } | 493 } |
| 494 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); | 494 TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); |
| 495 } | 495 } |
| 496 return TRUE; | 496 return true; |
| 497 } | 497 } |
| 498 | 498 |
| 499 void FlateUncompress(const uint8_t* src_buf, | 499 void FlateUncompress(const uint8_t* src_buf, |
| 500 uint32_t src_size, | 500 uint32_t src_size, |
| 501 uint32_t orig_size, | 501 uint32_t orig_size, |
| 502 uint8_t*& dest_buf, | 502 uint8_t*& dest_buf, |
| 503 uint32_t& dest_size, | 503 uint32_t& dest_size, |
| 504 uint32_t& offset) { | 504 uint32_t& offset) { |
| 505 uint32_t guess_size = orig_size ? orig_size : src_size * 2; | 505 uint32_t guess_size = orig_size ? orig_size : src_size * 2; |
| 506 const uint32_t kStepSize = 10240; | 506 const uint32_t kStepSize = 10240; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 int width, | 620 int width, |
| 621 int height, | 621 int height, |
| 622 int nComps, | 622 int nComps, |
| 623 int bpc, | 623 int bpc, |
| 624 int predictor, | 624 int predictor, |
| 625 int Colors, | 625 int Colors, |
| 626 int BitsPerComponent, | 626 int BitsPerComponent, |
| 627 int Columns); | 627 int Columns); |
| 628 | 628 |
| 629 // CCodec_ScanlineDecoder | 629 // CCodec_ScanlineDecoder |
| 630 FX_BOOL v_Rewind() override; | 630 bool v_Rewind() override; |
| 631 uint8_t* v_GetNextLine() override; | 631 uint8_t* v_GetNextLine() override; |
| 632 uint32_t GetSrcOffset() override; | 632 uint32_t GetSrcOffset() override; |
| 633 | 633 |
| 634 void* m_pFlate; | 634 void* m_pFlate; |
| 635 const uint8_t* m_SrcBuf; | 635 const uint8_t* m_SrcBuf; |
| 636 uint32_t m_SrcSize; | 636 uint32_t m_SrcSize; |
| 637 uint8_t* m_pScanline; | 637 uint8_t* m_pScanline; |
| 638 uint8_t* m_pLastLine; | 638 uint8_t* m_pLastLine; |
| 639 uint8_t* m_pPredictBuffer; | 639 uint8_t* m_pPredictBuffer; |
| 640 uint8_t* m_pPredictRaw; | 640 uint8_t* m_pPredictRaw; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 m_PredictPitch = | 700 m_PredictPitch = |
| 701 (static_cast<uint32_t>(m_BitsPerComponent) * m_Colors * m_Columns + | 701 (static_cast<uint32_t>(m_BitsPerComponent) * m_Colors * m_Columns + |
| 702 7) / | 702 7) / |
| 703 8; | 703 8; |
| 704 m_pLastLine = FX_Alloc(uint8_t, m_PredictPitch); | 704 m_pLastLine = FX_Alloc(uint8_t, m_PredictPitch); |
| 705 m_pPredictRaw = FX_Alloc(uint8_t, m_PredictPitch + 1); | 705 m_pPredictRaw = FX_Alloc(uint8_t, m_PredictPitch + 1); |
| 706 m_pPredictBuffer = FX_Alloc(uint8_t, m_PredictPitch); | 706 m_pPredictBuffer = FX_Alloc(uint8_t, m_PredictPitch); |
| 707 } | 707 } |
| 708 } | 708 } |
| 709 } | 709 } |
| 710 FX_BOOL CCodec_FlateScanlineDecoder::v_Rewind() { | 710 bool CCodec_FlateScanlineDecoder::v_Rewind() { |
| 711 if (m_pFlate) { | 711 if (m_pFlate) { |
| 712 FPDFAPI_FlateEnd(m_pFlate); | 712 FPDFAPI_FlateEnd(m_pFlate); |
| 713 } | 713 } |
| 714 m_pFlate = FPDFAPI_FlateInit(my_alloc_func, my_free_func); | 714 m_pFlate = FPDFAPI_FlateInit(my_alloc_func, my_free_func); |
| 715 if (!m_pFlate) { | 715 if (!m_pFlate) { |
| 716 return FALSE; | 716 return false; |
| 717 } | 717 } |
| 718 FPDFAPI_FlateInput(m_pFlate, m_SrcBuf, m_SrcSize); | 718 FPDFAPI_FlateInput(m_pFlate, m_SrcBuf, m_SrcSize); |
| 719 m_LeftOver = 0; | 719 m_LeftOver = 0; |
| 720 return TRUE; | 720 return true; |
| 721 } | 721 } |
| 722 uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() { | 722 uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() { |
| 723 if (m_Predictor) { | 723 if (m_Predictor) { |
| 724 if (m_Pitch == m_PredictPitch) { | 724 if (m_Pitch == m_PredictPitch) { |
| 725 if (m_Predictor == 2) { | 725 if (m_Predictor == 2) { |
| 726 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); | 726 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); |
| 727 PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine, | 727 PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine, |
| 728 m_BitsPerComponent, m_Colors, m_Columns); | 728 m_BitsPerComponent, m_Colors, m_Columns); |
| 729 FXSYS_memcpy(m_pLastLine, m_pScanline, m_PredictPitch); | 729 FXSYS_memcpy(m_pLastLine, m_pScanline, m_PredictPitch); |
| 730 } else { | 730 } else { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 int bpc, | 780 int bpc, |
| 781 int predictor, | 781 int predictor, |
| 782 int Colors, | 782 int Colors, |
| 783 int BitsPerComponent, | 783 int BitsPerComponent, |
| 784 int Columns) { | 784 int Columns) { |
| 785 CCodec_FlateScanlineDecoder* pDecoder = new CCodec_FlateScanlineDecoder; | 785 CCodec_FlateScanlineDecoder* pDecoder = new CCodec_FlateScanlineDecoder; |
| 786 pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, | 786 pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, |
| 787 Colors, BitsPerComponent, Columns); | 787 Colors, BitsPerComponent, Columns); |
| 788 return pDecoder; | 788 return pDecoder; |
| 789 } | 789 } |
| 790 uint32_t CCodec_FlateModule::FlateOrLZWDecode(FX_BOOL bLZW, | 790 uint32_t CCodec_FlateModule::FlateOrLZWDecode(bool bLZW, |
| 791 const uint8_t* src_buf, | 791 const uint8_t* src_buf, |
| 792 uint32_t src_size, | 792 uint32_t src_size, |
| 793 FX_BOOL bEarlyChange, | 793 bool bEarlyChange, |
| 794 int predictor, | 794 int predictor, |
| 795 int Colors, | 795 int Colors, |
| 796 int BitsPerComponent, | 796 int BitsPerComponent, |
| 797 int Columns, | 797 int Columns, |
| 798 uint32_t estimated_size, | 798 uint32_t estimated_size, |
| 799 uint8_t*& dest_buf, | 799 uint8_t*& dest_buf, |
| 800 uint32_t& dest_size) { | 800 uint32_t& dest_size) { |
| 801 dest_buf = nullptr; | 801 dest_buf = nullptr; |
| 802 uint32_t offset = 0; | 802 uint32_t offset = 0; |
| 803 int predictor_type = 0; | 803 int predictor_type = 0; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 825 dest_buf[dest_size] = '\0'; | 825 dest_buf[dest_size] = '\0'; |
| 826 decoder->Decode(dest_buf, dest_size, src_buf, offset, bEarlyChange); | 826 decoder->Decode(dest_buf, dest_size, src_buf, offset, bEarlyChange); |
| 827 } | 827 } |
| 828 } else { | 828 } else { |
| 829 FlateUncompress(src_buf, src_size, estimated_size, dest_buf, dest_size, | 829 FlateUncompress(src_buf, src_size, estimated_size, dest_buf, dest_size, |
| 830 offset); | 830 offset); |
| 831 } | 831 } |
| 832 if (predictor_type == 0) { | 832 if (predictor_type == 0) { |
| 833 return offset; | 833 return offset; |
| 834 } | 834 } |
| 835 FX_BOOL ret = TRUE; | 835 bool ret = true; |
| 836 if (predictor_type == 2) { | 836 if (predictor_type == 2) { |
| 837 ret = PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); | 837 ret = PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); |
| 838 } else if (predictor_type == 1) { | 838 } else if (predictor_type == 1) { |
| 839 ret = | 839 ret = |
| 840 TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); | 840 TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); |
| 841 } | 841 } |
| 842 return ret ? offset : FX_INVALID_OFFSET; | 842 return ret ? offset : FX_INVALID_OFFSET; |
| 843 } | 843 } |
| 844 | 844 |
| 845 bool CCodec_FlateModule::Encode(const uint8_t* src_buf, | 845 bool CCodec_FlateModule::Encode(const uint8_t* src_buf, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 860 uint32_t src_size, | 860 uint32_t src_size, |
| 861 uint8_t** dest_buf, | 861 uint8_t** dest_buf, |
| 862 uint32_t* dest_size) { | 862 uint32_t* dest_size) { |
| 863 uint8_t* pSrcBuf = FX_Alloc(uint8_t, src_size); | 863 uint8_t* pSrcBuf = FX_Alloc(uint8_t, src_size); |
| 864 FXSYS_memcpy(pSrcBuf, src_buf, src_size); | 864 FXSYS_memcpy(pSrcBuf, src_buf, src_size); |
| 865 PNG_PredictorEncode(&pSrcBuf, &src_size); | 865 PNG_PredictorEncode(&pSrcBuf, &src_size); |
| 866 bool ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); | 866 bool ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); |
| 867 FX_Free(pSrcBuf); | 867 FX_Free(pSrcBuf); |
| 868 return ret; | 868 return ret; |
| 869 } | 869 } |
| OLD | NEW |