// 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/codec/ccodec_gifmodule.h" #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" #include "third_party/base/ptr_util.h" CCodec_GifModule::CCodec_GifModule() { memset(m_szLastError, 0, sizeof(m_szLastError)); } CCodec_GifModule::~CCodec_GifModule() {} FXGIF_Context* CCodec_GifModule::Start() { FXGIF_Context* p = FX_Alloc(FXGIF_Context, 1); if (!p) return nullptr; memset(p, 0, sizeof(FXGIF_Context)); p->parent_ptr = this; p->m_Gif = pdfium::MakeUnique(p, m_szLastError); return p; } void CCodec_GifModule::Finish(FXGIF_Context* ctx) { if (ctx) { ctx->m_Gif = nullptr; FX_Free(ctx); } } GifDecodeStatus CCodec_GifModule::ReadHeader(FXGIF_Context* ctx, int* width, int* height, int* pal_num, void** pal_pp, int* bg_index, CFX_DIBAttribute* pAttribute) { if (setjmp(ctx->m_Gif->jmpbuf)) return GifDecodeStatus::Error; GifDecodeStatus ret = gif_read_header(ctx->m_Gif.get()); if (ret != GifDecodeStatus::Success) return ret; *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.empty() ? nullptr : 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->m_Gif->jmpbuf)) return GifDecodeStatus::Error; GifDecodeStatus ret = gif_get_frame(ctx->m_Gif.get()); if (ret != GifDecodeStatus::Success) return ret; *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->m_Gif->jmpbuf)) return GifDecodeStatus::Error; GifDecodeStatus ret = gif_load_frame(ctx->m_Gif.get(), frame_num); if (ret == GifDecodeStatus::Success) { if (pAttribute) { pAttribute->m_nGifLeft = ctx->m_Gif->m_Images[frame_num]->m_ImageInfo.left; pAttribute->m_nGifTop = ctx->m_Gif->m_Images[frame_num]->m_ImageInfo.top; pAttribute->m_fAspectRatio = ctx->m_Gif->pixel_aspect; const uint8_t* buf = reinterpret_cast(ctx->m_Gif->cmt_data.GetBuffer(0)); uint32_t len = ctx->m_Gif->cmt_data.GetLength(); if (len > 21) { uint8_t size = *buf++; if (size != 0) pAttribute->m_strAuthor = CFX_ByteString(buf, size); else pAttribute->m_strAuthor.clear(); } } } return ret; } uint32_t CCodec_GifModule::GetAvailInput(FXGIF_Context* ctx, uint8_t** 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->m_Gif.get(), (uint8_t*)src_buf, src_size); }