• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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