1 // Copyright 2017 The PDFium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_FXCODEC_GIF_LZW_DECOMPRESSOR_H_ 8 #define CORE_FXCODEC_GIF_LZW_DECOMPRESSOR_H_ 9 10 #include <stddef.h> 11 #include <stdint.h> 12 13 #include <array> 14 #include <memory> 15 16 #include "core/fxcodec/gif/cfx_gif.h" 17 #include "core/fxcrt/compiler_specific.h" 18 #include "core/fxcrt/data_vector.h" 19 #include "core/fxcrt/span.h" 20 21 namespace fxcodec { 22 23 class LZWDecompressor { 24 public: 25 enum class Status { 26 kError, 27 kSuccess, 28 kUnfinished, 29 kInsufficientDestSize, 30 }; 31 32 struct CodeEntry { 33 uint16_t prefix; 34 uint8_t suffix; 35 }; 36 37 // Returns nullptr on error 38 static std::unique_ptr<LZWDecompressor> Create(uint8_t color_exp, 39 uint8_t code_exp); 40 ~LZWDecompressor(); 41 SetSource(pdfium::span<const uint8_t> src_buf)42 void SetSource(pdfium::span<const uint8_t> src_buf) { 43 avail_input_ = src_buf; 44 } 45 UNSAFE_BUFFER_USAGE Status Decode(uint8_t* dest_buf, uint32_t* dest_size); 46 47 // Used by unittests, should not be called in production code. ExtractDataForTest(pdfium::span<uint8_t> dest_buf)48 size_t ExtractDataForTest(pdfium::span<uint8_t> dest_buf) { 49 return ExtractData(dest_buf); 50 } 51 DecompressedForTest()52 DataVector<uint8_t>* DecompressedForTest() { return &decompressed_; } DecompressedNextForTest()53 size_t* DecompressedNextForTest() { return &decompressed_next_; } 54 55 private: 56 // Use Create() instead. 57 LZWDecompressor(uint8_t color_exp, uint8_t code_exp); 58 59 void ClearTable(); 60 void AddCode(uint16_t prefix_code, uint8_t append_char); 61 bool DecodeString(uint16_t code); 62 size_t ExtractData(pdfium::span<uint8_t> dest_buf); 63 64 const uint8_t code_size_; 65 uint8_t code_size_cur_ = 0; 66 const uint16_t code_color_end_; 67 const uint16_t code_clear_; 68 const uint16_t code_end_; 69 uint16_t code_next_ = 0; 70 uint8_t code_first_ = 0; 71 DataVector<uint8_t> decompressed_; 72 size_t decompressed_next_ = 0; 73 uint16_t code_old_ = 0; 74 pdfium::span<const uint8_t> avail_input_; 75 uint8_t bits_left_ = 0; 76 uint32_t code_store_ = 0; 77 std::array<CodeEntry, GIF_MAX_LZW_CODE> code_table_; 78 }; 79 80 } // namespace fxcodec 81 82 using LZWDecompressor = fxcodec::LZWDecompressor; 83 84 #endif // CORE_FXCODEC_GIF_LZW_DECOMPRESSOR_H_ 85