summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn14
-rw-r--r--core/fxcodec/codec/ccodec_gifmodule.cpp80
-rw-r--r--core/fxcodec/codec/ccodec_gifmodule.h24
-rw-r--r--core/fxcodec/codec/fx_codec_progress.cpp18
-rw-r--r--core/fxcodec/gif/cfx_gif.cpp20
-rw-r--r--core/fxcodec/gif/cfx_gif.h (renamed from core/fxcodec/lgif/fx_gif.h)50
-rw-r--r--core/fxcodec/gif/cfx_gifcontext.cpp537
-rw-r--r--core/fxcodec/gif/cfx_gifcontext.h76
-rw-r--r--core/fxcodec/gif/cfx_lzwdecompressor.cpp (renamed from core/fxcodec/lgif/cfx_lzwdecoder.cpp)57
-rw-r--r--core/fxcodec/gif/cfx_lzwdecompressor.h (renamed from core/fxcodec/lgif/cfx_lzwdecoder.h)26
-rw-r--r--core/fxcodec/gif/cfx_lzwdecompressor_unittest.cpp (renamed from core/fxcodec/lgif/cfx_lzwdecoder_unittest.cpp)46
-rw-r--r--core/fxcodec/lgif/cgifcontext.cpp549
-rw-r--r--core/fxcodec/lgif/cgifcontext.h76
-rw-r--r--core/fxcodec/lgif/fx_gif.cpp18
14 files changed, 791 insertions, 800 deletions
diff --git a/BUILD.gn b/BUILD.gn
index ac244883bc..25c805ccb7 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -775,14 +775,14 @@ static_library("fxcodec") {
"core/fxcodec/codec/ccodec_tiffmodule.cpp",
"core/fxcodec/codec/ccodec_tiffmodule.h",
"core/fxcodec/codec/fx_codec_progress.cpp",
+ "core/fxcodec/gif/cfx_gif.cpp",
+ "core/fxcodec/gif/cfx_gif.h",
+ "core/fxcodec/gif/cfx_gifcontext.cpp",
+ "core/fxcodec/gif/cfx_gifcontext.h",
+ "core/fxcodec/gif/cfx_lzwdecompressor.cpp",
+ "core/fxcodec/gif/cfx_lzwdecompressor.h",
"core/fxcodec/lbmp/fx_bmp.cpp",
"core/fxcodec/lbmp/fx_bmp.h",
- "core/fxcodec/lgif/cfx_lzwdecoder.cpp",
- "core/fxcodec/lgif/cfx_lzwdecoder.h",
- "core/fxcodec/lgif/cgifcontext.cpp",
- "core/fxcodec/lgif/cgifcontext.h",
- "core/fxcodec/lgif/fx_gif.cpp",
- "core/fxcodec/lgif/fx_gif.h",
]
deps += [
"third_party:fx_lpng",
@@ -1950,7 +1950,7 @@ test("pdfium_unittests") {
include_dirs = []
if (pdf_enable_xfa) {
sources += [
- "core/fxcodec/lgif/cfx_lzwdecoder_unittest.cpp",
+ "core/fxcodec/gif/cfx_lzwdecompressor_unittest.cpp",
"core/fxcrt/css/cfx_cssdeclaration_unittest.cpp",
"core/fxcrt/css/cfx_cssstylesheet_unittest.cpp",
"core/fxcrt/css/cfx_cssvaluelistparser_unittest.cpp",
diff --git a/core/fxcodec/codec/ccodec_gifmodule.cpp b/core/fxcodec/codec/ccodec_gifmodule.cpp
index b7e55d5208..0567af06ea 100644
--- a/core/fxcodec/codec/ccodec_gifmodule.cpp
+++ b/core/fxcodec/codec/ccodec_gifmodule.cpp
@@ -8,8 +8,8 @@
#include "core/fxcodec/codec/codec_int.h"
#include "core/fxcodec/fx_codec.h"
-#include "core/fxcodec/lgif/cgifcontext.h"
-#include "core/fxcodec/lgif/fx_gif.h"
+#include "core/fxcodec/gif/cfx_gif.h"
+#include "core/fxcodec/gif/cfx_gifcontext.h"
#include "core/fxge/fx_dib.h"
#include "third_party/base/ptr_util.h"
@@ -19,55 +19,55 @@ CCodec_GifModule::~CCodec_GifModule() {}
std::unique_ptr<CCodec_GifModule::Context> CCodec_GifModule::Start(
Delegate* pDelegate) {
- return pdfium::MakeUnique<CGifContext>(this, pDelegate);
+ return pdfium::MakeUnique<CFX_GifContext>(this, pDelegate);
}
-GifDecodeStatus CCodec_GifModule::ReadHeader(Context* pContext,
- int* width,
- int* height,
- int* pal_num,
- void** pal_pp,
- int* bg_index,
- CFX_DIBAttribute* pAttribute) {
- auto* context = static_cast<CGifContext*>(pContext);
- GifDecodeStatus ret = context->ReadHeader();
- if (ret != GifDecodeStatus::Success)
+CFX_GifDecodeStatus CCodec_GifModule::ReadHeader(Context* pContext,
+ int* width,
+ int* height,
+ int* pal_num,
+ void** pal_pp,
+ int* bg_index,
+ CFX_DIBAttribute* pAttribute) {
+ auto* context = static_cast<CFX_GifContext*>(pContext);
+ CFX_GifDecodeStatus ret = context->ReadHeader();
+ if (ret != CFX_GifDecodeStatus::Success)
return ret;
- *width = context->width;
- *height = context->height;
- *pal_num = (2 << context->global_pal_exp);
- *pal_pp = context->m_GlobalPalette.empty() ? nullptr
- : context->m_GlobalPalette.data();
- *bg_index = context->bc_index;
- return GifDecodeStatus::Success;
+ *width = context->width_;
+ *height = context->height_;
+ *pal_num = (2 << context->global_pal_exp_);
+ *pal_pp = context->global_palette_.empty() ? nullptr
+ : context->global_palette_.data();
+ *bg_index = context->bc_index_;
+ return CFX_GifDecodeStatus::Success;
}
-GifDecodeStatus CCodec_GifModule::LoadFrameInfo(Context* pContext,
- int* frame_num) {
- auto* context = static_cast<CGifContext*>(pContext);
- GifDecodeStatus ret = context->GetFrame();
- if (ret != GifDecodeStatus::Success)
+CFX_GifDecodeStatus CCodec_GifModule::LoadFrameInfo(Context* pContext,
+ int* frame_num) {
+ auto* context = static_cast<CFX_GifContext*>(pContext);
+ CFX_GifDecodeStatus ret = context->GetFrame();
+ if (ret != CFX_GifDecodeStatus::Success)
return ret;
*frame_num = context->GetFrameNum();
- return GifDecodeStatus::Success;
+ return CFX_GifDecodeStatus::Success;
}
-GifDecodeStatus CCodec_GifModule::LoadFrame(Context* pContext,
- int frame_num,
- CFX_DIBAttribute* pAttribute) {
- auto* context = static_cast<CGifContext*>(pContext);
- GifDecodeStatus ret = context->LoadFrame(frame_num);
- if (ret != GifDecodeStatus::Success || !pAttribute)
+CFX_GifDecodeStatus CCodec_GifModule::LoadFrame(Context* pContext,
+ int frame_num,
+ CFX_DIBAttribute* pAttribute) {
+ auto* context = static_cast<CFX_GifContext*>(pContext);
+ CFX_GifDecodeStatus ret = context->LoadFrame(frame_num);
+ if (ret != CFX_GifDecodeStatus::Success || !pAttribute)
return ret;
- pAttribute->m_nGifLeft = context->m_Images[frame_num]->m_ImageInfo.left;
- pAttribute->m_nGifTop = context->m_Images[frame_num]->m_ImageInfo.top;
- pAttribute->m_fAspectRatio = context->pixel_aspect;
+ pAttribute->m_nGifLeft = context->images_[frame_num]->image_info.left;
+ pAttribute->m_nGifTop = context->images_[frame_num]->image_info.top;
+ pAttribute->m_fAspectRatio = context->pixel_aspect_;
const uint8_t* buf =
- reinterpret_cast<const uint8_t*>(context->cmt_data.GetBuffer(0));
- uint32_t len = context->cmt_data.GetLength();
+ reinterpret_cast<const uint8_t*>(context->cmt_data_.GetBuffer(0));
+ uint32_t len = context->cmt_data_.GetLength();
if (len > 21) {
uint8_t size = *buf++;
if (size != 0)
@@ -75,18 +75,18 @@ GifDecodeStatus CCodec_GifModule::LoadFrame(Context* pContext,
else
pAttribute->m_strAuthor.clear();
}
- return GifDecodeStatus::Success;
+ return CFX_GifDecodeStatus::Success;
}
uint32_t CCodec_GifModule::GetAvailInput(Context* pContext,
uint8_t** avail_buf_ptr) {
- auto* context = static_cast<CGifContext*>(pContext);
+ auto* context = static_cast<CFX_GifContext*>(pContext);
return context->GetAvailInput(avail_buf_ptr);
}
void CCodec_GifModule::Input(Context* pContext,
const uint8_t* src_buf,
uint32_t src_size) {
- auto* context = static_cast<CGifContext*>(pContext);
+ auto* context = static_cast<CFX_GifContext*>(pContext);
context->SetInputBuffer((uint8_t*)src_buf, src_size);
}
diff --git a/core/fxcodec/codec/ccodec_gifmodule.h b/core/fxcodec/codec/ccodec_gifmodule.h
index fe1c46478d..886c902bba 100644
--- a/core/fxcodec/codec/ccodec_gifmodule.h
+++ b/core/fxcodec/codec/ccodec_gifmodule.h
@@ -9,7 +9,7 @@
#include <memory>
-#include "core/fxcodec/lgif/fx_gif.h"
+#include "core/fxcodec/gif/cfx_gif.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_system.h"
@@ -43,17 +43,17 @@ class CCodec_GifModule {
std::unique_ptr<Context> Start(Delegate* pDelegate);
uint32_t GetAvailInput(Context* context, uint8_t** avail_buf_ptr = nullptr);
void Input(Context* context, const uint8_t* src_buf, uint32_t src_size);
- GifDecodeStatus ReadHeader(Context* context,
- int* width,
- int* height,
- int* pal_num,
- void** pal_pp,
- int* bg_index,
- CFX_DIBAttribute* pAttribute);
- GifDecodeStatus LoadFrameInfo(Context* context, int* frame_num);
- GifDecodeStatus LoadFrame(Context* context,
- int frame_num,
- CFX_DIBAttribute* pAttribute);
+ CFX_GifDecodeStatus ReadHeader(Context* context,
+ int* width,
+ int* height,
+ int* pal_num,
+ void** pal_pp,
+ int* bg_index,
+ CFX_DIBAttribute* pAttribute);
+ CFX_GifDecodeStatus LoadFrameInfo(Context* context, int* frame_num);
+ CFX_GifDecodeStatus LoadFrame(Context* context,
+ int frame_num,
+ CFX_DIBAttribute* pAttribute);
};
#endif // CORE_FXCODEC_CODEC_CCODEC_GIFMODULE_H_
diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp
index d28277173e..746a574bbc 100644
--- a/core/fxcodec/codec/fx_codec_progress.cpp
+++ b/core/fxcodec/codec/fx_codec_progress.cpp
@@ -1203,10 +1203,10 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType,
m_offSet += size;
pGifModule->Input(m_pGifContext.get(), m_pSrcBuf, size);
m_SrcComponents = 1;
- GifDecodeStatus readResult = pGifModule->ReadHeader(
+ CFX_GifDecodeStatus readResult = pGifModule->ReadHeader(
m_pGifContext.get(), &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber,
(void**)&m_pGifPalette, &m_GifBgIndex, nullptr);
- while (readResult == GifDecodeStatus::Unfinished) {
+ while (readResult == CFX_GifDecodeStatus::Unfinished) {
FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
if (!GifReadMoreData(pGifModule, error_status)) {
m_pGifContext = nullptr;
@@ -1217,7 +1217,7 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType,
m_pGifContext.get(), &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber,
(void**)&m_pGifPalette, &m_GifBgIndex, nullptr);
}
- if (readResult == GifDecodeStatus::Success) {
+ if (readResult == CFX_GifDecodeStatus::Success) {
m_SrcBPC = 8;
m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
return true;
@@ -1815,9 +1815,9 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t* frames) {
return m_status;
}
while (true) {
- GifDecodeStatus readResult =
+ CFX_GifDecodeStatus readResult =
pGifModule->LoadFrameInfo(m_pGifContext.get(), &m_FrameNumber);
- while (readResult == GifDecodeStatus::Unfinished) {
+ while (readResult == CFX_GifDecodeStatus::Unfinished) {
FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ;
if (!GifReadMoreData(pGifModule, error_status))
return error_status;
@@ -1825,7 +1825,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t* frames) {
readResult =
pGifModule->LoadFrameInfo(m_pGifContext.get(), &m_FrameNumber);
}
- if (readResult == GifDecodeStatus::Success) {
+ if (readResult == CFX_GifDecodeStatus::Success) {
*frames = m_FrameNumber;
m_status = FXCODEC_STATUS_DECODE_READY;
return m_status;
@@ -2118,9 +2118,9 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode() {
return m_status;
}
- GifDecodeStatus readRes =
+ CFX_GifDecodeStatus readRes =
pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr);
- while (readRes == GifDecodeStatus::Unfinished) {
+ while (readRes == CFX_GifDecodeStatus::Unfinished) {
FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
if (!GifReadMoreData(pGifModule, error_status)) {
m_pDeviceBitmap = nullptr;
@@ -2132,7 +2132,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode() {
pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr);
}
- if (readRes == GifDecodeStatus::Success) {
+ if (readRes == CFX_GifDecodeStatus::Success) {
m_pDeviceBitmap = nullptr;
m_pFile = nullptr;
m_status = FXCODEC_STATUS_DECODE_FINISH;
diff --git a/core/fxcodec/gif/cfx_gif.cpp b/core/fxcodec/gif/cfx_gif.cpp
new file mode 100644
index 0000000000..c3c5c85323
--- /dev/null
+++ b/core/fxcodec/gif/cfx_gif.cpp
@@ -0,0 +1,20 @@
+// 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/gif/cfx_gif.h"
+
+static_assert(sizeof(CFX_CFX_GifImageInfo) == 9,
+ "CFX_CFX_GifImageInfo should have a size of 9");
+static_assert(sizeof(CFX_GifPalette) == 3,
+ "CFX_GifPalette should have a size of 3");
+static_assert(sizeof(CFX_GifPlainTextExtension) == 13,
+ "CFX_GifPlainTextExtension should have a size of 13");
+static_assert(sizeof(CFX_GifGraphicControlExtension) == 5,
+ "CFX_GifGraphicControlExtension should have a size of 5");
+static_assert(sizeof(CFX_GifHeader) == 6,
+ "CFX_GifHeader should have a size of 6");
+static_assert(sizeof(CFX_GifLocalScreenDescriptor) == 7,
+ "CFX_GifLocalScreenDescriptor should have a size of 7");
diff --git a/core/fxcodec/lgif/fx_gif.h b/core/fxcodec/gif/cfx_gif.h
index 08a64c8326..02a4862017 100644
--- a/core/fxcodec/lgif/fx_gif.h
+++ b/core/fxcodec/gif/cfx_gif.h
@@ -4,13 +4,13 @@
// 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_
+#ifndef CORE_FXCODEC_GIF_CFX_GIF_H_
+#define CORE_FXCODEC_GIF_CFX_GIF_H_
#include <memory>
#include <vector>
-class CGifContext;
+class CFX_GifContext;
#define GIF_SIGNATURE "GIF"
#define GIF_SIG_EXTENSION 0x21
@@ -42,7 +42,7 @@ typedef struct {
uint8_t sort_flag : 1;
uint8_t color_resolution : 3;
uint8_t global_pal : 1;
-} GifGlobalFlags;
+} CFX_GifGlobalFlags;
typedef struct {
uint8_t pal_bits : 3;
@@ -50,42 +50,42 @@ typedef struct {
uint8_t sort_flag : 1;
uint8_t interlace : 1;
uint8_t local_pal : 1;
-} GifLocalFlags;
+} CFX_GifLocalFlags;
typedef struct {
char signature[3];
char version[3];
-} GifHeader;
+} CFX_GifHeader;
typedef struct {
uint16_t width;
uint16_t height;
- GifGlobalFlags global_flags;
+ CFX_GifGlobalFlags global_flags;
uint8_t bc_index;
uint8_t pixel_aspect;
-} GifLocalScreenDescriptor;
+} CFX_GifLocalScreenDescriptor;
typedef struct {
uint16_t left;
uint16_t top;
uint16_t width;
uint16_t height;
- GifLocalFlags local_flags;
-} GifImageInfo;
+ CFX_GifLocalFlags local_flags;
+} CFX_CFX_GifImageInfo;
typedef struct {
uint8_t transparency : 1;
uint8_t user_input : 1;
uint8_t disposal_method : 3;
uint8_t reserved : 3;
-} GifControlExtensionFlags;
+} CFX_GifControlExtensionFlags;
typedef struct {
uint8_t block_size;
- GifControlExtensionFlags gce_flags;
+ CFX_GifControlExtensionFlags gce_flags;
uint16_t delay_time;
uint8_t trans_index;
-} GifGraphicControlExtension;
+} CFX_GifGraphicControlExtension;
typedef struct {
uint8_t block_size;
@@ -99,7 +99,7 @@ typedef struct {
uint8_t fc_index;
uint8_t bc_index;
-} GifPlainTextExtension;
+} CFX_GifPlainTextExtension;
typedef struct {
uint8_t block_size;
@@ -107,10 +107,10 @@ typedef struct {
uint8_t app_authentication[3];
} GifApplicationExtension;
-typedef struct { uint8_t r, g, b; } GifPalette;
+typedef struct { uint8_t r, g, b; } CFX_GifPalette;
#pragma pack()
-enum class GifDecodeStatus {
+enum class CFX_GifDecodeStatus {
Error,
Success,
Unfinished,
@@ -118,14 +118,14 @@ enum class GifDecodeStatus {
};
typedef struct {
- std::unique_ptr<GifGraphicControlExtension> m_ImageGCE;
- std::vector<GifPalette> m_LocalPalettes;
- std::vector<uint8_t> m_ImageRowBuf;
- GifImageInfo m_ImageInfo;
+ std::unique_ptr<CFX_GifGraphicControlExtension> image_GCE;
+ std::vector<CFX_GifPalette> local_palettes;
+ std::vector<uint8_t> row_buffer;
+ CFX_CFX_GifImageInfo image_info;
uint8_t local_pallette_exp;
- uint8_t image_code_exp;
- uint32_t image_data_pos;
- int32_t image_row_num;
-} GifImage;
+ uint8_t code_exp;
+ uint32_t data_pos;
+ int32_t row_num;
+} CFX_GifImage;
-#endif // CORE_FXCODEC_LGIF_FX_GIF_H_
+#endif // CORE_FXCODEC_GIF_CFX_GIF_H_
diff --git a/core/fxcodec/gif/cfx_gifcontext.cpp b/core/fxcodec/gif/cfx_gifcontext.cpp
new file mode 100644
index 0000000000..a882a58bd2
--- /dev/null
+++ b/core/fxcodec/gif/cfx_gifcontext.cpp
@@ -0,0 +1,537 @@
+// 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/gif/cfx_gifcontext.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "core/fxcodec/codec/ccodec_gifmodule.h"
+#include "core/fxcodec/gif/cfx_gif.h"
+#include "core/fxcodec/lbmp/fx_bmp.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
+
+CFX_GifContext::CFX_GifContext(CCodec_GifModule* gif_module,
+ CCodec_GifModule::Delegate* delegate)
+ : gif_module_(gif_module),
+ delegate_(delegate),
+ 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) {}
+
+CFX_GifContext::~CFX_GifContext() {}
+
+void CFX_GifContext::RecordCurrentPosition(uint32_t* cur_pos) {
+ delegate_->GifRecordCurrentPosition(*cur_pos);
+}
+
+void CFX_GifContext::ReadScanline(int32_t row_num, uint8_t* row_buf) {
+ delegate_->GifReadScanline(row_num, row_buf);
+}
+
+bool CFX_GifContext::GetRecordPosition(uint32_t cur_pos,
+ int32_t left,
+ int32_t top,
+ int32_t width,
+ int32_t height,
+ int32_t pal_num,
+ CFX_GifPalette* pal,
+ int32_t delay_time,
+ bool user_input,
+ int32_t trans_index,
+ int32_t disposal_method,
+ bool interlace) {
+ return delegate_->GifInputRecordPositionBuf(
+ cur_pos, FX_RECT(left, top, left + width, top + height), pal_num, pal,
+ delay_time, user_input, trans_index, disposal_method, interlace);
+}
+
+CFX_GifDecodeStatus CFX_GifContext::ReadHeader() {
+ uint32_t skip_size_org = skip_size_;
+ CFX_GifHeader* gif_header = nullptr;
+ if (!ReadData(reinterpret_cast<uint8_t**>(&gif_header), 6))
+ return CFX_GifDecodeStatus::Unfinished;
+
+ if (strncmp(gif_header->signature, GIF_SIGNATURE, 3) != 0 ||
+ gif_header->version[0] != '8' || gif_header->version[2] != 'a')
+ return CFX_GifDecodeStatus::Error;
+
+ CFX_GifLocalScreenDescriptor* gif_lsd = nullptr;
+ if (!ReadData(reinterpret_cast<uint8_t**>(&gif_lsd), 7)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ if (gif_lsd->global_flags.global_pal) {
+ global_pal_exp_ = gif_lsd->global_flags.pal_bits;
+ uint32_t global_pal_size = unsigned(2 << global_pal_exp_) * 3u;
+ uint8_t* global_pal = nullptr;
+ if (!ReadData(&global_pal, global_pal_size)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ global_sort_flag_ = gif_lsd->global_flags.sort_flag;
+ global_color_resolution_ = gif_lsd->global_flags.color_resolution;
+ global_palette_.resize(global_pal_size / 3);
+ memcpy(global_palette_.data(), global_pal, global_pal_size);
+ }
+
+ width_ = static_cast<int>(
+ GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_lsd->width)));
+ height_ = static_cast<int>(
+ GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_lsd->height)));
+ bc_index_ = gif_lsd->bc_index;
+ pixel_aspect_ = gif_lsd->pixel_aspect;
+ return CFX_GifDecodeStatus::Success;
+}
+
+CFX_GifDecodeStatus CFX_GifContext::GetFrame() {
+ CFX_GifDecodeStatus ret = CFX_GifDecodeStatus::Success;
+ while (true) {
+ switch (decode_status_) {
+ case GIF_D_STATUS_TAIL:
+ return CFX_GifDecodeStatus::Success;
+ case GIF_D_STATUS_SIG: {
+ uint8_t* signature = nullptr;
+ if (!ReadData(&signature, 1))
+ return CFX_GifDecodeStatus::Unfinished;
+
+ switch (*signature) {
+ 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 CFX_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 CFX_GifDecodeStatus::Success;
+ }
+ }
+ case GIF_D_STATUS_EXT: {
+ uint8_t* extension = nullptr;
+ if (!ReadData(&extension, 1))
+ return CFX_GifDecodeStatus::Unfinished;
+
+ switch (*extension) {
+ 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 (*extension == GIF_BLOCK_PTE) {
+ status = GIF_D_STATUS_EXT_PTE;
+ }
+ SaveDecodingStatus(status);
+ continue;
+ }
+ }
+ }
+ case GIF_D_STATUS_IMG_INFO: {
+ ret = DecodeImageInfo();
+ if (ret != CFX_GifDecodeStatus::Success)
+ return ret;
+
+ continue;
+ }
+ case GIF_D_STATUS_IMG_DATA: {
+ uint8_t* img_data_size = nullptr;
+ uint8_t* img_data = nullptr;
+ uint32_t skip_size_org = skip_size_;
+ if (!ReadData(&img_data_size, 1))
+ return CFX_GifDecodeStatus::Unfinished;
+
+ while (*img_data_size != GIF_BLOCK_TERMINAL) {
+ if (!ReadData(&img_data, *img_data_size)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
+ skip_size_org = skip_size_;
+ if (!ReadData(&img_data_size, 1))
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+ SaveDecodingStatus(GIF_D_STATUS_SIG);
+ continue;
+ }
+ default: {
+ ret = DecodeExtension();
+ if (ret != CFX_GifDecodeStatus::Success)
+ return ret;
+ break;
+ }
+ }
+ }
+ return CFX_GifDecodeStatus::Success;
+}
+
+CFX_GifDecodeStatus CFX_GifContext::LoadFrame(int32_t frame_num) {
+ if (!pdfium::IndexInBounds(images_, frame_num))
+ return CFX_GifDecodeStatus::Error;
+
+ uint8_t* img_data_size = nullptr;
+ uint8_t* img_data = nullptr;
+ uint32_t skip_size_org = skip_size_;
+ CFX_GifImage* gif_image = images_[frame_num].get();
+ uint32_t gif_img_row_bytes = gif_image->image_info.width;
+ if (gif_img_row_bytes == 0)
+ return CFX_GifDecodeStatus::Error;
+
+ if (decode_status_ == GIF_D_STATUS_TAIL) {
+ gif_image->row_buffer.resize(gif_img_row_bytes);
+ CFX_GifGraphicControlExtension* gif_img_gce = gif_image->image_GCE.get();
+ int32_t loc_pal_num =
+ gif_image->image_info.local_flags.local_pal
+ ? (2 << gif_image->image_info.local_flags.pal_bits)
+ : 0;
+ avail_in_ = 0;
+ CFX_GifPalette* pLocalPalette = gif_image->local_palettes.empty()
+ ? nullptr
+ : gif_image->local_palettes.data();
+ if (!gif_img_gce) {
+ bool bRes = GetRecordPosition(
+ gif_image->data_pos, gif_image->image_info.left,
+ gif_image->image_info.top, gif_image->image_info.width,
+ gif_image->image_info.height, loc_pal_num, pLocalPalette, 0, 0, -1, 0,
+ gif_image->image_info.local_flags.interlace);
+ if (!bRes) {
+ gif_image->row_buffer.clear();
+ return CFX_GifDecodeStatus::Error;
+ }
+ } else {
+ bool bRes = GetRecordPosition(
+ gif_image->data_pos, gif_image->image_info.left,
+ gif_image->image_info.top, gif_image->image_info.width,
+ gif_image->image_info.height, loc_pal_num, pLocalPalette,
+ static_cast<int32_t>(gif_image->image_GCE->delay_time),
+ gif_image->image_GCE->gce_flags.user_input,
+ gif_image->image_GCE->gce_flags.transparency
+ ? static_cast<int32_t>(gif_image->image_GCE->trans_index)
+ : -1,
+ static_cast<int32_t>(gif_image->image_GCE->gce_flags.disposal_method),
+ gif_image->image_info.local_flags.interlace);
+ if (!bRes) {
+ gif_image->row_buffer.clear();
+ return CFX_GifDecodeStatus::Error;
+ }
+ }
+
+ if (gif_image->code_exp > GIF_MAX_LZW_EXP) {
+ gif_image->row_buffer.clear();
+ return CFX_GifDecodeStatus::Error;
+ }
+
+ img_row_offset_ = 0;
+ img_row_avail_size_ = 0;
+ img_pass_num_ = 0;
+ gif_image->row_num = 0;
+ SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
+ }
+
+ if (decode_status_ == GIF_D_STATUS_IMG_DATA) {
+ if (!ReadData(&img_data_size, 1))
+ return CFX_GifDecodeStatus::Unfinished;
+
+ if (*img_data_size != GIF_BLOCK_TERMINAL) {
+ if (!ReadData(&img_data, *img_data_size)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ if (!lzw_decompressor_.get())
+ lzw_decompressor_ = CFX_LZWDecompressor::Create(
+ !gif_image->local_palettes.empty() ? gif_image->local_pallette_exp
+ : global_pal_exp_,
+ gif_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_;
+ CFX_GifDecodeStatus ret =
+ lzw_decompressor_.get()
+ ? lzw_decompressor_->Decode(
+ img_data, *img_data_size,
+ gif_image->row_buffer.data() + img_row_offset_,
+ &img_row_avail_size_)
+ : CFX_GifDecodeStatus::Error;
+ if (ret == CFX_GifDecodeStatus::Error) {
+ DecodingFailureAtTailCleanup(gif_image);
+ return CFX_GifDecodeStatus::Error;
+ }
+ while (ret != CFX_GifDecodeStatus::Error) {
+ if (ret == CFX_GifDecodeStatus::Success) {
+ ReadScanline(gif_image->row_num, gif_image->row_buffer.data());
+ gif_image->row_buffer.clear();
+ SaveDecodingStatus(GIF_D_STATUS_TAIL);
+ return CFX_GifDecodeStatus::Success;
+ }
+ if (ret == CFX_GifDecodeStatus::Unfinished) {
+ skip_size_org = skip_size_;
+ if (!ReadData(&img_data_size, 1))
+ return CFX_GifDecodeStatus::Unfinished;
+
+ if (*img_data_size != GIF_BLOCK_TERMINAL) {
+ if (!ReadData(&img_data, *img_data_size)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+ if (!lzw_decompressor_.get())
+ lzw_decompressor_ = CFX_LZWDecompressor::Create(
+ !gif_image->local_palettes.empty()
+ ? gif_image->local_pallette_exp
+ : global_pal_exp_,
+ gif_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 = lzw_decompressor_.get()
+ ? lzw_decompressor_->Decode(
+ img_data, *img_data_size,
+ gif_image->row_buffer.data() + img_row_offset_,
+ &img_row_avail_size_)
+ : CFX_GifDecodeStatus::Error;
+ }
+ }
+ if (ret == CFX_GifDecodeStatus::InsufficientDestSize) {
+ if (gif_image->image_info.local_flags.interlace) {
+ ReadScanline(gif_image->row_num, gif_image->row_buffer.data());
+ gif_image->row_num += s_gif_interlace_step[img_pass_num_];
+ if (gif_image->row_num >=
+ static_cast<int32_t>(gif_image->image_info.height)) {
+ img_pass_num_++;
+ if (img_pass_num_ == FX_ArraySize(s_gif_interlace_step)) {
+ DecodingFailureAtTailCleanup(gif_image);
+ return CFX_GifDecodeStatus::Error;
+ }
+ gif_image->row_num = s_gif_interlace_step[img_pass_num_] / 2;
+ }
+ } else {
+ ReadScanline(gif_image->row_num++, gif_image->row_buffer.data());
+ }
+ img_row_offset_ = 0;
+ img_row_avail_size_ = gif_img_row_bytes;
+ ret = lzw_decompressor_.get()
+ ? lzw_decompressor_->Decode(
+ img_data, *img_data_size,
+ gif_image->row_buffer.data() + img_row_offset_,
+ &img_row_avail_size_)
+ : CFX_GifDecodeStatus::Error;
+ }
+ if (ret == CFX_GifDecodeStatus::Error) {
+ DecodingFailureAtTailCleanup(gif_image);
+ return CFX_GifDecodeStatus::Error;
+ }
+ }
+ }
+ SaveDecodingStatus(GIF_D_STATUS_TAIL);
+ }
+ return CFX_GifDecodeStatus::Error;
+}
+
+void CFX_GifContext::SetInputBuffer(uint8_t* src_buf, uint32_t src_size) {
+ next_in_ = src_buf;
+ avail_in_ = src_size;
+ skip_size_ = 0;
+}
+
+uint32_t CFX_GifContext::GetAvailInput(uint8_t** avail_buf) const {
+ if (avail_buf) {
+ *avail_buf = nullptr;
+ if (avail_in_ > 0)
+ *avail_buf = next_in_;
+ }
+ return avail_in_;
+}
+
+int32_t CFX_GifContext::GetFrameNum() const {
+ return pdfium::CollectionSize<int32_t>(images_);
+}
+
+uint8_t* CFX_GifContext::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 CFX_GifContext::SaveDecodingStatus(int32_t status) {
+ decode_status_ = status;
+ next_in_ += skip_size_;
+ avail_in_ -= skip_size_;
+ skip_size_ = 0;
+}
+
+CFX_GifDecodeStatus CFX_GifContext::DecodeExtension() {
+ uint8_t* data_size = nullptr;
+ uint8_t* data_buf = nullptr;
+ uint32_t skip_size_org = skip_size_;
+ switch (decode_status_) {
+ case GIF_D_STATUS_EXT_CE: {
+ if (!ReadData(&data_size, 1)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ cmt_data_.clear();
+ while (*data_size != GIF_BLOCK_TERMINAL) {
+ uint8_t block_size = *data_size;
+ if (!ReadData(&data_buf, *data_size) || !ReadData(&data_size, 1)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ cmt_data_ += ByteString(data_buf, block_size);
+ }
+ break;
+ }
+ case GIF_D_STATUS_EXT_PTE: {
+ CFX_GifPlainTextExtension* gif_pte = nullptr;
+ if (!ReadData(reinterpret_cast<uint8_t**>(&gif_pte), 13))
+ return CFX_GifDecodeStatus::Unfinished;
+
+ graphic_control_extension_ = nullptr;
+ if (!ReadData(&data_size, 1)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ while (*data_size != GIF_BLOCK_TERMINAL) {
+ if (!ReadData(&data_buf, *data_size) || !ReadData(&data_size, 1)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+ }
+ break;
+ }
+ case GIF_D_STATUS_EXT_GCE: {
+ CFX_GifGraphicControlExtension* gif_gce = nullptr;
+ if (!ReadData(reinterpret_cast<uint8_t**>(&gif_gce), 6))
+ return CFX_GifDecodeStatus::Unfinished;
+
+ if (!graphic_control_extension_.get())
+ graphic_control_extension_ =
+ pdfium::MakeUnique<CFX_GifGraphicControlExtension>();
+ graphic_control_extension_->block_size = gif_gce->block_size;
+ graphic_control_extension_->gce_flags = gif_gce->gce_flags;
+ graphic_control_extension_->delay_time =
+ GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_gce->delay_time));
+ graphic_control_extension_->trans_index = gif_gce->trans_index;
+ break;
+ }
+ default: {
+ if (decode_status_ == GIF_D_STATUS_EXT_PTE)
+ graphic_control_extension_ = nullptr;
+ if (!ReadData(&data_size, 1))
+ return CFX_GifDecodeStatus::Unfinished;
+
+ while (*data_size != GIF_BLOCK_TERMINAL) {
+ if (!ReadData(&data_buf, *data_size) || !ReadData(&data_size, 1)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+ }
+ }
+ }
+ SaveDecodingStatus(GIF_D_STATUS_SIG);
+ return CFX_GifDecodeStatus::Success;
+}
+
+CFX_GifDecodeStatus CFX_GifContext::DecodeImageInfo() {
+ if (width_ <= 0 || height_ <= 0)
+ return CFX_GifDecodeStatus::Error;
+
+ uint32_t skip_size_org = skip_size_;
+ CFX_CFX_GifImageInfo* img_info = nullptr;
+ if (!ReadData(reinterpret_cast<uint8_t**>(&img_info), 9))
+ return CFX_GifDecodeStatus::Unfinished;
+
+ auto gif_image = pdfium::MakeUnique<CFX_GifImage>();
+ gif_image->image_info.left =
+ GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&img_info->left));
+ gif_image->image_info.top =
+ GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&img_info->top));
+ gif_image->image_info.width =
+ GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&img_info->width));
+ gif_image->image_info.height =
+ GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&img_info->height));
+ gif_image->image_info.local_flags = img_info->local_flags;
+ if (gif_image->image_info.left + gif_image->image_info.width > width_ ||
+ gif_image->image_info.top + gif_image->image_info.height > height_)
+ return CFX_GifDecodeStatus::Error;
+
+ CFX_GifLocalFlags* gif_img_info_lf = &img_info->local_flags;
+ if (gif_img_info_lf->local_pal) {
+ gif_image->local_pallette_exp = gif_img_info_lf->pal_bits;
+ uint32_t loc_pal_size = unsigned(2 << gif_img_info_lf->pal_bits) * 3u;
+ uint8_t* loc_pal = nullptr;
+ if (!ReadData(&loc_pal, loc_pal_size)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ gif_image->local_palettes = std::vector<CFX_GifPalette>(loc_pal_size / 3);
+ std::copy(loc_pal, loc_pal + loc_pal_size,
+ reinterpret_cast<uint8_t*>(gif_image->local_palettes.data()));
+ }
+
+ uint8_t* code_size = nullptr;
+ if (!ReadData(&code_size, 1)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ gif_image->code_exp = *code_size;
+ RecordCurrentPosition(&gif_image->data_pos);
+ gif_image->data_pos += skip_size_;
+ gif_image->image_GCE = nullptr;
+ if (graphic_control_extension_.get()) {
+ gif_image->image_GCE = std::move(graphic_control_extension_);
+ graphic_control_extension_ = nullptr;
+ }
+ images_.push_back(std::move(gif_image));
+ SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
+ return CFX_GifDecodeStatus::Success;
+}
+
+void CFX_GifContext::DecodingFailureAtTailCleanup(CFX_GifImage* gif_image) {
+ gif_image->row_buffer.clear();
+ SaveDecodingStatus(GIF_D_STATUS_TAIL);
+}
diff --git a/core/fxcodec/gif/cfx_gifcontext.h b/core/fxcodec/gif/cfx_gifcontext.h
new file mode 100644
index 0000000000..a1cffb2746
--- /dev/null
+++ b/core/fxcodec/gif/cfx_gifcontext.h
@@ -0,0 +1,76 @@
+// 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_GIF_CFX_GIFCONTEXT_H_
+#define CORE_FXCODEC_GIF_CFX_GIFCONTEXT_H_
+
+#include <memory>
+#include <vector>
+
+#include "core/fxcodec/codec/ccodec_gifmodule.h"
+#include "core/fxcodec/gif/cfx_gif.h"
+#include "core/fxcodec/gif/cfx_lzwdecompressor.h"
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/unowned_ptr.h"
+
+class CFX_GifContext : public CCodec_GifModule::Context {
+ public:
+ CFX_GifContext(CCodec_GifModule* gif_module,
+ CCodec_GifModule::Delegate* delegate);
+ ~CFX_GifContext() override;
+
+ void RecordCurrentPosition(uint32_t* cur_pos);
+ 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,
+ CFX_GifPalette* pal,
+ int32_t delay_time,
+ bool user_input,
+ int32_t trans_index,
+ int32_t disposal_method,
+ bool interlace);
+ CFX_GifDecodeStatus ReadHeader();
+ CFX_GifDecodeStatus GetFrame();
+ CFX_GifDecodeStatus LoadFrame(int32_t frame_num);
+ void SetInputBuffer(uint8_t* src_buf, uint32_t src_size);
+ uint32_t GetAvailInput(uint8_t** avail_buf) const;
+ int32_t GetFrameNum() const;
+
+ UnownedPtr<CCodec_GifModule> gif_module_;
+ UnownedPtr<CCodec_GifModule::Delegate> delegate_;
+ std::vector<CFX_GifPalette> global_palette_;
+ 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<CFX_GifGraphicControlExtension> graphic_control_extension_;
+ uint8_t* next_in_;
+ std::vector<std::unique_ptr<CFX_GifImage>> images_;
+ std::unique_ptr<CFX_LZWDecompressor> lzw_decompressor_;
+ 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);
+ CFX_GifDecodeStatus DecodeExtension();
+ CFX_GifDecodeStatus DecodeImageInfo();
+ void DecodingFailureAtTailCleanup(CFX_GifImage* gif_image);
+};
+
+#endif // CORE_FXCODEC_GIF_CFX_GIFCONTEXT_H_
diff --git a/core/fxcodec/lgif/cfx_lzwdecoder.cpp b/core/fxcodec/gif/cfx_lzwdecompressor.cpp
index 9479eeafaa..27e36b12e9 100644
--- a/core/fxcodec/lgif/cfx_lzwdecoder.cpp
+++ b/core/fxcodec/gif/cfx_lzwdecompressor.cpp
@@ -4,7 +4,7 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#include "core/fxcodec/lgif/cfx_lzwdecoder.h"
+#include "core/fxcodec/gif/cfx_lzwdecompressor.h"
#include <algorithm>
#include <memory>
@@ -15,15 +15,16 @@
#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) {
+std::unique_ptr<CFX_LZWDecompressor> CFX_LZWDecompressor::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));
+ return std::unique_ptr<CFX_LZWDecompressor>(
+ new CFX_LZWDecompressor(color_exp, code_exp));
}
-CFX_LZWDecoder::CFX_LZWDecoder(uint8_t color_exp, uint8_t code_exp)
+CFX_LZWDecompressor::CFX_LZWDecompressor(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)),
@@ -38,17 +39,17 @@ CFX_LZWDecoder::CFX_LZWDecoder(uint8_t color_exp, uint8_t code_exp)
bits_left_(0),
code_store_(0) {}
-CFX_LZWDecoder::~CFX_LZWDecoder() {}
+CFX_LZWDecompressor::~CFX_LZWDecompressor() {}
-GifDecodeStatus CFX_LZWDecoder::Decode(uint8_t* src_buf,
- uint32_t src_size,
- uint8_t* des_buf,
- uint32_t* des_size) {
+CFX_GifDecodeStatus CFX_LZWDecompressor::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;
+ return CFX_GifDecodeStatus::Error;
if (*des_size == 0)
- return GifDecodeStatus::InsufficientDestSize;
+ return CFX_GifDecodeStatus::InsufficientDestSize;
next_in_ = src_buf;
avail_in_ = src_size;
@@ -60,7 +61,7 @@ GifDecodeStatus CFX_LZWDecoder::Decode(uint8_t* src_buf,
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;
+ return CFX_GifDecodeStatus::InsufficientDestSize;
}
memcpy(des_buf, &stack_[GIF_MAX_LZW_CODE - stack_size_], stack_size_);
@@ -71,17 +72,17 @@ GifDecodeStatus CFX_LZWDecoder::Decode(uint8_t* src_buf,
while (i <= *des_size && (avail_in_ > 0 || bits_left_ >= code_size_cur_)) {
if (code_size_cur_ > GIF_MAX_LZW_EXP)
- return GifDecodeStatus::Error;
+ return CFX_GifDecodeStatus::Error;
if (avail_in_ > 0) {
if (bits_left_ > 31)
- return GifDecodeStatus::Error;
+ return CFX_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;
+ return CFX_GifDecodeStatus::Error;
code_store_ = safe_code.ValueOrDie();
--avail_in_;
@@ -99,7 +100,7 @@ GifDecodeStatus CFX_LZWDecoder::Decode(uint8_t* src_buf,
}
if (code == code_end_) {
*des_size = i;
- return GifDecodeStatus::Success;
+ return CFX_GifDecodeStatus::Success;
}
if (code_old_ != static_cast<uint16_t>(-1)) {
@@ -107,12 +108,12 @@ GifDecodeStatus CFX_LZWDecoder::Decode(uint8_t* src_buf,
if (code == code_next_) {
AddCode(code_old_, code_first_);
if (!DecodeString(code))
- return GifDecodeStatus::Error;
+ return CFX_GifDecodeStatus::Error;
} else if (code > code_next_) {
- return GifDecodeStatus::Error;
+ return CFX_GifDecodeStatus::Error;
} else {
if (!DecodeString(code))
- return GifDecodeStatus::Error;
+ return CFX_GifDecodeStatus::Error;
uint8_t append_char = stack_[GIF_MAX_LZW_CODE - stack_size_];
AddCode(code_old_, append_char);
@@ -120,14 +121,14 @@ GifDecodeStatus CFX_LZWDecoder::Decode(uint8_t* src_buf,
}
} else {
if (!DecodeString(code))
- return GifDecodeStatus::Error;
+ return CFX_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;
+ return CFX_GifDecodeStatus::InsufficientDestSize;
}
memcpy(des_buf, &stack_[GIF_MAX_LZW_CODE - stack_size_], stack_size_);
@@ -138,13 +139,13 @@ GifDecodeStatus CFX_LZWDecoder::Decode(uint8_t* src_buf,
}
if (avail_in_ != 0)
- return GifDecodeStatus::Error;
+ return CFX_GifDecodeStatus::Error;
*des_size = i;
- return GifDecodeStatus::Unfinished;
+ return CFX_GifDecodeStatus::Unfinished;
}
-void CFX_LZWDecoder::ClearTable() {
+void CFX_LZWDecompressor::ClearTable() {
code_size_cur_ = code_size_ + 1;
code_next_ = code_end_ + 1;
code_old_ = static_cast<uint16_t>(-1);
@@ -154,7 +155,7 @@ void CFX_LZWDecoder::ClearTable() {
code_table_[i].suffix = static_cast<uint8_t>(i);
}
-void CFX_LZWDecoder::AddCode(uint16_t prefix_code, uint8_t append_char) {
+void CFX_LZWDecompressor::AddCode(uint16_t prefix_code, uint8_t append_char) {
if (code_next_ == GIF_MAX_LZW_CODE)
return;
@@ -166,7 +167,7 @@ void CFX_LZWDecoder::AddCode(uint16_t prefix_code, uint8_t append_char) {
}
}
-bool CFX_LZWDecoder::DecodeString(uint16_t code) {
+bool CFX_LZWDecompressor::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)
diff --git a/core/fxcodec/lgif/cfx_lzwdecoder.h b/core/fxcodec/gif/cfx_lzwdecompressor.h
index 9dbf15d9b7..10c0a566d7 100644
--- a/core/fxcodec/lgif/cfx_lzwdecoder.h
+++ b/core/fxcodec/gif/cfx_lzwdecompressor.h
@@ -4,15 +4,15 @@
// 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_
+#ifndef CORE_FXCODEC_GIF_CFX_LZWDECOMPRESSOR_H_
+#define CORE_FXCODEC_GIF_CFX_LZWDECOMPRESSOR_H_
#include <memory>
#include <vector>
-#include "core/fxcodec/lgif/fx_gif.h"
+#include "core/fxcodec/gif/cfx_gif.h"
-class CFX_LZWDecoder {
+class CFX_LZWDecompressor {
public:
typedef struct {
uint16_t prefix;
@@ -20,17 +20,17 @@ class CFX_LZWDecoder {
} CodeEntry;
// Returns nullptr on error
- static std::unique_ptr<CFX_LZWDecoder> Create(uint8_t color_exp,
- uint8_t code_exp);
- ~CFX_LZWDecoder();
+ static std::unique_ptr<CFX_LZWDecompressor> Create(uint8_t color_exp,
+ uint8_t code_exp);
+ ~CFX_LZWDecompressor();
- GifDecodeStatus Decode(uint8_t* src_buf,
- uint32_t src_size,
- uint8_t* des_buf,
- uint32_t* des_size);
+ CFX_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);
+ CFX_LZWDecompressor(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);
@@ -52,4 +52,4 @@ class CFX_LZWDecoder {
uint32_t code_store_;
};
-#endif // CORE_FXCODEC_LGIF_CFX_LZWDECODER_H_
+#endif // CORE_FXCODEC_GIF_CFX_LZWDECOMPRESSOR_H_
diff --git a/core/fxcodec/lgif/cfx_lzwdecoder_unittest.cpp b/core/fxcodec/gif/cfx_lzwdecompressor_unittest.cpp
index 9e4b7b788e..cc3ce6367d 100644
--- a/core/fxcodec/lgif/cfx_lzwdecoder_unittest.cpp
+++ b/core/fxcodec/gif/cfx_lzwdecompressor_unittest.cpp
@@ -2,21 +2,21 @@
// 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/fxcodec/gif/cfx_lzwdecompressor.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_LZWDecompressor, CreateBadParams) {
+ EXPECT_EQ(nullptr, CFX_LZWDecompressor::Create(0x10, 0x2));
+ EXPECT_EQ(nullptr, CFX_LZWDecompressor::Create(0x4, 0x0F));
}
-TEST(CFX_LZWDecoder, DecodeBadParams) {
+TEST(CFX_LZWDecompressor, DecodeBadParams) {
uint8_t palette_exp = 0x0;
uint8_t code_exp = 0x2;
- auto decoder = CFX_LZWDecoder::Create(palette_exp, code_exp);
+ auto decoder = CFX_LZWDecompressor::Create(palette_exp, code_exp);
ASSERT_NE(nullptr, decoder);
uint8_t image_data[10];
@@ -25,25 +25,25 @@ TEST(CFX_LZWDecoder, DecodeBadParams) {
uint8_t output_data[10];
uint32_t output_size = FX_ArraySize(output_data);
- EXPECT_EQ(GifDecodeStatus::Error,
+ EXPECT_EQ(CFX_GifDecodeStatus::Error,
decoder->Decode(nullptr, image_size, output_data, &output_size));
- EXPECT_EQ(GifDecodeStatus::Error,
+ EXPECT_EQ(CFX_GifDecodeStatus::Error,
decoder->Decode(image_data, 0, output_data, &output_size));
- EXPECT_EQ(GifDecodeStatus::Error,
+ EXPECT_EQ(CFX_GifDecodeStatus::Error,
decoder->Decode(image_data, image_size, nullptr, &output_size));
- EXPECT_EQ(GifDecodeStatus::Error,
+ EXPECT_EQ(CFX_GifDecodeStatus::Error,
decoder->Decode(image_data, image_size, output_data, nullptr));
output_size = 0;
- EXPECT_EQ(GifDecodeStatus::InsufficientDestSize,
+ EXPECT_EQ(CFX_GifDecodeStatus::InsufficientDestSize,
decoder->Decode(image_data, image_size, output_data, &output_size));
}
-TEST(CFX_LZWDecoder, Decode1x1SingleColour) {
+TEST(CFX_LZWDecompressor, Decode1x1SingleColour) {
uint8_t palette_exp = 0x0;
uint8_t code_exp = 0x2;
- auto decoder = CFX_LZWDecoder::Create(palette_exp, code_exp);
+ auto decoder = CFX_LZWDecompressor::Create(palette_exp, code_exp);
ASSERT_NE(nullptr, decoder);
uint8_t image_data[] = {0x44, 0x01};
@@ -52,7 +52,7 @@ TEST(CFX_LZWDecoder, Decode1x1SingleColour) {
uint8_t output_data[1];
uint32_t output_size = FX_ArraySize(output_data);
- EXPECT_EQ(GifDecodeStatus::Success,
+ EXPECT_EQ(CFX_GifDecodeStatus::Success,
decoder->Decode(image_data, image_size, output_data, &output_size));
uint8_t expected_data[] = {0x00};
@@ -60,11 +60,11 @@ TEST(CFX_LZWDecoder, Decode1x1SingleColour) {
EXPECT_TRUE(0 == memcmp(expected_data, output_data, sizeof(expected_data)));
}
-TEST(CFX_LZWDecoder, Decode10x10SingleColour) {
+TEST(CFX_LZWDecompressor, Decode10x10SingleColour) {
uint8_t palette_exp = 0x0;
uint8_t code_exp = 0x2;
- auto decoder = CFX_LZWDecoder::Create(palette_exp, code_exp);
+ auto decoder = CFX_LZWDecompressor::Create(palette_exp, code_exp);
ASSERT_NE(nullptr, decoder);
uint8_t image_data[] = {0x84, 0x8F, 0xA9, 0xCB, 0xED, 0x0F, 0x63, 0x2B};
@@ -74,7 +74,7 @@ TEST(CFX_LZWDecoder, Decode10x10SingleColour) {
memset(output_data, 0, sizeof(output_data));
uint32_t output_size = FX_ArraySize(output_data);
- EXPECT_EQ(GifDecodeStatus::Success,
+ EXPECT_EQ(CFX_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,
@@ -91,11 +91,11 @@ TEST(CFX_LZWDecoder, Decode10x10SingleColour) {
EXPECT_TRUE(0 == memcmp(expected_data, output_data, sizeof(expected_data)));
}
-TEST(CFX_LZWDecoder, Decode10x10MultipleColour) {
+TEST(CFX_LZWDecompressor, Decode10x10MultipleColour) {
uint8_t palette_exp = 0x1;
uint8_t code_exp = 0x2;
- auto decoder = CFX_LZWDecoder::Create(palette_exp, code_exp);
+ auto decoder = CFX_LZWDecompressor::Create(palette_exp, code_exp);
ASSERT_NE(nullptr, decoder);
uint8_t image_data[] = {0x8C, 0x2D, 0x99, 0x87, 0x2A, 0x1C, 0xDC, 0x33,
@@ -107,7 +107,7 @@ TEST(CFX_LZWDecoder, Decode10x10MultipleColour) {
memset(output_data, 0, sizeof(output_data));
uint32_t output_size = FX_ArraySize(output_data);
- EXPECT_EQ(GifDecodeStatus::Success,
+ EXPECT_EQ(CFX_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,
@@ -124,12 +124,12 @@ TEST(CFX_LZWDecoder, Decode10x10MultipleColour) {
EXPECT_TRUE(0 == memcmp(expected_data, output_data, sizeof(expected_data)));
}
-TEST(CFX_LZWDecoder, HandleColourCodeOutOfPalette) {
+TEST(CFX_LZWDecompressor, 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);
+ auto decoder = CFX_LZWDecompressor::Create(palette_exp, code_exp);
ASSERT_NE(nullptr, decoder);
uint8_t image_data[] = {0x30, 0xC9, 0x49, 0x81, 0xBD, 0x78, 0xE8, 0xCD,
@@ -142,6 +142,6 @@ TEST(CFX_LZWDecoder, HandleColourCodeOutOfPalette) {
memset(output_data, 0, sizeof(output_data));
uint32_t output_size = FX_ArraySize(output_data);
- EXPECT_EQ(GifDecodeStatus::Error,
+ EXPECT_EQ(CFX_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");