From 808828cb7b5539ab9a3f52b67ada6f26fa3c9d51 Mon Sep 17 00:00:00 2001 From: Nicolas Pena Date: Tue, 9 May 2017 12:35:19 -0400 Subject: Cleanup of CGifDecompressor part 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL changes the tag_gif_decompress_struct into CGifDecompressor. It cleans up a bunch of unnecessary function pointers and starts cleaning up the members of the new class. Change-Id: Id49cd8f5377dc8daaa15118551dadad4ddde7931 Reviewed-on: https://pdfium-review.googlesource.com/5170 Reviewed-by: dsinclair Commit-Queue: Nicolás Peña --- BUILD.gn | 2 + core/fxcodec/codec/ccodec_gifmodule.cpp | 128 ++++++--------------------- core/fxcodec/codec/ccodec_gifmodule.h | 2 +- core/fxcodec/lgif/cgifdecompressor.cpp | 96 +++++++++++++++++++++ core/fxcodec/lgif/cgifdecompressor.h | 79 +++++++++++++++++ core/fxcodec/lgif/fx_gif.cpp | 147 ++++++++++---------------------- core/fxcodec/lgif/fx_gif.h | 67 ++------------- 7 files changed, 255 insertions(+), 266 deletions(-) create mode 100644 core/fxcodec/lgif/cgifdecompressor.cpp create mode 100644 core/fxcodec/lgif/cgifdecompressor.h diff --git a/BUILD.gn b/BUILD.gn index 680416c05a..1abcc8d756 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -729,6 +729,8 @@ static_library("fxcodec") { "core/fxcodec/codec/fx_codec_progress.cpp", "core/fxcodec/lbmp/fx_bmp.cpp", "core/fxcodec/lbmp/fx_bmp.h", + "core/fxcodec/lgif/cgifdecompressor.cpp", + "core/fxcodec/lgif/cgifdecompressor.h", "core/fxcodec/lgif/fx_gif.cpp", "core/fxcodec/lgif/fx_gif.h", ] diff --git a/core/fxcodec/codec/ccodec_gifmodule.cpp b/core/fxcodec/codec/ccodec_gifmodule.cpp index b53880587e..33d74a9da4 100644 --- a/core/fxcodec/codec/ccodec_gifmodule.cpp +++ b/core/fxcodec/codec/ccodec_gifmodule.cpp @@ -8,74 +8,10 @@ #include "core/fxcodec/codec/codec_int.h" #include "core/fxcodec/fx_codec.h" +#include "core/fxcodec/lgif/cgifdecompressor.h" #include "core/fxcodec/lgif/fx_gif.h" #include "core/fxge/fx_dib.h" - -struct FXGIF_Context { - gif_decompress_struct_p gif_ptr; - void* parent_ptr; - - void* (*m_AllocFunc)(unsigned int); - void (*m_FreeFunc)(void*); -}; - -extern "C" { -static void* gif_alloc_func(unsigned int size) { - return FX_Alloc(char, size); -} -static void gif_free_func(void* p) { - FX_Free(p); -} -}; - -static void gif_error_data(gif_decompress_struct_p gif_ptr, - const char* err_msg) { - strncpy((char*)gif_ptr->err_ptr, err_msg, GIF_MAX_ERROR_SIZE - 1); - longjmp(gif_ptr->jmpbuf, 1); -} - -static uint8_t* gif_ask_buf_for_pal(gif_decompress_struct_p gif_ptr, - int32_t pal_size) { - FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; - CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - return pModule->GetDelegate()->GifAskLocalPaletteBuf( - gif_get_frame_num(gif_ptr), pal_size); -} - -static void gif_record_current_position(gif_decompress_struct_p gif_ptr, - uint32_t* cur_pos_ptr) { - FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; - CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - pModule->GetDelegate()->GifRecordCurrentPosition(*cur_pos_ptr); -} - -static void gif_read_scanline(gif_decompress_struct_p gif_ptr, - int32_t row_num, - uint8_t* row_buf) { - FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; - CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - pModule->GetDelegate()->GifReadScanline(row_num, row_buf); -} - -static bool gif_get_record_position(gif_decompress_struct_p gif_ptr, - uint32_t cur_pos, - int32_t left, - int32_t top, - int32_t width, - int32_t height, - int32_t pal_num, - void* pal_ptr, - int32_t delay_time, - bool user_input, - int32_t trans_index, - int32_t disposal_method, - bool interlace) { - FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; - CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - return pModule->GetDelegate()->GifInputRecordPositionBuf( - cur_pos, FX_RECT(left, top, left + width, top + height), pal_num, pal_ptr, - delay_time, user_input, trans_index, disposal_method, interlace); -} +#include "third_party/base/ptr_util.h" CCodec_GifModule::CCodec_GifModule() { memset(m_szLastError, 0, sizeof(m_szLastError)); @@ -89,29 +25,15 @@ FXGIF_Context* CCodec_GifModule::Start() { return nullptr; memset(p, 0, sizeof(FXGIF_Context)); - p->m_AllocFunc = gif_alloc_func; - p->m_FreeFunc = gif_free_func; - p->gif_ptr = nullptr; p->parent_ptr = this; - p->gif_ptr = gif_create_decompress(); - if (!p->gif_ptr) { - FX_Free(p); - return nullptr; - } - p->gif_ptr->context_ptr = p; - p->gif_ptr->err_ptr = m_szLastError; - p->gif_ptr->gif_error_fn = gif_error_data; - p->gif_ptr->gif_ask_buf_for_pal_fn = gif_ask_buf_for_pal; - p->gif_ptr->gif_record_current_position_fn = gif_record_current_position; - p->gif_ptr->gif_get_row_fn = gif_read_scanline; - p->gif_ptr->gif_get_record_position_fn = gif_get_record_position; + p->m_Gif = pdfium::MakeUnique(p, m_szLastError); return p; } void CCodec_GifModule::Finish(FXGIF_Context* ctx) { if (ctx) { - gif_destroy_decompress(&ctx->gif_ptr); - ctx->m_FreeFunc(ctx); + ctx->m_Gif = nullptr; + FX_Free(ctx); } } @@ -122,52 +44,52 @@ GifDecodeStatus CCodec_GifModule::ReadHeader(FXGIF_Context* ctx, void** pal_pp, int* bg_index, CFX_DIBAttribute* pAttribute) { - if (setjmp(ctx->gif_ptr->jmpbuf)) + if (setjmp(ctx->m_Gif->jmpbuf)) return GifDecodeStatus::Error; - GifDecodeStatus ret = gif_read_header(ctx->gif_ptr); + GifDecodeStatus ret = gif_read_header(ctx->m_Gif.get()); if (ret != GifDecodeStatus::Success) return ret; - *width = ctx->gif_ptr->width; - *height = ctx->gif_ptr->height; - *pal_num = ctx->gif_ptr->global_pal_num; - *pal_pp = ctx->gif_ptr->global_pal_ptr; - *bg_index = ctx->gif_ptr->bc_index; + *width = ctx->m_Gif->width; + *height = ctx->m_Gif->height; + *pal_num = ctx->m_Gif->global_pal_num; + *pal_pp = ctx->m_Gif->m_GlobalPalette.data(); + *bg_index = ctx->m_Gif->bc_index; return GifDecodeStatus::Success; } GifDecodeStatus CCodec_GifModule::LoadFrameInfo(FXGIF_Context* ctx, int* frame_num) { - if (setjmp(ctx->gif_ptr->jmpbuf)) + if (setjmp(ctx->m_Gif->jmpbuf)) return GifDecodeStatus::Error; - GifDecodeStatus ret = gif_get_frame(ctx->gif_ptr); + GifDecodeStatus ret = gif_get_frame(ctx->m_Gif.get()); if (ret != GifDecodeStatus::Success) return ret; - *frame_num = gif_get_frame_num(ctx->gif_ptr); + *frame_num = gif_get_frame_num(ctx->m_Gif.get()); return GifDecodeStatus::Success; } GifDecodeStatus CCodec_GifModule::LoadFrame(FXGIF_Context* ctx, int frame_num, CFX_DIBAttribute* pAttribute) { - if (setjmp(ctx->gif_ptr->jmpbuf)) + if (setjmp(ctx->m_Gif->jmpbuf)) return GifDecodeStatus::Error; - GifDecodeStatus ret = gif_load_frame(ctx->gif_ptr, frame_num); + GifDecodeStatus ret = gif_load_frame(ctx->m_Gif.get(), frame_num); if (ret == GifDecodeStatus::Success) { if (pAttribute) { pAttribute->m_nGifLeft = - (*ctx->gif_ptr->img_ptr_arr_ptr)[frame_num]->image_info_ptr->left; + (*ctx->m_Gif->img_ptr_arr_ptr)[frame_num]->image_info_ptr->left; pAttribute->m_nGifTop = - (*ctx->gif_ptr->img_ptr_arr_ptr)[frame_num]->image_info_ptr->top; - pAttribute->m_fAspectRatio = ctx->gif_ptr->pixel_aspect; - if (ctx->gif_ptr->cmt_data_ptr) { + (*ctx->m_Gif->img_ptr_arr_ptr)[frame_num]->image_info_ptr->top; + pAttribute->m_fAspectRatio = ctx->m_Gif->pixel_aspect; + if (ctx->m_Gif->cmt_data_ptr) { const uint8_t* buf = - (const uint8_t*)ctx->gif_ptr->cmt_data_ptr->GetBuffer(0); - uint32_t len = ctx->gif_ptr->cmt_data_ptr->GetLength(); + (const uint8_t*)ctx->m_Gif->cmt_data_ptr->GetBuffer(0); + uint32_t len = ctx->m_Gif->cmt_data_ptr->GetLength(); if (len > 21) { uint8_t size = *buf++; if (size) { @@ -189,11 +111,11 @@ GifDecodeStatus CCodec_GifModule::LoadFrame(FXGIF_Context* ctx, uint32_t CCodec_GifModule::GetAvailInput(FXGIF_Context* ctx, uint8_t** avail_buf_ptr) { - return gif_get_avail_input(ctx->gif_ptr, avail_buf_ptr); + return gif_get_avail_input(ctx->m_Gif.get(), avail_buf_ptr); } void CCodec_GifModule::Input(FXGIF_Context* ctx, const uint8_t* src_buf, uint32_t src_size) { - gif_input_buffer(ctx->gif_ptr, (uint8_t*)src_buf, src_size); + gif_input_buffer(ctx->m_Gif.get(), (uint8_t*)src_buf, src_size); } diff --git a/core/fxcodec/codec/ccodec_gifmodule.h b/core/fxcodec/codec/ccodec_gifmodule.h index b42a86642b..c4298224b3 100644 --- a/core/fxcodec/codec/ccodec_gifmodule.h +++ b/core/fxcodec/codec/ccodec_gifmodule.h @@ -12,7 +12,7 @@ #include "core/fxcrt/fx_system.h" class CFX_DIBAttribute; -struct FXGIF_Context; +class FXGIF_Context; class CCodec_GifModule { public: diff --git a/core/fxcodec/lgif/cgifdecompressor.cpp b/core/fxcodec/lgif/cgifdecompressor.cpp new file mode 100644 index 0000000000..fb461f70e9 --- /dev/null +++ b/core/fxcodec/lgif/cgifdecompressor.cpp @@ -0,0 +1,96 @@ +// 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/cgifdecompressor.h" + +#include + +#include "core/fxcodec/codec/ccodec_gifmodule.h" +#include "core/fxcodec/lgif/fx_gif.h" +#include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" + +FXGIF_Context::FXGIF_Context() {} + +FXGIF_Context::~FXGIF_Context() {} + +CGifDecompressor::CGifDecompressor(FXGIF_Context* p, char* error_string) + : decode_status(GIF_D_STATUS_SIG), + err_ptr(error_string), + context_ptr(p), + cmt_data_ptr(new CFX_ByteString), + pt_ptr_arr_ptr(new std::vector), + img_ptr_arr_ptr(new std::vector) {} + +CGifDecompressor::~CGifDecompressor() { + // TODO(npm): fix ownership in CGifDecompressor to avoid all of the frees and + // deletes in here. + GifPalette* pGlobalPal = m_GlobalPalette.data(); + if (img_ptr_arr_ptr) { + size_t size_img_arr = img_ptr_arr_ptr->size(); + for (size_t i = 0; i < size_img_arr; i++) { + GifImage* p = (*img_ptr_arr_ptr)[i]; + FX_Free(p->image_info_ptr); + FX_Free(p->image_gce_ptr); + FX_Free(p->image_row_buf); + if (p->local_pal_ptr && p->local_pal_ptr != pGlobalPal) + FX_Free(p->local_pal_ptr); + FX_Free(p); + } + img_ptr_arr_ptr->clear(); + delete img_ptr_arr_ptr; + } + delete cmt_data_ptr; + FX_Free(gce_ptr); + if (pt_ptr_arr_ptr) { + size_t size_pt_arr = pt_ptr_arr_ptr->size(); + for (size_t i = 0; i < size_pt_arr; i++) { + GifPlainText* p = (*pt_ptr_arr_ptr)[i]; + FX_Free(p->gce_ptr); + FX_Free(p->pte_ptr); + delete p->string_ptr; + FX_Free(p); + } + pt_ptr_arr_ptr->clear(); + delete pt_ptr_arr_ptr; + } +} + +void CGifDecompressor::ErrorData(const char* err_msg) { + strncpy(err_ptr, err_msg, GIF_MAX_ERROR_SIZE - 1); + longjmp(jmpbuf, 1); +} + +uint8_t* CGifDecompressor::AskBufForPal(int32_t pal_size) { + return context_ptr->parent_ptr->GetDelegate()->GifAskLocalPaletteBuf( + gif_get_frame_num(this), pal_size); +} + +void CGifDecompressor::RecordCurrentPosition(uint32_t* cur_pos_ptr) { + context_ptr->parent_ptr->GetDelegate()->GifRecordCurrentPosition( + *cur_pos_ptr); +} + +void CGifDecompressor::ReadScanline(int32_t row_num, uint8_t* row_buf) { + context_ptr->parent_ptr->GetDelegate()->GifReadScanline(row_num, row_buf); +} + +bool CGifDecompressor::GetRecordPosition(uint32_t cur_pos, + int32_t left, + int32_t top, + int32_t width, + int32_t height, + int32_t pal_num, + void* pal_ptr, + int32_t delay_time, + bool user_input, + int32_t trans_index, + int32_t disposal_method, + bool interlace) { + return context_ptr->parent_ptr->GetDelegate()->GifInputRecordPositionBuf( + cur_pos, FX_RECT(left, top, left + width, top + height), pal_num, pal_ptr, + delay_time, user_input, trans_index, disposal_method, interlace); +} diff --git a/core/fxcodec/lgif/cgifdecompressor.h b/core/fxcodec/lgif/cgifdecompressor.h new file mode 100644 index 0000000000..32d9dc4563 --- /dev/null +++ b/core/fxcodec/lgif/cgifdecompressor.h @@ -0,0 +1,79 @@ +// 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_CGIFDECOMPRESSOR_H_ +#define CORE_FXCODEC_LGIF_CGIFDECOMPRESSOR_H_ + +#include +#include +#include + +#include "core/fxcodec/lgif/fx_gif.h" +#include "core/fxcrt/fx_basic.h" + +class CCodec_GifModule; + +// TODO(npm): Get rid of this, maybe rename CGifDecompressor->GifContext +class FXGIF_Context { + public: + FXGIF_Context(); + ~FXGIF_Context(); + + std::unique_ptr m_Gif; + CCodec_GifModule* parent_ptr; +}; + +class CGifDecompressor { + public: + CGifDecompressor(FXGIF_Context* p, char* error_string); + ~CGifDecompressor(); + + void ErrorData(const char* err_msg); + uint8_t* AskBufForPal(int32_t pal_size); + 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, + void* pal_ptr, + int32_t delay_time, + bool user_input, + int32_t trans_index, + int32_t disposal_method, + bool interlace); + + jmp_buf jmpbuf; + std::vector m_GlobalPalette; + int32_t global_pal_num; + uint32_t img_row_offset; + uint32_t img_row_avail_size; + uint32_t avail_in; + int32_t decode_status; + uint32_t skip_size; + + char* err_ptr; + FXGIF_Context* context_ptr; + CFX_ByteString* cmt_data_ptr; + GifGCE* gce_ptr; + std::vector* pt_ptr_arr_ptr; + uint8_t* next_in; + std::vector* img_ptr_arr_ptr; + std::unique_ptr 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; +}; + +#endif // CORE_FXCODEC_LGIF_CGIFDECOMPRESSOR_H_ diff --git a/core/fxcodec/lgif/fx_gif.cpp b/core/fxcodec/lgif/fx_gif.cpp index 307834d867..059da925a4 100644 --- a/core/fxcodec/lgif/fx_gif.cpp +++ b/core/fxcodec/lgif/fx_gif.cpp @@ -9,6 +9,8 @@ #include #include "core/fxcodec/lbmp/fx_bmp.h" +#include "core/fxcodec/lgif/cgifdecompressor.h" +#include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" static_assert(sizeof(GifImageInfo) == 9, @@ -21,21 +23,13 @@ static_assert(sizeof(GifLSD) == 7, "GifLSD should have a size of 7"); namespace { -void gif_error(gif_decompress_struct_p gif_ptr, const char* err_msg) { - if (gif_ptr && gif_ptr->gif_error_fn) - gif_ptr->gif_error_fn(gif_ptr, err_msg); -} - -void gif_warn(gif_decompress_struct_p gif_ptr, const char* err_msg) {} - -void gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr, - GifGCE** gce_ptr_ptr) { +void gif_takeover_gce_ptr(CGifDecompressor* gif_ptr, GifGCE** gce_ptr_ptr) { *gce_ptr_ptr = nullptr; if (gif_ptr->gce_ptr) std::swap(*gce_ptr_ptr, gif_ptr->gce_ptr); } -uint8_t* gif_read_data(gif_decompress_struct_p gif_ptr, +uint8_t* gif_read_data(CGifDecompressor* gif_ptr, uint8_t** des_buf_pp, uint32_t data_size) { if (!gif_ptr || gif_ptr->avail_in < gif_ptr->skip_size + data_size) @@ -46,14 +40,14 @@ uint8_t* gif_read_data(gif_decompress_struct_p gif_ptr, return *des_buf_pp; } -void gif_save_decoding_status(gif_decompress_struct_p gif_ptr, int32_t status) { +void gif_save_decoding_status(CGifDecompressor* gif_ptr, int32_t status) { gif_ptr->decode_status = status; gif_ptr->next_in += gif_ptr->skip_size; gif_ptr->avail_in -= gif_ptr->skip_size; gif_ptr->skip_size = 0; } -GifDecodeStatus gif_decode_extension(gif_decompress_struct_p gif_ptr) { +GifDecodeStatus gif_decode_extension(CGifDecompressor* gif_ptr) { uint8_t* data_size_ptr = nullptr; uint8_t* data_ptr = nullptr; uint32_t skip_size_org = gif_ptr->skip_size; @@ -160,9 +154,9 @@ GifDecodeStatus gif_decode_extension(gif_decompress_struct_p gif_ptr) { return GifDecodeStatus::Success; } -GifDecodeStatus gif_decode_image_info(gif_decompress_struct_p gif_ptr) { +GifDecodeStatus gif_decode_image_info(CGifDecompressor* gif_ptr) { if (gif_ptr->width == 0 || gif_ptr->height == 0) { - gif_error(gif_ptr, "No Image Header Info"); + gif_ptr->ErrorData("No Image Header Info"); return GifDecodeStatus::Error; } uint32_t skip_size_org = gif_ptr->skip_size; @@ -191,7 +185,7 @@ GifDecodeStatus gif_decode_image_info(gif_decompress_struct_p gif_ptr) { FX_Free(gif_image_ptr->image_info_ptr); FX_Free(gif_image_ptr->image_row_buf); FX_Free(gif_image_ptr); - gif_error(gif_ptr, "Image Data Out Of LSD, The File May Be Corrupt"); + gif_ptr->ErrorData("Image Data Out Of LSD, The File May Be Corrupt"); return GifDecodeStatus::Error; } GifLF* gif_img_info_lf_ptr = (GifLF*)&gif_img_info_ptr->local_flag; @@ -206,7 +200,7 @@ GifDecodeStatus gif_decode_image_info(gif_decompress_struct_p gif_ptr) { return GifDecodeStatus::Unfinished; } gif_image_ptr->local_pal_ptr = - (GifPalette*)gif_ptr->gif_ask_buf_for_pal_fn(gif_ptr, loc_pal_size); + (GifPalette*)gif_ptr->AskBufForPal(loc_pal_size); if (gif_image_ptr->local_pal_ptr) { memcpy((uint8_t*)gif_image_ptr->local_pal_ptr, loc_pal_ptr, loc_pal_size); } @@ -221,8 +215,7 @@ GifDecodeStatus gif_decode_image_info(gif_decompress_struct_p gif_ptr) { return GifDecodeStatus::Unfinished; } gif_image_ptr->image_code_size = *code_size_ptr; - gif_ptr->gif_record_current_position_fn(gif_ptr, - &gif_image_ptr->image_data_pos); + gif_ptr->RecordCurrentPosition(&gif_image_ptr->image_data_pos); gif_image_ptr->image_data_pos += gif_ptr->skip_size; gif_takeover_gce_ptr(gif_ptr, &gif_image_ptr->image_gce_ptr); gif_ptr->img_ptr_arr_ptr->push_back(gif_image_ptr); @@ -230,12 +223,12 @@ GifDecodeStatus gif_decode_image_info(gif_decompress_struct_p gif_ptr) { return GifDecodeStatus::Success; } -void gif_decoding_failure_at_tail_cleanup(gif_decompress_struct_p gif_ptr, +void gif_decoding_failure_at_tail_cleanup(CGifDecompressor* gif_ptr, GifImage* gif_image_ptr) { FX_Free(gif_image_ptr->image_row_buf); gif_image_ptr->image_row_buf = nullptr; gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); - gif_error(gif_ptr, "Decode Image Data Error"); + gif_ptr->ErrorData("Decode Image Data Error"); } } // namespace @@ -403,56 +396,7 @@ GifDecodeStatus CGifLZWDecoder::Decode(uint8_t* des_buf, uint32_t* des_size) { return GifDecodeStatus::Error; } -gif_decompress_struct_p gif_create_decompress() { - gif_decompress_struct_p gif_ptr = FX_Alloc(gif_decompress_struct, 1); - memset(gif_ptr, 0, sizeof(gif_decompress_struct)); - gif_ptr->decode_status = GIF_D_STATUS_SIG; - gif_ptr->img_ptr_arr_ptr = new std::vector; - gif_ptr->cmt_data_ptr = new CFX_ByteString; - gif_ptr->pt_ptr_arr_ptr = new std::vector; - return gif_ptr; -} - -void gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr) { - if (!gif_ptr_ptr || !*gif_ptr_ptr) - return; - - gif_decompress_struct_p gif_ptr = *gif_ptr_ptr; - *gif_ptr_ptr = nullptr; - FX_Free(gif_ptr->global_pal_ptr); - delete gif_ptr->img_decoder_ptr; - if (gif_ptr->img_ptr_arr_ptr) { - size_t size_img_arr = gif_ptr->img_ptr_arr_ptr->size(); - for (size_t i = 0; i < size_img_arr; i++) { - GifImage* p = (*gif_ptr->img_ptr_arr_ptr)[i]; - FX_Free(p->image_info_ptr); - FX_Free(p->image_gce_ptr); - FX_Free(p->image_row_buf); - if (p->local_pal_ptr && p->local_pal_ptr != gif_ptr->global_pal_ptr) - FX_Free(p->local_pal_ptr); - FX_Free(p); - } - gif_ptr->img_ptr_arr_ptr->clear(); - delete gif_ptr->img_ptr_arr_ptr; - } - delete gif_ptr->cmt_data_ptr; - FX_Free(gif_ptr->gce_ptr); - if (gif_ptr->pt_ptr_arr_ptr) { - size_t size_pt_arr = gif_ptr->pt_ptr_arr_ptr->size(); - for (size_t i = 0; i < size_pt_arr; i++) { - GifPlainText* p = (*gif_ptr->pt_ptr_arr_ptr)[i]; - FX_Free(p->gce_ptr); - FX_Free(p->pte_ptr); - delete p->string_ptr; - FX_Free(p); - } - gif_ptr->pt_ptr_arr_ptr->clear(); - delete gif_ptr->pt_ptr_arr_ptr; - } - FX_Free(gif_ptr); -} - -GifDecodeStatus gif_read_header(gif_decompress_struct_p gif_ptr) { +GifDecodeStatus gif_read_header(CGifDecompressor* gif_ptr) { if (!gif_ptr) return GifDecodeStatus::Error; @@ -463,7 +407,7 @@ GifDecodeStatus gif_read_header(gif_decompress_struct_p gif_ptr) { if (strncmp(gif_header_ptr->signature, GIF_SIGNATURE, 3) != 0 || gif_header_ptr->version[0] != '8' || gif_header_ptr->version[2] != 'a') { - gif_error(gif_ptr, "Not A Gif Image"); + gif_ptr->ErrorData("Not A Gif Image"); return GifDecodeStatus::Error; } GifLSD* gif_lsd_ptr = nullptr; @@ -483,9 +427,8 @@ GifDecodeStatus gif_read_header(gif_decompress_struct_p gif_ptr) { gif_ptr->global_sort_flag = ((GifGF*)&gif_lsd_ptr->global_flag)->sort_flag; gif_ptr->global_color_resolution = ((GifGF*)&gif_lsd_ptr->global_flag)->color_resolution; - FX_Free(gif_ptr->global_pal_ptr); - gif_ptr->global_pal_ptr = (GifPalette*)FX_Alloc(uint8_t, global_pal_size); - memcpy(gif_ptr->global_pal_ptr, global_pal_ptr, global_pal_size); + gif_ptr->m_GlobalPalette.resize(global_pal_size / 3); + memcpy(gif_ptr->m_GlobalPalette.data(), global_pal_ptr, global_pal_size); } gif_ptr->width = (int)GetWord_LSBFirst((uint8_t*)&gif_lsd_ptr->width); gif_ptr->height = (int)GetWord_LSBFirst((uint8_t*)&gif_lsd_ptr->height); @@ -494,7 +437,7 @@ GifDecodeStatus gif_read_header(gif_decompress_struct_p gif_ptr) { return GifDecodeStatus::Success; } -GifDecodeStatus gif_get_frame(gif_decompress_struct_p gif_ptr) { +GifDecodeStatus gif_get_frame(CGifDecompressor* gif_ptr) { if (!gif_ptr) return GifDecodeStatus::Error; @@ -520,11 +463,11 @@ GifDecodeStatus gif_get_frame(gif_decompress_struct_p gif_ptr) { return GifDecodeStatus::Success; default: if (gif_ptr->avail_in) { - gif_warn(gif_ptr, "The Gif File has non_standard Tag!"); + // The Gif File has non_standard Tag! gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG); continue; } - gif_warn(gif_ptr, "The Gif File Doesn't have Trailer Tag!"); + // The Gif File Doesn't have Trailer Tag! return GifDecodeStatus::Success; } } @@ -590,8 +533,7 @@ GifDecodeStatus gif_get_frame(gif_decompress_struct_p gif_ptr) { return GifDecodeStatus::Success; } -GifDecodeStatus gif_load_frame(gif_decompress_struct_p gif_ptr, - int32_t frame_num) { +GifDecodeStatus gif_load_frame(CGifDecompressor* gif_ptr, int32_t frame_num) { if (!gif_ptr || !pdfium::IndexInBounds(*gif_ptr->img_ptr_arr_ptr, frame_num)) return GifDecodeStatus::Error; @@ -601,7 +543,7 @@ GifDecodeStatus gif_load_frame(gif_decompress_struct_p gif_ptr, GifImage* gif_image_ptr = (*gif_ptr->img_ptr_arr_ptr)[frame_num]; uint32_t gif_img_row_bytes = gif_image_ptr->image_info_ptr->width; if (gif_img_row_bytes == 0) { - gif_error(gif_ptr, "Error Invalid Number of Row Bytes"); + gif_ptr->ErrorData("Error Invalid Number of Row Bytes"); return GifDecodeStatus::Error; } if (gif_ptr->decode_status == GIF_D_STATUS_TAIL) { @@ -618,9 +560,8 @@ GifDecodeStatus gif_load_frame(gif_decompress_struct_p gif_ptr, : 0; gif_ptr->avail_in = 0; if (!gif_img_gce_ptr) { - bool bRes = gif_ptr->gif_get_record_position_fn( - gif_ptr, gif_image_ptr->image_data_pos, - gif_image_ptr->image_info_ptr->left, + bool bRes = gif_ptr->GetRecordPosition( + gif_image_ptr->image_data_pos, gif_image_ptr->image_info_ptr->left, gif_image_ptr->image_info_ptr->top, gif_image_ptr->image_info_ptr->width, gif_image_ptr->image_info_ptr->height, loc_pal_num, @@ -630,13 +571,12 @@ GifDecodeStatus gif_load_frame(gif_decompress_struct_p gif_ptr, if (!bRes) { FX_Free(gif_image_ptr->image_row_buf); gif_image_ptr->image_row_buf = nullptr; - gif_error(gif_ptr, "Error Read Record Position Data"); + gif_ptr->ErrorData("Error Read Record Position Data"); return GifDecodeStatus::Error; } } else { - bool bRes = gif_ptr->gif_get_record_position_fn( - gif_ptr, gif_image_ptr->image_data_pos, - gif_image_ptr->image_info_ptr->left, + bool bRes = gif_ptr->GetRecordPosition( + gif_image_ptr->image_data_pos, gif_image_ptr->image_info_ptr->left, gif_image_ptr->image_info_ptr->top, gif_image_ptr->image_info_ptr->width, gif_image_ptr->image_info_ptr->height, loc_pal_num, @@ -653,26 +593,27 @@ GifDecodeStatus gif_load_frame(gif_decompress_struct_p gif_ptr, if (!bRes) { FX_Free(gif_image_ptr->image_row_buf); gif_image_ptr->image_row_buf = nullptr; - gif_error(gif_ptr, "Error Read Record Position Data"); + gif_ptr->ErrorData("Error Read Record Position Data"); return GifDecodeStatus::Error; } } if (gif_image_ptr->image_code_size >= 32) { FX_Free(gif_image_ptr->image_row_buf); gif_image_ptr->image_row_buf = nullptr; - gif_error(gif_ptr, "Error Invalid Code Size"); + gif_ptr->ErrorData("Error Invalid Code Size"); return GifDecodeStatus::Error; } - if (!gif_ptr->img_decoder_ptr) - gif_ptr->img_decoder_ptr = new CGifLZWDecoder(gif_ptr->err_ptr); - gif_ptr->img_decoder_ptr->InitTable(gif_image_ptr->image_code_size); + if (!gif_ptr->m_ImgDecoder.get()) + gif_ptr->m_ImgDecoder = + pdfium::MakeUnique(gif_ptr->err_ptr); + gif_ptr->m_ImgDecoder->InitTable(gif_image_ptr->image_code_size); gif_ptr->img_row_offset = 0; gif_ptr->img_row_avail_size = 0; gif_ptr->img_pass_num = 0; gif_image_ptr->image_row_num = 0; gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA); } - CGifLZWDecoder* img_decoder_ptr = gif_ptr->img_decoder_ptr; + CGifLZWDecoder* img_decoder_ptr = gif_ptr->m_ImgDecoder.get(); if (gif_ptr->decode_status == GIF_D_STATUS_IMG_DATA) { if (!gif_read_data(gif_ptr, &data_size_ptr, 1)) return GifDecodeStatus::Unfinished; @@ -695,8 +636,8 @@ GifDecodeStatus gif_load_frame(gif_decompress_struct_p gif_ptr, } while (ret != GifDecodeStatus::Error) { if (ret == GifDecodeStatus::Success) { - gif_ptr->gif_get_row_fn(gif_ptr, gif_image_ptr->image_row_num, - gif_image_ptr->image_row_buf); + gif_ptr->ReadScanline(gif_image_ptr->image_row_num, + gif_image_ptr->image_row_buf); FX_Free(gif_image_ptr->image_row_buf); gif_image_ptr->image_row_buf = nullptr; gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); @@ -725,8 +666,8 @@ GifDecodeStatus gif_load_frame(gif_decompress_struct_p gif_ptr, } if (ret == GifDecodeStatus::InsufficientDestSize) { if (((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)->interlace) { - gif_ptr->gif_get_row_fn(gif_ptr, gif_image_ptr->image_row_num, - gif_image_ptr->image_row_buf); + gif_ptr->ReadScanline(gif_image_ptr->image_row_num, + gif_image_ptr->image_row_buf); gif_image_ptr->image_row_num += s_gif_interlace_step[gif_ptr->img_pass_num]; if (gif_image_ptr->image_row_num >= @@ -740,8 +681,8 @@ GifDecodeStatus gif_load_frame(gif_decompress_struct_p gif_ptr, s_gif_interlace_step[gif_ptr->img_pass_num] / 2; } } else { - gif_ptr->gif_get_row_fn(gif_ptr, gif_image_ptr->image_row_num++, - gif_image_ptr->image_row_buf); + gif_ptr->ReadScanline(gif_image_ptr->image_row_num++, + gif_image_ptr->image_row_buf); } gif_ptr->img_row_offset = 0; gif_ptr->img_row_avail_size = gif_img_row_bytes; @@ -757,11 +698,11 @@ GifDecodeStatus gif_load_frame(gif_decompress_struct_p gif_ptr, } gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); } - gif_error(gif_ptr, "Decode Image Data Error"); + gif_ptr->ErrorData("Decode Image Data Error"); return GifDecodeStatus::Error; } -void gif_input_buffer(gif_decompress_struct_p gif_ptr, +void gif_input_buffer(CGifDecompressor* gif_ptr, uint8_t* src_buf, uint32_t src_size) { gif_ptr->next_in = src_buf; @@ -769,7 +710,7 @@ void gif_input_buffer(gif_decompress_struct_p gif_ptr, gif_ptr->skip_size = 0; } -uint32_t gif_get_avail_input(gif_decompress_struct_p gif_ptr, +uint32_t gif_get_avail_input(CGifDecompressor* gif_ptr, uint8_t** avail_buf_ptr) { if (avail_buf_ptr) { *avail_buf_ptr = nullptr; @@ -779,6 +720,6 @@ uint32_t gif_get_avail_input(gif_decompress_struct_p gif_ptr, return gif_ptr->avail_in; } -int32_t gif_get_frame_num(gif_decompress_struct_p gif_ptr) { +int32_t gif_get_frame_num(CGifDecompressor* gif_ptr) { return pdfium::CollectionSize(*gif_ptr->img_ptr_arr_ptr); } diff --git a/core/fxcodec/lgif/fx_gif.h b/core/fxcodec/lgif/fx_gif.h index c83368479c..58dad203d1 100644 --- a/core/fxcodec/lgif/fx_gif.h +++ b/core/fxcodec/lgif/fx_gif.h @@ -12,6 +12,8 @@ #include "core/fxcrt/fx_basic.h" +class CGifDecompressor; + #define GIF_SIGNATURE "GIF" #define GIF_SIG_EXTENSION 0x21 #define GIF_SIG_IMAGE 0x2C @@ -162,69 +164,16 @@ class CGifLZWDecoder { char* err_msg_ptr; }; -typedef struct tag_gif_decompress_struct gif_decompress_struct; -typedef gif_decompress_struct* gif_decompress_struct_p; -typedef gif_decompress_struct_p* gif_decompress_struct_pp; static const int32_t s_gif_interlace_step[4] = {8, 8, 4, 2}; -struct tag_gif_decompress_struct { - jmp_buf jmpbuf; - char* err_ptr; - void (*gif_error_fn)(gif_decompress_struct_p gif_ptr, const char* err_msg); - void* context_ptr; - int width; - int height; - GifPalette* global_pal_ptr; - int32_t global_pal_num; - uint8_t global_sort_flag; - uint8_t global_color_resolution; - - uint8_t bc_index; - uint8_t pixel_aspect; - CGifLZWDecoder* img_decoder_ptr; - uint32_t img_row_offset; - uint32_t img_row_avail_size; - uint8_t img_pass_num; - std::vector* img_ptr_arr_ptr; - uint8_t* (*gif_ask_buf_for_pal_fn)(gif_decompress_struct_p gif_ptr, - int32_t pal_size); - uint8_t* next_in; - uint32_t avail_in; - int32_t decode_status; - uint32_t skip_size; - void (*gif_record_current_position_fn)(gif_decompress_struct_p gif_ptr, - uint32_t* cur_pos_ptr); - void (*gif_get_row_fn)(gif_decompress_struct_p gif_ptr, - int32_t row_num, - uint8_t* row_buf); - bool (*gif_get_record_position_fn)(gif_decompress_struct_p gif_ptr, - uint32_t cur_pos, - int32_t left, - int32_t top, - int32_t width, - int32_t height, - int32_t pal_num, - void* pal_ptr, - int32_t delay_time, - bool user_input, - int32_t trans_index, - int32_t disposal_method, - bool interlace); - CFX_ByteString* cmt_data_ptr; - GifGCE* gce_ptr; - std::vector* pt_ptr_arr_ptr; -}; -gif_decompress_struct_p gif_create_decompress(); -void gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr); -GifDecodeStatus gif_read_header(gif_decompress_struct_p gif_ptr); -GifDecodeStatus gif_get_frame(gif_decompress_struct_p gif_ptr); -int32_t gif_get_frame_num(gif_decompress_struct_p gif_ptr); -GifDecodeStatus gif_load_frame(gif_decompress_struct_p gif_ptr, - int32_t frame_num); -void gif_input_buffer(gif_decompress_struct_p gif_ptr, +GifDecodeStatus gif_read_header(CGifDecompressor* gif_ptr); +GifDecodeStatus gif_get_frame(CGifDecompressor* gif_ptr); +int32_t gif_get_frame_num(CGifDecompressor* gif_ptr); +GifDecodeStatus gif_load_frame(CGifDecompressor* gif_ptr, int32_t frame_num); +void gif_input_buffer(CGifDecompressor* gif_ptr, uint8_t* src_buf, uint32_t src_size); -uint32_t gif_get_avail_input(gif_decompress_struct_p gif_ptr, +uint32_t gif_get_avail_input(CGifDecompressor* gif_ptr, uint8_t** avail_buf_ptr); #endif // CORE_FXCODEC_LGIF_FX_GIF_H_ -- cgit v1.2.3