diff options
Diffstat (limited to 'core/fxcodec/lgif')
-rw-r--r-- | core/fxcodec/lgif/cfx_lzwdecoder.cpp | 184 | ||||
-rw-r--r-- | core/fxcodec/lgif/cfx_lzwdecoder.h | 55 | ||||
-rw-r--r-- | core/fxcodec/lgif/cfx_lzwdecoder_unittest.cpp | 147 | ||||
-rw-r--r-- | core/fxcodec/lgif/cgifcontext.cpp | 549 | ||||
-rw-r--r-- | core/fxcodec/lgif/cgifcontext.h | 76 | ||||
-rw-r--r-- | core/fxcodec/lgif/fx_gif.cpp | 18 | ||||
-rw-r--r-- | core/fxcodec/lgif/fx_gif.h | 131 |
7 files changed, 0 insertions, 1160 deletions
diff --git a/core/fxcodec/lgif/cfx_lzwdecoder.cpp b/core/fxcodec/lgif/cfx_lzwdecoder.cpp deleted file mode 100644 index 9479eeafaa..0000000000 --- a/core/fxcodec/lgif/cfx_lzwdecoder.cpp +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2017 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fxcodec/lgif/cfx_lzwdecoder.h" - -#include <algorithm> -#include <memory> -#include <utility> - -#include "core/fxcodec/lbmp/fx_bmp.h" -#include "third_party/base/numerics/safe_math.h" -#include "third_party/base/ptr_util.h" -#include "third_party/base/stl_util.h" - -std::unique_ptr<CFX_LZWDecoder> CFX_LZWDecoder::Create(uint8_t color_exp, - uint8_t code_exp) { - if (code_exp > GIF_MAX_LZW_EXP || code_exp + 1 < color_exp) - return nullptr; - return std::unique_ptr<CFX_LZWDecoder>( - new CFX_LZWDecoder(color_exp, code_exp)); -} - -CFX_LZWDecoder::CFX_LZWDecoder(uint8_t color_exp, uint8_t code_exp) - : code_size_(code_exp), - code_size_cur_(0), - code_color_end_(static_cast<uint16_t>(2 << color_exp)), - code_clear_(static_cast<uint16_t>(1 << code_exp)), - code_end_(static_cast<uint16_t>((1 << code_exp) + 1)), - code_next_(0), - code_first_(0), - stack_size_(0), - code_old_(0), - next_in_(nullptr), - avail_in_(0), - bits_left_(0), - code_store_(0) {} - -CFX_LZWDecoder::~CFX_LZWDecoder() {} - -GifDecodeStatus CFX_LZWDecoder::Decode(uint8_t* src_buf, - uint32_t src_size, - uint8_t* des_buf, - uint32_t* des_size) { - if (!src_buf || src_size == 0 || !des_buf || !des_size) - return GifDecodeStatus::Error; - - if (*des_size == 0) - return GifDecodeStatus::InsufficientDestSize; - - next_in_ = src_buf; - avail_in_ = src_size; - - ClearTable(); - - 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; - } - - while (i <= *des_size && (avail_in_ > 0 || bits_left_ >= code_size_cur_)) { - if (code_size_cur_ > GIF_MAX_LZW_EXP) - return GifDecodeStatus::Error; - - if (avail_in_ > 0) { - if (bits_left_ > 31) - return GifDecodeStatus::Error; - - pdfium::base::CheckedNumeric<uint32_t> safe_code = *next_in_++; - safe_code <<= bits_left_; - safe_code |= code_store_; - if (!safe_code.IsValid()) - 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)) - return GifDecodeStatus::Error; - } else if (code > code_next_) { - return GifDecodeStatus::Error; - } else { - if (!DecodeString(code)) - return GifDecodeStatus::Error; - - uint8_t append_char = stack_[GIF_MAX_LZW_CODE - stack_size_]; - AddCode(code_old_, append_char); - } - } - } else { - if (!DecodeString(code)) - 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) - return GifDecodeStatus::Error; - - *des_size = i; - return GifDecodeStatus::Unfinished; -} - -void CFX_LZWDecoder::ClearTable() { - code_size_cur_ = code_size_ + 1; - code_next_ = code_end_ + 1; - code_old_ = static_cast<uint16_t>(-1); - memset(code_table_, 0, sizeof(code_table_)); - memset(stack_, 0, sizeof(stack_)); - for (uint16_t i = 0; i < code_clear_; i++) - code_table_[i].suffix = static_cast<uint8_t>(i); -} - -void CFX_LZWDecoder::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_++; - } -} - -bool CFX_LZWDecoder::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; -} diff --git a/core/fxcodec/lgif/cfx_lzwdecoder.h b/core/fxcodec/lgif/cfx_lzwdecoder.h deleted file mode 100644 index 9dbf15d9b7..0000000000 --- a/core/fxcodec/lgif/cfx_lzwdecoder.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2017 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FXCODEC_LGIF_CFX_LZWDECODER_H_ -#define CORE_FXCODEC_LGIF_CFX_LZWDECODER_H_ - -#include <memory> -#include <vector> - -#include "core/fxcodec/lgif/fx_gif.h" - -class CFX_LZWDecoder { - public: - typedef struct { - uint16_t prefix; - uint8_t suffix; - } CodeEntry; - - // Returns nullptr on error - static std::unique_ptr<CFX_LZWDecoder> Create(uint8_t color_exp, - uint8_t code_exp); - ~CFX_LZWDecoder(); - - GifDecodeStatus Decode(uint8_t* src_buf, - uint32_t src_size, - uint8_t* des_buf, - uint32_t* des_size); - - private: - CFX_LZWDecoder(uint8_t color_exp, uint8_t code_exp); - void ClearTable(); - void AddCode(uint16_t prefix_code, uint8_t append_char); - bool DecodeString(uint16_t code); - - uint8_t code_size_; - uint8_t code_size_cur_; - uint16_t code_color_end_; - uint16_t code_clear_; - uint16_t code_end_; - uint16_t code_next_; - uint8_t code_first_; - uint8_t stack_[GIF_MAX_LZW_CODE]; - size_t stack_size_; - CodeEntry code_table_[GIF_MAX_LZW_CODE]; - uint16_t code_old_; - uint8_t* next_in_; - uint32_t avail_in_; - uint8_t bits_left_; - uint32_t code_store_; -}; - -#endif // CORE_FXCODEC_LGIF_CFX_LZWDECODER_H_ diff --git a/core/fxcodec/lgif/cfx_lzwdecoder_unittest.cpp b/core/fxcodec/lgif/cfx_lzwdecoder_unittest.cpp deleted file mode 100644 index 9e4b7b788e..0000000000 --- a/core/fxcodec/lgif/cfx_lzwdecoder_unittest.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2017 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/fxcodec/lgif/cfx_lzwdecoder.h" - -#include "core/fxcrt/fx_memory.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(CFX_LZWDecoder, CreateBadParams) { - EXPECT_EQ(nullptr, CFX_LZWDecoder::Create(0x10, 0x2)); - EXPECT_EQ(nullptr, CFX_LZWDecoder::Create(0x4, 0x0F)); -} - -TEST(CFX_LZWDecoder, DecodeBadParams) { - uint8_t palette_exp = 0x0; - uint8_t code_exp = 0x2; - - auto decoder = CFX_LZWDecoder::Create(palette_exp, code_exp); - ASSERT_NE(nullptr, decoder); - - uint8_t image_data[10]; - uint32_t image_size = FX_ArraySize(image_data); - - uint8_t output_data[10]; - uint32_t output_size = FX_ArraySize(output_data); - - EXPECT_EQ(GifDecodeStatus::Error, - decoder->Decode(nullptr, image_size, output_data, &output_size)); - EXPECT_EQ(GifDecodeStatus::Error, - decoder->Decode(image_data, 0, output_data, &output_size)); - EXPECT_EQ(GifDecodeStatus::Error, - decoder->Decode(image_data, image_size, nullptr, &output_size)); - EXPECT_EQ(GifDecodeStatus::Error, - decoder->Decode(image_data, image_size, output_data, nullptr)); - - output_size = 0; - EXPECT_EQ(GifDecodeStatus::InsufficientDestSize, - decoder->Decode(image_data, image_size, output_data, &output_size)); -} - -TEST(CFX_LZWDecoder, Decode1x1SingleColour) { - uint8_t palette_exp = 0x0; - uint8_t code_exp = 0x2; - - auto decoder = CFX_LZWDecoder::Create(palette_exp, code_exp); - ASSERT_NE(nullptr, decoder); - - uint8_t image_data[] = {0x44, 0x01}; - uint32_t image_size = FX_ArraySize(image_data); - - uint8_t output_data[1]; - uint32_t output_size = FX_ArraySize(output_data); - - EXPECT_EQ(GifDecodeStatus::Success, - decoder->Decode(image_data, image_size, output_data, &output_size)); - uint8_t expected_data[] = {0x00}; - - EXPECT_EQ(FX_ArraySize(output_data), output_size); - EXPECT_TRUE(0 == memcmp(expected_data, output_data, sizeof(expected_data))); -} - -TEST(CFX_LZWDecoder, Decode10x10SingleColour) { - uint8_t palette_exp = 0x0; - uint8_t code_exp = 0x2; - - auto decoder = CFX_LZWDecoder::Create(palette_exp, code_exp); - ASSERT_NE(nullptr, decoder); - - uint8_t image_data[] = {0x84, 0x8F, 0xA9, 0xCB, 0xED, 0x0F, 0x63, 0x2B}; - uint32_t image_size = FX_ArraySize(image_data); - - uint8_t output_data[100]; - memset(output_data, 0, sizeof(output_data)); - uint32_t output_size = FX_ArraySize(output_data); - - EXPECT_EQ(GifDecodeStatus::Success, - decoder->Decode(image_data, image_size, output_data, &output_size)); - uint8_t expected_data[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}; - - EXPECT_EQ(FX_ArraySize(output_data), output_size); - EXPECT_TRUE(0 == memcmp(expected_data, output_data, sizeof(expected_data))); -} - -TEST(CFX_LZWDecoder, Decode10x10MultipleColour) { - uint8_t palette_exp = 0x1; - uint8_t code_exp = 0x2; - - auto decoder = CFX_LZWDecoder::Create(palette_exp, code_exp); - ASSERT_NE(nullptr, decoder); - - uint8_t image_data[] = {0x8C, 0x2D, 0x99, 0x87, 0x2A, 0x1C, 0xDC, 0x33, - 0xA0, 0x02, 0x75, 0xEC, 0x95, 0xFA, 0xA8, 0xDE, - 0x60, 0x8C, 0x04, 0x91, 0x4C, 0x01}; - uint32_t image_size = FX_ArraySize(image_data); - - uint8_t output_data[100]; - memset(output_data, 0, sizeof(output_data)); - uint32_t output_size = FX_ArraySize(output_data); - - EXPECT_EQ(GifDecodeStatus::Success, - decoder->Decode(image_data, image_size, output_data, &output_size)); - uint8_t expected_data[] = { - 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, - 0x01, 0x01, 0x01, 0x01}; - - EXPECT_EQ(FX_ArraySize(output_data), output_size); - EXPECT_TRUE(0 == memcmp(expected_data, output_data, sizeof(expected_data))); -} - -TEST(CFX_LZWDecoder, HandleColourCodeOutOfPalette) { - uint8_t palette_exp = 0x2; // Image uses 10 colours, so the palette exp - // should be 3, 2^(3+1) = 16 colours. - uint8_t code_exp = 0x4; - - auto decoder = CFX_LZWDecoder::Create(palette_exp, code_exp); - ASSERT_NE(nullptr, decoder); - - uint8_t image_data[] = {0x30, 0xC9, 0x49, 0x81, 0xBD, 0x78, 0xE8, 0xCD, - 0x89, 0xFF, 0x60, 0x20, 0x8E, 0xE4, 0x61, 0x9E, - 0xA8, 0xA1, 0xAE, 0x2C, 0xE2, 0xBE, 0xB0, 0x20, - 0xCF, 0x74, 0x61, 0xDF, 0x78, 0x04}; - uint32_t image_size = FX_ArraySize(image_data); - - uint8_t output_data[100]; - memset(output_data, 0, sizeof(output_data)); - uint32_t output_size = FX_ArraySize(output_data); - - EXPECT_EQ(GifDecodeStatus::Error, - decoder->Decode(image_data, image_size, output_data, &output_size)); -} diff --git a/core/fxcodec/lgif/cgifcontext.cpp b/core/fxcodec/lgif/cgifcontext.cpp deleted file mode 100644 index af1895316f..0000000000 --- a/core/fxcodec/lgif/cgifcontext.cpp +++ /dev/null @@ -1,549 +0,0 @@ -// Copyright 2017 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fxcodec/lgif/cgifcontext.h" - -#include <algorithm> -#include <utility> - -#include "core/fxcodec/codec/ccodec_gifmodule.h" -#include "core/fxcodec/lbmp/fx_bmp.h" -#include "core/fxcodec/lgif/fx_gif.h" -#include "third_party/base/ptr_util.h" -#include "third_party/base/stl_util.h" - -namespace { - -const int32_t s_gif_interlace_step[4] = {8, 8, 4, 2}; - -} // namespace - -CGifContext::CGifContext(CCodec_GifModule* gif_module, - CCodec_GifModule::Delegate* pDelegate) - : m_pModule(gif_module), - m_pDelegate(pDelegate), - global_pal_exp(0), - img_row_offset(0), - img_row_avail_size(0), - avail_in(0), - decode_status(GIF_D_STATUS_SIG), - skip_size(0), - next_in(nullptr), - width(0), - height(0), - bc_index(0), - pixel_aspect(0), - global_sort_flag(0), - global_color_resolution(0), - img_pass_num(0) { -} - -CGifContext::~CGifContext() {} - -void CGifContext::RecordCurrentPosition(uint32_t* cur_pos_ptr) { - m_pDelegate->GifRecordCurrentPosition(*cur_pos_ptr); -} - -void CGifContext::ReadScanline(int32_t row_num, uint8_t* row_buf) { - m_pDelegate->GifReadScanline(row_num, row_buf); -} - -bool CGifContext::GetRecordPosition(uint32_t cur_pos, - int32_t left, - int32_t top, - int32_t width, - int32_t height, - int32_t pal_num, - GifPalette* pal_ptr, - int32_t delay_time, - bool user_input, - int32_t trans_index, - int32_t disposal_method, - bool interlace) { - return m_pDelegate->GifInputRecordPositionBuf( - cur_pos, FX_RECT(left, top, left + width, top + height), pal_num, pal_ptr, - delay_time, user_input, trans_index, disposal_method, interlace); -} - -GifDecodeStatus CGifContext::ReadHeader() { - uint32_t skip_size_org = skip_size; - GifHeader* gif_header_ptr = nullptr; - if (!ReadData(reinterpret_cast<uint8_t**>(&gif_header_ptr), 6)) - return GifDecodeStatus::Unfinished; - - if (strncmp(gif_header_ptr->signature, GIF_SIGNATURE, 3) != 0 || - gif_header_ptr->version[0] != '8' || gif_header_ptr->version[2] != 'a') - return GifDecodeStatus::Error; - - GifLocalScreenDescriptor* gif_lsd_ptr = nullptr; - if (!ReadData(reinterpret_cast<uint8_t**>(&gif_lsd_ptr), 7)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - - if (gif_lsd_ptr->global_flags.global_pal) { - global_pal_exp = gif_lsd_ptr->global_flags.pal_bits; - uint32_t global_pal_size = unsigned(2 << global_pal_exp) * 3u; - uint8_t* global_pal_ptr = nullptr; - if (!ReadData(&global_pal_ptr, global_pal_size)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - - global_sort_flag = gif_lsd_ptr->global_flags.sort_flag; - global_color_resolution = gif_lsd_ptr->global_flags.color_resolution; - m_GlobalPalette.resize(global_pal_size / 3); - memcpy(m_GlobalPalette.data(), global_pal_ptr, global_pal_size); - } - - width = static_cast<int>( - GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_lsd_ptr->width))); - height = static_cast<int>( - GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_lsd_ptr->height))); - bc_index = gif_lsd_ptr->bc_index; - pixel_aspect = gif_lsd_ptr->pixel_aspect; - return GifDecodeStatus::Success; -} - -GifDecodeStatus CGifContext::GetFrame() { - GifDecodeStatus ret = GifDecodeStatus::Success; - while (true) { - switch (decode_status) { - case GIF_D_STATUS_TAIL: - return GifDecodeStatus::Success; - case GIF_D_STATUS_SIG: { - uint8_t* sig_ptr = nullptr; - if (!ReadData(&sig_ptr, 1)) - return GifDecodeStatus::Unfinished; - - switch (*sig_ptr) { - case GIF_SIG_EXTENSION: - SaveDecodingStatus(GIF_D_STATUS_EXT); - continue; - case GIF_SIG_IMAGE: - SaveDecodingStatus(GIF_D_STATUS_IMG_INFO); - continue; - case GIF_SIG_TRAILER: - SaveDecodingStatus(GIF_D_STATUS_TAIL); - return GifDecodeStatus::Success; - default: - if (avail_in) { - // The Gif File has non_standard Tag! - SaveDecodingStatus(GIF_D_STATUS_SIG); - continue; - } - // The Gif File Doesn't have Trailer Tag! - return GifDecodeStatus::Success; - } - } - case GIF_D_STATUS_EXT: { - uint8_t* ext_ptr = nullptr; - if (!ReadData(&ext_ptr, 1)) - return GifDecodeStatus::Unfinished; - - switch (*ext_ptr) { - case GIF_BLOCK_CE: - SaveDecodingStatus(GIF_D_STATUS_EXT_CE); - continue; - case GIF_BLOCK_GCE: - SaveDecodingStatus(GIF_D_STATUS_EXT_GCE); - continue; - case GIF_BLOCK_PTE: - SaveDecodingStatus(GIF_D_STATUS_EXT_PTE); - continue; - default: { - int32_t status = GIF_D_STATUS_EXT_UNE; - if (*ext_ptr == GIF_BLOCK_PTE) { - status = GIF_D_STATUS_EXT_PTE; - } - SaveDecodingStatus(status); - continue; - } - } - } - case GIF_D_STATUS_IMG_INFO: { - ret = DecodeImageInfo(); - if (ret != GifDecodeStatus::Success) - return ret; - - continue; - } - case GIF_D_STATUS_IMG_DATA: { - uint8_t* data_size_ptr = nullptr; - uint8_t* data_ptr = nullptr; - uint32_t skip_size_org = skip_size; - if (!ReadData(&data_size_ptr, 1)) - return GifDecodeStatus::Unfinished; - - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (!ReadData(&data_ptr, *data_size_ptr)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - - SaveDecodingStatus(GIF_D_STATUS_IMG_DATA); - skip_size_org = skip_size; - if (!ReadData(&data_size_ptr, 1)) - return GifDecodeStatus::Unfinished; - } - SaveDecodingStatus(GIF_D_STATUS_SIG); - continue; - } - default: { - ret = DecodeExtension(); - if (ret != GifDecodeStatus::Success) - return ret; - break; - } - } - } - return GifDecodeStatus::Success; -} - -GifDecodeStatus CGifContext::LoadFrame(int32_t frame_num) { - if (!pdfium::IndexInBounds(m_Images, frame_num)) - return GifDecodeStatus::Error; - - uint8_t* data_size_ptr = nullptr; - uint8_t* data_ptr = nullptr; - uint32_t skip_size_org = skip_size; - GifImage* gif_image_ptr = m_Images[frame_num].get(); - uint32_t gif_img_row_bytes = gif_image_ptr->m_ImageInfo.width; - if (gif_img_row_bytes == 0) - return GifDecodeStatus::Error; - - if (decode_status == GIF_D_STATUS_TAIL) { - gif_image_ptr->m_ImageRowBuf.resize(gif_img_row_bytes); - GifGraphicControlExtension* gif_img_gce_ptr = - gif_image_ptr->m_ImageGCE.get(); - int32_t loc_pal_num = - gif_image_ptr->m_ImageInfo.local_flags.local_pal - ? (2 << gif_image_ptr->m_ImageInfo.local_flags.pal_bits) - : 0; - avail_in = 0; - GifPalette* pLocalPalette = gif_image_ptr->m_LocalPalettes.empty() - ? nullptr - : gif_image_ptr->m_LocalPalettes.data(); - if (!gif_img_gce_ptr) { - bool bRes = GetRecordPosition( - gif_image_ptr->image_data_pos, gif_image_ptr->m_ImageInfo.left, - gif_image_ptr->m_ImageInfo.top, gif_image_ptr->m_ImageInfo.width, - gif_image_ptr->m_ImageInfo.height, loc_pal_num, pLocalPalette, 0, 0, - -1, 0, gif_image_ptr->m_ImageInfo.local_flags.interlace); - if (!bRes) { - gif_image_ptr->m_ImageRowBuf.clear(); - return GifDecodeStatus::Error; - } - } else { - bool bRes = GetRecordPosition( - gif_image_ptr->image_data_pos, gif_image_ptr->m_ImageInfo.left, - gif_image_ptr->m_ImageInfo.top, gif_image_ptr->m_ImageInfo.width, - gif_image_ptr->m_ImageInfo.height, loc_pal_num, pLocalPalette, - static_cast<int32_t>(gif_image_ptr->m_ImageGCE->delay_time), - gif_image_ptr->m_ImageGCE->gce_flags.user_input, - gif_image_ptr->m_ImageGCE->gce_flags.transparency - ? static_cast<int32_t>(gif_image_ptr->m_ImageGCE->trans_index) - : -1, - static_cast<int32_t>( - gif_image_ptr->m_ImageGCE->gce_flags.disposal_method), - gif_image_ptr->m_ImageInfo.local_flags.interlace); - if (!bRes) { - gif_image_ptr->m_ImageRowBuf.clear(); - return GifDecodeStatus::Error; - } - } - - if (gif_image_ptr->image_code_exp > GIF_MAX_LZW_EXP) { - gif_image_ptr->m_ImageRowBuf.clear(); - return GifDecodeStatus::Error; - } - - img_row_offset = 0; - img_row_avail_size = 0; - img_pass_num = 0; - gif_image_ptr->image_row_num = 0; - SaveDecodingStatus(GIF_D_STATUS_IMG_DATA); - } - - if (decode_status == GIF_D_STATUS_IMG_DATA) { - if (!ReadData(&data_size_ptr, 1)) - return GifDecodeStatus::Unfinished; - - if (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (!ReadData(&data_ptr, *data_size_ptr)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - - if (!m_ImgDecoder.get()) - m_ImgDecoder = - CFX_LZWDecoder::Create(!gif_image_ptr->m_LocalPalettes.empty() - ? gif_image_ptr->local_pallette_exp - : global_pal_exp, - gif_image_ptr->image_code_exp); - SaveDecodingStatus(GIF_D_STATUS_IMG_DATA); - img_row_offset += img_row_avail_size; - img_row_avail_size = gif_img_row_bytes - img_row_offset; - GifDecodeStatus ret = - m_ImgDecoder.get() - ? m_ImgDecoder->Decode( - data_ptr, *data_size_ptr, - gif_image_ptr->m_ImageRowBuf.data() + img_row_offset, - &img_row_avail_size) - : GifDecodeStatus::Error; - if (ret == GifDecodeStatus::Error) { - DecodingFailureAtTailCleanup(gif_image_ptr); - return GifDecodeStatus::Error; - } - while (ret != GifDecodeStatus::Error) { - if (ret == GifDecodeStatus::Success) { - ReadScanline(gif_image_ptr->image_row_num, - gif_image_ptr->m_ImageRowBuf.data()); - gif_image_ptr->m_ImageRowBuf.clear(); - SaveDecodingStatus(GIF_D_STATUS_TAIL); - return GifDecodeStatus::Success; - } - if (ret == GifDecodeStatus::Unfinished) { - skip_size_org = skip_size; - if (!ReadData(&data_size_ptr, 1)) - return GifDecodeStatus::Unfinished; - - if (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (!ReadData(&data_ptr, *data_size_ptr)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - if (!m_ImgDecoder.get()) - m_ImgDecoder = - CFX_LZWDecoder::Create(!gif_image_ptr->m_LocalPalettes.empty() - ? gif_image_ptr->local_pallette_exp - : global_pal_exp, - gif_image_ptr->image_code_exp); - SaveDecodingStatus(GIF_D_STATUS_IMG_DATA); - img_row_offset += img_row_avail_size; - img_row_avail_size = gif_img_row_bytes - img_row_offset; - ret = - m_ImgDecoder.get() - ? m_ImgDecoder->Decode( - data_ptr, *data_size_ptr, - gif_image_ptr->m_ImageRowBuf.data() + img_row_offset, - &img_row_avail_size) - : GifDecodeStatus::Error; - } - } - if (ret == GifDecodeStatus::InsufficientDestSize) { - if (gif_image_ptr->m_ImageInfo.local_flags.interlace) { - ReadScanline(gif_image_ptr->image_row_num, - gif_image_ptr->m_ImageRowBuf.data()); - gif_image_ptr->image_row_num += s_gif_interlace_step[img_pass_num]; - if (gif_image_ptr->image_row_num >= - static_cast<int32_t>(gif_image_ptr->m_ImageInfo.height)) { - img_pass_num++; - if (img_pass_num == FX_ArraySize(s_gif_interlace_step)) { - DecodingFailureAtTailCleanup(gif_image_ptr); - return GifDecodeStatus::Error; - } - gif_image_ptr->image_row_num = - s_gif_interlace_step[img_pass_num] / 2; - } - } else { - ReadScanline(gif_image_ptr->image_row_num++, - gif_image_ptr->m_ImageRowBuf.data()); - } - img_row_offset = 0; - img_row_avail_size = gif_img_row_bytes; - ret = m_ImgDecoder.get() - ? m_ImgDecoder->Decode( - data_ptr, *data_size_ptr, - gif_image_ptr->m_ImageRowBuf.data() + img_row_offset, - &img_row_avail_size) - : GifDecodeStatus::Error; - } - if (ret == GifDecodeStatus::Error) { - DecodingFailureAtTailCleanup(gif_image_ptr); - return GifDecodeStatus::Error; - } - } - } - SaveDecodingStatus(GIF_D_STATUS_TAIL); - } - return GifDecodeStatus::Error; -} - -void CGifContext::SetInputBuffer(uint8_t* src_buf, uint32_t src_size) { - next_in = src_buf; - avail_in = src_size; - skip_size = 0; -} - -uint32_t CGifContext::GetAvailInput(uint8_t** avail_buf_ptr) const { - if (avail_buf_ptr) { - *avail_buf_ptr = nullptr; - if (avail_in > 0) - *avail_buf_ptr = next_in; - } - return avail_in; -} - -int32_t CGifContext::GetFrameNum() const { - return pdfium::CollectionSize<int32_t>(m_Images); -} - -uint8_t* CGifContext::ReadData(uint8_t** des_buf_pp, uint32_t data_size) { - if (avail_in < skip_size + data_size) - return nullptr; - - *des_buf_pp = next_in + skip_size; - skip_size += data_size; - return *des_buf_pp; -} - -void CGifContext::SaveDecodingStatus(int32_t status) { - decode_status = status; - next_in += skip_size; - avail_in -= skip_size; - skip_size = 0; -} - -GifDecodeStatus CGifContext::DecodeExtension() { - uint8_t* data_size_ptr = nullptr; - uint8_t* data_ptr = nullptr; - uint32_t skip_size_org = skip_size; - switch (decode_status) { - case GIF_D_STATUS_EXT_CE: { - if (!ReadData(&data_size_ptr, 1)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - - cmt_data.clear(); - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - uint8_t data_size = *data_size_ptr; - if (!ReadData(&data_ptr, *data_size_ptr) || - !ReadData(&data_size_ptr, 1)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - - cmt_data += ByteString(data_ptr, data_size); - } - break; - } - case GIF_D_STATUS_EXT_PTE: { - GifPlainTextExtension* gif_pte = nullptr; - if (!ReadData(reinterpret_cast<uint8_t**>(&gif_pte), 13)) - return GifDecodeStatus::Unfinished; - - m_GraphicControlExtension = nullptr; - if (!ReadData(&data_size_ptr, 1)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (!ReadData(&data_ptr, *data_size_ptr) || - !ReadData(&data_size_ptr, 1)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - } - break; - } - case GIF_D_STATUS_EXT_GCE: { - GifGraphicControlExtension* gif_gce_ptr = nullptr; - if (!ReadData(reinterpret_cast<uint8_t**>(&gif_gce_ptr), 6)) - return GifDecodeStatus::Unfinished; - - if (!m_GraphicControlExtension.get()) - m_GraphicControlExtension = - pdfium::MakeUnique<GifGraphicControlExtension>(); - m_GraphicControlExtension->block_size = gif_gce_ptr->block_size; - m_GraphicControlExtension->gce_flags = gif_gce_ptr->gce_flags; - m_GraphicControlExtension->delay_time = GetWord_LSBFirst( - reinterpret_cast<uint8_t*>(&gif_gce_ptr->delay_time)); - m_GraphicControlExtension->trans_index = gif_gce_ptr->trans_index; - break; - } - default: { - if (decode_status == GIF_D_STATUS_EXT_PTE) - m_GraphicControlExtension = nullptr; - if (!ReadData(&data_size_ptr, 1)) - return GifDecodeStatus::Unfinished; - - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (!ReadData(&data_ptr, *data_size_ptr) || - !ReadData(&data_size_ptr, 1)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - } - } - } - SaveDecodingStatus(GIF_D_STATUS_SIG); - return GifDecodeStatus::Success; -} - -GifDecodeStatus CGifContext::DecodeImageInfo() { - if (width == 0 || height == 0) - return GifDecodeStatus::Error; - - uint32_t skip_size_org = skip_size; - GifImageInfo* gif_img_info_ptr = nullptr; - if (!ReadData(reinterpret_cast<uint8_t**>(&gif_img_info_ptr), 9)) - return GifDecodeStatus::Unfinished; - - auto gif_image = pdfium::MakeUnique<GifImage>(); - gif_image->m_ImageInfo.left = - GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->left)); - gif_image->m_ImageInfo.top = - GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->top)); - gif_image->m_ImageInfo.width = - GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->width)); - gif_image->m_ImageInfo.height = - GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->height)); - gif_image->m_ImageInfo.local_flags = gif_img_info_ptr->local_flags; - if (gif_image->m_ImageInfo.left + gif_image->m_ImageInfo.width > width || - gif_image->m_ImageInfo.top + gif_image->m_ImageInfo.height > height) - return GifDecodeStatus::Error; - - GifLocalFlags* gif_img_info_lf_ptr = &gif_img_info_ptr->local_flags; - if (gif_img_info_lf_ptr->local_pal) { - gif_image->local_pallette_exp = gif_img_info_lf_ptr->pal_bits; - uint32_t loc_pal_size = unsigned(2 << gif_img_info_lf_ptr->pal_bits) * 3u; - uint8_t* loc_pal_ptr = nullptr; - if (!ReadData(&loc_pal_ptr, loc_pal_size)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - - gif_image->m_LocalPalettes = std::vector<GifPalette>(loc_pal_size / 3); - std::copy(loc_pal_ptr, loc_pal_ptr + loc_pal_size, - reinterpret_cast<uint8_t*>(gif_image->m_LocalPalettes.data())); - } - - uint8_t* code_size_ptr = nullptr; - if (!ReadData(&code_size_ptr, 1)) { - skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - - gif_image->image_code_exp = *code_size_ptr; - RecordCurrentPosition(&gif_image->image_data_pos); - gif_image->image_data_pos += skip_size; - gif_image->m_ImageGCE = nullptr; - if (m_GraphicControlExtension.get()) { - gif_image->m_ImageGCE = std::move(m_GraphicControlExtension); - m_GraphicControlExtension = nullptr; - } - m_Images.push_back(std::move(gif_image)); - SaveDecodingStatus(GIF_D_STATUS_IMG_DATA); - return GifDecodeStatus::Success; -} - -void CGifContext::DecodingFailureAtTailCleanup(GifImage* gif_image_ptr) { - gif_image_ptr->m_ImageRowBuf.clear(); - SaveDecodingStatus(GIF_D_STATUS_TAIL); -} diff --git a/core/fxcodec/lgif/cgifcontext.h b/core/fxcodec/lgif/cgifcontext.h deleted file mode 100644 index 2573a2e470..0000000000 --- a/core/fxcodec/lgif/cgifcontext.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2017 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FXCODEC_LGIF_CGIFCONTEXT_H_ -#define CORE_FXCODEC_LGIF_CGIFCONTEXT_H_ - -#include <memory> -#include <vector> - -#include "core/fxcodec/codec/ccodec_gifmodule.h" -#include "core/fxcodec/lgif/cfx_lzwdecoder.h" -#include "core/fxcodec/lgif/fx_gif.h" -#include "core/fxcrt/fx_string.h" -#include "core/fxcrt/unowned_ptr.h" - -class CGifContext : public CCodec_GifModule::Context { - public: - CGifContext(CCodec_GifModule* gif_module, - CCodec_GifModule::Delegate* pDelegate); - ~CGifContext() override; - - void RecordCurrentPosition(uint32_t* cur_pos_ptr); - void ReadScanline(int32_t row_num, uint8_t* row_buf); - bool GetRecordPosition(uint32_t cur_pos, - int32_t left, - int32_t top, - int32_t width, - int32_t height, - int32_t pal_num, - GifPalette* pal_ptr, - int32_t delay_time, - bool user_input, - int32_t trans_index, - int32_t disposal_method, - bool interlace); - GifDecodeStatus ReadHeader(); - GifDecodeStatus GetFrame(); - GifDecodeStatus LoadFrame(int32_t frame_num); - void SetInputBuffer(uint8_t* src_buf, uint32_t src_size); - uint32_t GetAvailInput(uint8_t** avail_buf_ptr) const; - int32_t GetFrameNum() const; - - UnownedPtr<CCodec_GifModule> m_pModule; - UnownedPtr<CCodec_GifModule::Delegate> m_pDelegate; - std::vector<GifPalette> m_GlobalPalette; - uint8_t global_pal_exp; - uint32_t img_row_offset; - uint32_t img_row_avail_size; - uint32_t avail_in; - int32_t decode_status; - uint32_t skip_size; - ByteString cmt_data; - std::unique_ptr<GifGraphicControlExtension> m_GraphicControlExtension; - uint8_t* next_in; - std::vector<std::unique_ptr<GifImage>> m_Images; - std::unique_ptr<CFX_LZWDecoder> m_ImgDecoder; - int width; - int height; - uint8_t bc_index; - uint8_t pixel_aspect; - uint8_t global_sort_flag; - uint8_t global_color_resolution; - uint8_t img_pass_num; - - private: - uint8_t* ReadData(uint8_t** des_buf_pp, uint32_t data_size); - void SaveDecodingStatus(int32_t status); - GifDecodeStatus DecodeExtension(); - GifDecodeStatus DecodeImageInfo(); - void DecodingFailureAtTailCleanup(GifImage* gif_image_ptr); -}; - -#endif // CORE_FXCODEC_LGIF_CGIFCONTEXT_H_ diff --git a/core/fxcodec/lgif/fx_gif.cpp b/core/fxcodec/lgif/fx_gif.cpp deleted file mode 100644 index b8e5cb8994..0000000000 --- a/core/fxcodec/lgif/fx_gif.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fxcodec/lgif/fx_gif.h" - -static_assert(sizeof(GifImageInfo) == 9, - "GifImageInfo should have a size of 9"); -static_assert(sizeof(GifPalette) == 3, "GifPalette should have a size of 3"); -static_assert(sizeof(GifPlainTextExtension) == 13, - "GifPlainTextExtension should have a size of 13"); -static_assert(sizeof(GifGraphicControlExtension) == 5, - "GifGraphicControlExtension should have a size of 5"); -static_assert(sizeof(GifHeader) == 6, "GifHeader should have a size of 6"); -static_assert(sizeof(GifLocalScreenDescriptor) == 7, - "GifLocalScreenDescriptor should have a size of 7"); diff --git a/core/fxcodec/lgif/fx_gif.h b/core/fxcodec/lgif/fx_gif.h deleted file mode 100644 index 08a64c8326..0000000000 --- a/core/fxcodec/lgif/fx_gif.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FXCODEC_LGIF_FX_GIF_H_ -#define CORE_FXCODEC_LGIF_FX_GIF_H_ - -#include <memory> -#include <vector> - -class CGifContext; - -#define GIF_SIGNATURE "GIF" -#define GIF_SIG_EXTENSION 0x21 -#define GIF_SIG_IMAGE 0x2C -#define GIF_SIG_TRAILER 0x3B -#define GIF_BLOCK_GCE 0xF9 -#define GIF_BLOCK_PTE 0x01 -#define GIF_BLOCK_CE 0xFE -#define GIF_BLOCK_AE 0xFF -#define GIF_BLOCK_TERMINAL 0x00 -#define GIF_MAX_LZW_EXP 12 -#define GIF_MAX_LZW_CODE 4096 -#define GIF_DATA_BLOCK 255 -#define GIF_MAX_ERROR_SIZE 256 -#define GIF_D_STATUS_SIG 0x01 -#define GIF_D_STATUS_TAIL 0x02 -#define GIF_D_STATUS_EXT 0x03 -#define GIF_D_STATUS_EXT_AE 0x04 -#define GIF_D_STATUS_EXT_CE 0x05 -#define GIF_D_STATUS_EXT_GCE 0x06 -#define GIF_D_STATUS_EXT_PTE 0x07 -#define GIF_D_STATUS_EXT_UNE 0x08 -#define GIF_D_STATUS_IMG_INFO 0x09 -#define GIF_D_STATUS_IMG_DATA 0x0A - -#pragma pack(1) -typedef struct { - uint8_t pal_bits : 3; - uint8_t sort_flag : 1; - uint8_t color_resolution : 3; - uint8_t global_pal : 1; -} GifGlobalFlags; - -typedef struct { - uint8_t pal_bits : 3; - uint8_t reserved : 2; - uint8_t sort_flag : 1; - uint8_t interlace : 1; - uint8_t local_pal : 1; -} GifLocalFlags; - -typedef struct { - char signature[3]; - char version[3]; -} GifHeader; - -typedef struct { - uint16_t width; - uint16_t height; - GifGlobalFlags global_flags; - uint8_t bc_index; - uint8_t pixel_aspect; -} GifLocalScreenDescriptor; - -typedef struct { - uint16_t left; - uint16_t top; - uint16_t width; - uint16_t height; - GifLocalFlags local_flags; -} GifImageInfo; - -typedef struct { - uint8_t transparency : 1; - uint8_t user_input : 1; - uint8_t disposal_method : 3; - uint8_t reserved : 3; -} GifControlExtensionFlags; - -typedef struct { - uint8_t block_size; - GifControlExtensionFlags gce_flags; - uint16_t delay_time; - uint8_t trans_index; -} GifGraphicControlExtension; - -typedef struct { - uint8_t block_size; - uint16_t grid_left; - uint16_t grid_top; - uint16_t grid_width; - uint16_t grid_height; - - uint8_t char_width; - uint8_t char_height; - - uint8_t fc_index; - uint8_t bc_index; -} GifPlainTextExtension; - -typedef struct { - uint8_t block_size; - uint8_t app_identify[8]; - uint8_t app_authentication[3]; -} GifApplicationExtension; - -typedef struct { uint8_t r, g, b; } GifPalette; -#pragma pack() - -enum class GifDecodeStatus { - Error, - Success, - Unfinished, - InsufficientDestSize, // Only used internally by CGifLZWDecoder::Decode() -}; - -typedef struct { - std::unique_ptr<GifGraphicControlExtension> m_ImageGCE; - std::vector<GifPalette> m_LocalPalettes; - std::vector<uint8_t> m_ImageRowBuf; - GifImageInfo m_ImageInfo; - uint8_t local_pallette_exp; - uint8_t image_code_exp; - uint32_t image_data_pos; - int32_t image_row_num; -} GifImage; - -#endif // CORE_FXCODEC_LGIF_FX_GIF_H_ |