summaryrefslogtreecommitdiff
path: root/core/fxcodec/lgif/fx_gif.cpp
diff options
context:
space:
mode:
authorRyan Harrison <rharrison@chromium.org>2017-09-26 15:39:10 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-09-26 19:58:33 +0000
commite2df5b7305df66efbd81232d911615af60624ae3 (patch)
tree5c5aff0ae260792790cfb1ed2f3f15863c0c0d63 /core/fxcodec/lgif/fx_gif.cpp
parent7d04f1b0ab4848f1d10983b7a7b1444ac93dec70 (diff)
downloadpdfium-e2df5b7305df66efbd81232d911615af60624ae3.tar.xz
Move LZW decoder out of fx_gif
CGifLZWDecoder has been moved out into its own file, name changed to CFX_LZWDecoder, member variable names updated, creation pattern changed, and unit tests added. Wrt the creation pattern, there is no longer a constructor and 2 initialization methods that need to be called. Instead all of the initialization is done as part of the constructor. A wrapper has been added for generating a std::unique_ptr<CFX_LZWDecoder>, so that params can be validated. BUG=pdfium:900,pdfium:901,pdfium:903,pdfium:904 Change-Id: Idcbe773f7fb18b08e64d5a89bfd87d4801332c53 Reviewed-on: https://pdfium-review.googlesource.com/14814 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Diffstat (limited to 'core/fxcodec/lgif/fx_gif.cpp')
-rw-r--r--core/fxcodec/lgif/fx_gif.cpp181
1 files changed, 0 insertions, 181 deletions
diff --git a/core/fxcodec/lgif/fx_gif.cpp b/core/fxcodec/lgif/fx_gif.cpp
index 6e1c26ed12..db0744a6bb 100644
--- a/core/fxcodec/lgif/fx_gif.cpp
+++ b/core/fxcodec/lgif/fx_gif.cpp
@@ -26,184 +26,3 @@ static_assert(sizeof(GifLSD) == 7, "GifLSD should have a size of 7");
GifImage::GifImage() {}
GifImage::~GifImage() {}
-
-void CGifLZWDecoder::Input(uint8_t* src_buf, uint32_t src_size) {
- next_in = src_buf;
- avail_in = src_size;
-}
-
-uint32_t CGifLZWDecoder::GetAvailInput() {
- return avail_in;
-}
-
-CGifLZWDecoder::CGifLZWDecoder(char* error_ptr)
- : code_size(0),
- code_size_cur(0),
- code_clear(0),
- code_end(0),
- code_next(0),
- code_first(0),
- stack_size(0),
- code_old(0),
- next_in(nullptr),
- avail_in(0),
- bits_left(0),
- code_store(0),
- err_msg_ptr(error_ptr) {}
-
-CGifLZWDecoder::~CGifLZWDecoder() {}
-
-void CGifLZWDecoder::InitTable(uint8_t color_exp, uint8_t code_exp) {
- // TODO(rharrison): Refactor all of this, so that initializing the table with
- // bad values will kill the decompress.
- ASSERT(code_exp <= GIF_MAX_LZW_EXP);
- code_color_end = std::min(2 << color_exp, 1 << code_exp);
- code_size = code_exp;
- code_clear = 1 << code_exp;
- code_end = code_clear + 1;
- bits_left = 0;
- code_store = 0;
- next_in = nullptr;
- avail_in = 0;
- stack_size = 0;
- code_first = 0;
- ClearTable();
-}
-
-void CGifLZWDecoder::ClearTable() {
- code_size_cur = code_size + 1;
- code_next = code_end + 1;
- code_old = static_cast<uint16_t>(-1);
- memset(code_table, 0, sizeof(tag_Table) * GIF_MAX_LZW_CODE);
- memset(stack, 0, GIF_MAX_LZW_CODE);
- for (uint16_t i = 0; i < code_clear; i++)
- code_table[i].suffix = static_cast<uint8_t>(i);
-}
-
-bool CGifLZWDecoder::DecodeString(uint16_t code) {
- stack_size = 0;
- while (code >= code_clear && code <= code_next) {
- if (code == code_table[code].prefix || stack_size == GIF_MAX_LZW_CODE - 1)
- return false;
-
- stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = code_table[code].suffix;
- code = code_table[code].prefix;
- }
- if (code >= code_color_end)
- return false;
-
- stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = static_cast<uint8_t>(code);
- code_first = static_cast<uint8_t>(code);
- return true;
-}
-
-void CGifLZWDecoder::AddCode(uint16_t prefix_code, uint8_t append_char) {
- if (code_next == GIF_MAX_LZW_CODE)
- return;
-
- code_table[code_next].prefix = prefix_code;
- code_table[code_next].suffix = append_char;
- if (++code_next < GIF_MAX_LZW_CODE) {
- if (code_next >> code_size_cur)
- code_size_cur++;
- }
-}
-
-GifDecodeStatus CGifLZWDecoder::Decode(uint8_t* des_buf, uint32_t* des_size) {
- if (*des_size == 0)
- return GifDecodeStatus::InsufficientDestSize;
-
- uint32_t i = 0;
- if (stack_size != 0) {
- if (*des_size < stack_size) {
- memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], *des_size);
- stack_size -= static_cast<uint16_t>(*des_size);
- return GifDecodeStatus::InsufficientDestSize;
- }
- memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], stack_size);
- des_buf += stack_size;
- i += stack_size;
- stack_size = 0;
- }
- ASSERT(err_msg_ptr);
- while (i <= *des_size && (avail_in > 0 || bits_left >= code_size_cur)) {
- if (code_size_cur > GIF_MAX_LZW_EXP) {
- strncpy(err_msg_ptr, "Code Length Out Of Range", GIF_MAX_ERROR_SIZE - 1);
- return GifDecodeStatus::Error;
- }
- if (avail_in > 0) {
- if (bits_left > 31) {
- strncpy(err_msg_ptr, "Decode Error", GIF_MAX_ERROR_SIZE - 1);
- return GifDecodeStatus::Error;
- }
- pdfium::base::CheckedNumeric<uint32_t> safe_code = *next_in++;
- safe_code <<= bits_left;
- safe_code |= code_store;
- if (!safe_code.IsValid()) {
- strncpy(err_msg_ptr, "Code Store Out Of Range", GIF_MAX_ERROR_SIZE - 1);
- return GifDecodeStatus::Error;
- }
- code_store = safe_code.ValueOrDie();
- --avail_in;
- bits_left += 8;
- }
- while (bits_left >= code_size_cur) {
- uint16_t code =
- static_cast<uint16_t>(code_store) & ((1 << code_size_cur) - 1);
- code_store >>= code_size_cur;
- bits_left -= code_size_cur;
- if (code == code_clear) {
- ClearTable();
- continue;
- }
- if (code == code_end) {
- *des_size = i;
- return GifDecodeStatus::Success;
- }
- if (code_old != static_cast<uint16_t>(-1)) {
- if (code_next < GIF_MAX_LZW_CODE) {
- if (code == code_next) {
- AddCode(code_old, code_first);
- if (!DecodeString(code)) {
- strncpy(err_msg_ptr, "String Decoding Error",
- GIF_MAX_ERROR_SIZE - 1);
- return GifDecodeStatus::Error;
- }
- } else if (code > code_next) {
- strncpy(err_msg_ptr, "Decode Error, Out Of Range",
- GIF_MAX_ERROR_SIZE - 1);
- return GifDecodeStatus::Error;
- } else {
- if (!DecodeString(code)) {
- strncpy(err_msg_ptr, "String Decoding Error",
- GIF_MAX_ERROR_SIZE - 1);
- return GifDecodeStatus::Error;
- }
- uint8_t append_char = stack[GIF_MAX_LZW_CODE - stack_size];
- AddCode(code_old, append_char);
- }
- }
- } else {
- if (!DecodeString(code)) {
- strncpy(err_msg_ptr, "String Decoding Error", GIF_MAX_ERROR_SIZE - 1);
- return GifDecodeStatus::Error;
- }
- }
- code_old = code;
- if (i + stack_size > *des_size) {
- memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], *des_size - i);
- stack_size -= static_cast<uint16_t>(*des_size - i);
- return GifDecodeStatus::InsufficientDestSize;
- }
- memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], stack_size);
- des_buf += stack_size;
- i += stack_size;
- stack_size = 0;
- }
- }
- if (avail_in == 0) {
- *des_size = i;
- return GifDecodeStatus::Unfinished;
- }
- return GifDecodeStatus::Error;
-}