summaryrefslogtreecommitdiff
path: root/core/fxcodec
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxcodec')
-rw-r--r--core/fxcodec/codec/ccodec_gifmodule.cpp2
-rw-r--r--core/fxcodec/codec/ccodec_progressivedecoder.h2
-rw-r--r--core/fxcodec/codec/fx_codec_progress.cpp44
-rw-r--r--core/fxcodec/fx_codec_def.h1
-rw-r--r--core/fxcodec/lgif/cgifcontext.cpp2
-rw-r--r--core/fxcodec/lgif/cgifcontext.h2
-rw-r--r--core/fxcodec/lgif/fx_gif.cpp32
-rw-r--r--core/fxcodec/lgif/fx_gif.h7
8 files changed, 55 insertions, 37 deletions
diff --git a/core/fxcodec/codec/ccodec_gifmodule.cpp b/core/fxcodec/codec/ccodec_gifmodule.cpp
index f7e3546a8f..911323c3a1 100644
--- a/core/fxcodec/codec/ccodec_gifmodule.cpp
+++ b/core/fxcodec/codec/ccodec_gifmodule.cpp
@@ -36,7 +36,7 @@ GifDecodeStatus CCodec_GifModule::ReadHeader(Context* pContext,
*width = context->width;
*height = context->height;
- *pal_num = context->global_pal_num;
+ *pal_num = (2 << context->global_pal_exp);
*pal_pp = context->m_GlobalPalette.empty() ? nullptr
: context->m_GlobalPalette.data();
*bg_index = context->bc_index;
diff --git a/core/fxcodec/codec/ccodec_progressivedecoder.h b/core/fxcodec/codec/ccodec_progressivedecoder.h
index 87bed08fcf..05b7c92078 100644
--- a/core/fxcodec/codec/ccodec_progressivedecoder.h
+++ b/core/fxcodec/codec/ccodec_progressivedecoder.h
@@ -56,7 +56,7 @@ class CCodec_ProgressiveDecoder : public CCodec_BmpModule::Delegate,
int32_t GetBPC() const { return m_SrcBPC; }
void SetClipBox(FX_RECT* clip);
- FXCODEC_STATUS GetFrames(int32_t& frames);
+ FXCODEC_STATUS GetFrames(int32_t* frames);
FXCODEC_STATUS StartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap,
int start_x,
int start_y,
diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp
index 8b90d3ab84..f10523cc39 100644
--- a/core/fxcodec/codec/fx_codec_progress.cpp
+++ b/core/fxcodec/codec/fx_codec_progress.cpp
@@ -1791,7 +1791,7 @@ void CCodec_ProgressiveDecoder::Resample(
}
}
-FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames) {
+FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t* frames) {
if (!(m_status == FXCODEC_STATUS_FRAME_READY ||
m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) {
return FXCODEC_STATUS_ERROR;
@@ -1801,7 +1801,8 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames) {
case FXCODEC_IMAGE_BMP:
case FXCODEC_IMAGE_PNG:
case FXCODEC_IMAGE_TIF:
- frames = m_FrameNumber = 1;
+ *frames = 1;
+ m_FrameNumber = 1;
m_status = FXCODEC_STATUS_DECODE_READY;
return m_status;
case FXCODEC_IMAGE_GIF: {
@@ -1822,7 +1823,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames) {
pGifModule->LoadFrameInfo(m_pGifContext.get(), &m_FrameNumber);
}
if (readResult == GifDecodeStatus::Success) {
- frames = m_FrameNumber;
+ *frames = m_FrameNumber;
m_status = FXCODEC_STATUS_DECODE_READY;
return m_status;
}
@@ -2108,34 +2109,37 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode() {
case FXCODEC_IMAGE_GIF: {
CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
if (!pGifModule) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
m_status = FXCODEC_STATUS_ERR_MEMORY;
return m_status;
}
- while (true) {
- GifDecodeStatus readRes =
- pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr);
- while (readRes == GifDecodeStatus::Unfinished) {
- FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
- if (!GifReadMoreData(pGifModule, error_status)) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = error_status;
- return m_status;
- }
- readRes =
- pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr);
- }
- if (readRes == GifDecodeStatus::Success) {
+
+ GifDecodeStatus readRes =
+ pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr);
+ while (readRes == GifDecodeStatus::Unfinished) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
+ if (!GifReadMoreData(pGifModule, error_status)) {
m_pDeviceBitmap = nullptr;
m_pFile = nullptr;
- m_status = FXCODEC_STATUS_DECODE_FINISH;
+ m_status = error_status;
return m_status;
}
+ readRes =
+ pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr);
+ }
+
+ if (readRes == GifDecodeStatus::Success) {
m_pDeviceBitmap = nullptr;
m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERROR;
+ m_status = FXCODEC_STATUS_DECODE_FINISH;
return m_status;
}
+
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERROR;
+ return m_status;
}
case FXCODEC_IMAGE_BMP: {
CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
diff --git a/core/fxcodec/fx_codec_def.h b/core/fxcodec/fx_codec_def.h
index fd23d78fa5..04696a11dd 100644
--- a/core/fxcodec/fx_codec_def.h
+++ b/core/fxcodec/fx_codec_def.h
@@ -22,6 +22,7 @@ enum FXCODEC_STATUS {
FXCODEC_STATUS_ERR_FORMAT,
FXCODEC_STATUS_ERR_PARAMS
};
+
#define JP2_SPACE_INVALID -1
#define JPX_SPACE_INVALID -1
#define JP2_SPACE_bilevel1 0
diff --git a/core/fxcodec/lgif/cgifcontext.cpp b/core/fxcodec/lgif/cgifcontext.cpp
index e57e978218..4dc663644c 100644
--- a/core/fxcodec/lgif/cgifcontext.cpp
+++ b/core/fxcodec/lgif/cgifcontext.cpp
@@ -17,7 +17,7 @@ CGifContext::CGifContext(CCodec_GifModule* gif_module,
CCodec_GifModule::Delegate* pDelegate)
: m_pModule(gif_module),
m_pDelegate(pDelegate),
- global_pal_num(0),
+ global_pal_exp(0),
img_row_offset(0),
img_row_avail_size(0),
avail_in(0),
diff --git a/core/fxcodec/lgif/cgifcontext.h b/core/fxcodec/lgif/cgifcontext.h
index d85243711d..71cf2bc75e 100644
--- a/core/fxcodec/lgif/cgifcontext.h
+++ b/core/fxcodec/lgif/cgifcontext.h
@@ -40,7 +40,7 @@ class CGifContext : public CCodec_GifModule::Context {
UnownedPtr<CCodec_GifModule> m_pModule;
UnownedPtr<CCodec_GifModule::Delegate> m_pDelegate;
std::vector<GifPalette> m_GlobalPalette;
- int32_t global_pal_num;
+ uint8_t global_pal_exp;
uint32_t img_row_offset;
uint32_t img_row_avail_size;
uint32_t avail_in;
diff --git a/core/fxcodec/lgif/fx_gif.cpp b/core/fxcodec/lgif/fx_gif.cpp
index 18385c3bdd..ea78259420 100644
--- a/core/fxcodec/lgif/fx_gif.cpp
+++ b/core/fxcodec/lgif/fx_gif.cpp
@@ -147,6 +147,7 @@ GifDecodeStatus gif_decode_image_info(CGifContext* context) {
}
GifLF* gif_img_info_lf_ptr = (GifLF*)&gif_img_info_ptr->local_flag;
if (gif_img_info_lf_ptr->local_pal) {
+ gif_image->local_pallette_exp = gif_img_info_lf_ptr->pal_bits;
int32_t loc_pal_size = (2 << gif_img_info_lf_ptr->pal_bits) * 3;
uint8_t* loc_pal_ptr = nullptr;
if (!gif_read_data(context, &loc_pal_ptr, loc_pal_size)) {
@@ -162,7 +163,7 @@ GifDecodeStatus gif_decode_image_info(CGifContext* context) {
context->skip_size = skip_size_org;
return GifDecodeStatus::Unfinished;
}
- gif_image->image_code_size = *code_size_ptr;
+ gif_image->image_code_exp = *code_size_ptr;
context->RecordCurrentPosition(&gif_image->image_data_pos);
gif_image->image_data_pos += context->skip_size;
gif_image->m_ImageGCE = nullptr;
@@ -214,10 +215,13 @@ CGifLZWDecoder::CGifLZWDecoder(char* error_ptr)
CGifLZWDecoder::~CGifLZWDecoder() {}
-void CGifLZWDecoder::InitTable(uint8_t code_len) {
- code_size = code_len;
- ASSERT(code_size < 13);
- code_clear = 1 << code_size;
+void CGifLZWDecoder::InitTable(uint8_t color_exp, uint8_t code_exp) {
+ // TODO(rharrison): Refactor all of this, so that initializing the table with
+ // bad values will kill the decompress.
+ ASSERT(code_exp <= GIF_MAX_LZW_EXP);
+ code_color_end = std::min(2 << color_exp, 1 << code_exp);
+ code_size = code_exp;
+ code_clear = 1 << code_exp;
code_end = code_clear + 1;
bits_left = 0;
code_store = 0;
@@ -247,6 +251,9 @@ bool CGifLZWDecoder::DecodeString(uint16_t code) {
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;
@@ -282,7 +289,7 @@ GifDecodeStatus CGifLZWDecoder::Decode(uint8_t* des_buf, uint32_t* des_size) {
}
ASSERT(err_msg_ptr);
while (i <= *des_size && (avail_in > 0 || bits_left >= code_size_cur)) {
- if (code_size_cur > 12) {
+ if (code_size_cur > GIF_MAX_LZW_EXP) {
strncpy(err_msg_ptr, "Code Length Out Of Range", GIF_MAX_ERROR_SIZE - 1);
return GifDecodeStatus::Error;
}
@@ -383,9 +390,9 @@ GifDecodeStatus gif_read_header(CGifContext* context) {
return GifDecodeStatus::Unfinished;
}
if (reinterpret_cast<GifGF*>(&gif_lsd_ptr->global_flag)->global_pal) {
- context->global_pal_num =
- 2 << reinterpret_cast<GifGF*>(&gif_lsd_ptr->global_flag)->pal_bits;
- int32_t global_pal_size = context->global_pal_num * 3;
+ context->global_pal_exp =
+ reinterpret_cast<GifGF*>(&gif_lsd_ptr->global_flag)->pal_bits;
+ int32_t global_pal_size = (2 << context->global_pal_exp) * 3;
uint8_t* global_pal_ptr = nullptr;
if (!gif_read_data(context, &global_pal_ptr, global_pal_size)) {
context->skip_size = skip_size_org;
@@ -558,7 +565,7 @@ GifDecodeStatus gif_load_frame(CGifContext* context, int32_t frame_num) {
return GifDecodeStatus::Error;
}
}
- if (gif_image_ptr->image_code_size >= 13) {
+ if (gif_image_ptr->image_code_exp > GIF_MAX_LZW_EXP) {
gif_image_ptr->m_ImageRowBuf.clear();
context->AddError("Error Invalid Code Size");
return GifDecodeStatus::Error;
@@ -566,7 +573,10 @@ GifDecodeStatus gif_load_frame(CGifContext* context, int32_t frame_num) {
if (!context->m_ImgDecoder.get())
context->m_ImgDecoder =
pdfium::MakeUnique<CGifLZWDecoder>(context->m_szLastError);
- context->m_ImgDecoder->InitTable(gif_image_ptr->image_code_size);
+ context->m_ImgDecoder->InitTable(!gif_image_ptr->m_LocalPalettes.empty()
+ ? gif_image_ptr->local_pallette_exp
+ : context->global_pal_exp,
+ gif_image_ptr->image_code_exp);
context->img_row_offset = 0;
context->img_row_avail_size = 0;
context->img_pass_num = 0;
diff --git a/core/fxcodec/lgif/fx_gif.h b/core/fxcodec/lgif/fx_gif.h
index fd95aba17a..bddb22b30c 100644
--- a/core/fxcodec/lgif/fx_gif.h
+++ b/core/fxcodec/lgif/fx_gif.h
@@ -21,6 +21,7 @@ class CGifContext;
#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
@@ -116,7 +117,8 @@ class GifImage {
std::vector<GifPalette> m_LocalPalettes;
std::vector<uint8_t> m_ImageRowBuf;
GifImageInfo m_ImageInfo;
- uint8_t image_code_size;
+ uint8_t local_pallette_exp;
+ uint8_t image_code_exp;
uint32_t image_data_pos;
int32_t image_row_num;
};
@@ -131,7 +133,7 @@ class CGifLZWDecoder {
explicit CGifLZWDecoder(char* error_ptr);
~CGifLZWDecoder();
- void InitTable(uint8_t code_len);
+ void InitTable(uint8_t color_exp, uint8_t code_exp);
GifDecodeStatus Decode(uint8_t* des_buf, uint32_t* des_size);
void Input(uint8_t* src_buf, uint32_t src_size);
uint32_t GetAvailInput();
@@ -143,6 +145,7 @@ class CGifLZWDecoder {
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;