7#include "core/fxcodec/gif/lzw_decompressor.h"
15#include "core/fxcrt/fx_safe_types.h"
16#include "third_party/base/memory/ptr_util.h"
32 : code_size_(code_exp),
33 code_color_end_(
static_cast<uint16_t>(1 << (color_exp + 1))),
34 code_clear_(
static_cast<uint16_t>(1 << code_exp)),
35 code_end_(
static_cast<uint16_t>((1 << code_exp) + 1)) {
47 uint32_t* dest_size) {
48 if (!next_in_ || !dest_buf || !dest_size)
58 if (decompressed_next_ != 0) {
59 uint32_t extracted_size = ExtractData(dest_buf, *dest_size);
60 if (decompressed_next_ != 0)
63 dest_buf += extracted_size;
67 while (i <= *dest_size && (avail_in_ > 0 || bits_left_ >= code_size_cur_)) {
75 FX_SAFE_UINT32 safe_code = *next_in_++;
76 safe_code <<= bits_left_;
77 safe_code |= code_store_;
78 if (!safe_code.IsValid())
81 code_store_ = safe_code.ValueOrDie();
86 while (bits_left_ >= code_size_cur_) {
88 static_cast<uint16_t>(code_store_) & ((1 << code_size_cur_) - 1);
89 code_store_ >>= code_size_cur_;
90 bits_left_ -= code_size_cur_;
91 if (code == code_clear_) {
95 if (code == code_end_) {
100 if (code_old_ !=
static_cast<uint16_t>(-1)) {
102 if (code == code_next_) {
103 AddCode(code_old_, code_first_);
104 if (!DecodeString(code))
106 }
else if (code > code_next_) {
109 if (!DecodeString(code))
112 uint8_t append_char = decompressed_[decompressed_next_ - 1];
113 AddCode(code_old_, append_char);
117 if (!DecodeString(code))
122 uint32_t extracted_size = ExtractData(dest_buf, *dest_size - i);
123 if (decompressed_next_ != 0)
126 dest_buf += extracted_size;
139 code_size_cur_ = code_size_ + 1;
140 code_next_ = code_end_ + 1;
141 code_old_ =
static_cast<uint16_t>(-1);
142 memset(code_table_, 0,
sizeof(code_table_));
143 for (uint16_t i = 0; i < code_clear_; i++)
144 code_table_[i]
.suffix =
static_cast<uint8_t>(i);
145 decompressed_.resize(code_next_ - code_clear_ + 1);
146 decompressed_next_ = 0;
149void LZWDecompressor::AddCode(uint16_t prefix_code, uint8_t append_char) {
153 code_table_[code_next_]
.prefix = prefix_code;
154 code_table_[code_next_]
.suffix = append_char;
156 if (code_next_ >> code_size_cur_)
162 decompressed_.resize(code_next_ - code_clear_ + 1);
163 decompressed_next_ = 0;
165 while (code >= code_clear_ && code <= code_next_) {
166 if (code == code_table_[code].prefix ||
167 decompressed_next_ >= decompressed_.size())
170 decompressed_[decompressed_next_++] = code_table_[code].suffix;
171 code = code_table_[code]
.prefix;
174 if (code >= code_color_end_)
177 decompressed_[decompressed_next_++] =
static_cast<uint8_t>(code);
178 code_first_ =
static_cast<uint8_t>(code);
182uint32_t
LZWDecompressor::ExtractData(uint8_t* dest_buf, uint32_t dest_size) {
186 uint32_t copy_size = dest_size <= decompressed_next_
188 :
static_cast<uint32_t>(decompressed_next_);
189 std::reverse_copy(decompressed_.data() + decompressed_next_ - copy_size,
190 decompressed_.data() + decompressed_next_, dest_buf);
191 decompressed_next_ -= copy_size;
Status Decode(uint8_t *dest_buf, uint32_t *dest_size)
void SetSource(const uint8_t *src_buf, uint32_t src_size)