From 73c9f3bb3d82563d6d4496c4b0204d5c0825e8a2 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Mon, 27 Feb 2017 10:12:59 -0800 Subject: Allow building XFA without additional codecs. This is something we'd like to try for initial XFA launches adding in codecs as justified by results in the wild. Adding statistics for the unsupported cases is a follow-up exercise once this builds correctly. We always build all the additional libraries, to allow fuzzers to link against them even if we are not shipping them. The linker will sort it out for the actual code. Rename some files to match the classes contained within. That the existing tests seem to pass with the codecs disabled warrants further investigation. Change-Id: Iad269db91289f12dc9f5dda8f48121d27a0c4367 Reviewed-on: https://pdfium-review.googlesource.com/2836 Commit-Queue: Tom Sepez Reviewed-by: Lei Zhang --- core/fxcodec/codec/ccodec_bmpmodule.cpp | 127 +++++++ core/fxcodec/codec/ccodec_gifmodule.cpp | 189 ++++++++++ core/fxcodec/codec/ccodec_gifmodule.h | 2 + core/fxcodec/codec/ccodec_pngmodule.cpp | 258 +++++++++++++ core/fxcodec/codec/ccodec_progressivedecoder.h | 30 +- core/fxcodec/codec/ccodec_tiffmodule.cpp | 504 +++++++++++++++++++++++++ core/fxcodec/codec/fx_codec.cpp | 14 +- core/fxcodec/codec/fx_codec_bmp.cpp | 124 ------ core/fxcodec/codec/fx_codec_gif.cpp | 186 --------- core/fxcodec/codec/fx_codec_png.cpp | 256 ------------- core/fxcodec/codec/fx_codec_progress.cpp | 62 ++- core/fxcodec/codec/fx_codec_tiff.cpp | 502 ------------------------ 12 files changed, 1164 insertions(+), 1090 deletions(-) create mode 100644 core/fxcodec/codec/ccodec_bmpmodule.cpp create mode 100644 core/fxcodec/codec/ccodec_gifmodule.cpp create mode 100644 core/fxcodec/codec/ccodec_pngmodule.cpp create mode 100644 core/fxcodec/codec/ccodec_tiffmodule.cpp delete mode 100644 core/fxcodec/codec/fx_codec_bmp.cpp delete mode 100644 core/fxcodec/codec/fx_codec_gif.cpp delete mode 100644 core/fxcodec/codec/fx_codec_png.cpp delete mode 100644 core/fxcodec/codec/fx_codec_tiff.cpp (limited to 'core/fxcodec/codec') diff --git a/core/fxcodec/codec/ccodec_bmpmodule.cpp b/core/fxcodec/codec/ccodec_bmpmodule.cpp new file mode 100644 index 0000000000..c6ebd2d939 --- /dev/null +++ b/core/fxcodec/codec/ccodec_bmpmodule.cpp @@ -0,0 +1,127 @@ +// 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_bmpmodule.h" + +#include "core/fxcodec/codec/codec_int.h" +#include "core/fxcodec/fx_codec.h" +#include "core/fxcodec/lbmp/fx_bmp.h" +#include "core/fxge/fx_dib.h" + +struct FXBMP_Context { + bmp_decompress_struct_p bmp_ptr; + void* parent_ptr; + void* child_ptr; + + void* (*m_AllocFunc)(unsigned int); + void (*m_FreeFunc)(void*); +}; +extern "C" { +static void* bmp_alloc_func(unsigned int size) { + return FX_Alloc(char, size); +} +static void bmp_free_func(void* p) { + FX_Free(p); +} +}; +static void bmp_error_data(bmp_decompress_struct_p bmp_ptr, + const FX_CHAR* err_msg) { + FXSYS_strncpy((char*)bmp_ptr->err_ptr, err_msg, BMP_MAX_ERROR_SIZE - 1); + longjmp(bmp_ptr->jmpbuf, 1); +} +static void bmp_read_scanline(bmp_decompress_struct_p bmp_ptr, + int32_t row_num, + uint8_t* row_buf) { + FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr; + CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr; + pModule->ReadScanlineCallback(p->child_ptr, row_num, row_buf); +} +static bool bmp_get_data_position(bmp_decompress_struct_p bmp_ptr, + uint32_t rcd_pos) { + FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr; + CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr; + return pModule->InputImagePositionBufCallback(p->child_ptr, rcd_pos); +} + +FXBMP_Context* CCodec_BmpModule::Start(void* pModule) { + FXBMP_Context* p = FX_Alloc(FXBMP_Context, 1); + if (!p) + return nullptr; + + FXSYS_memset(p, 0, sizeof(FXBMP_Context)); + if (!p) + return nullptr; + + p->m_AllocFunc = bmp_alloc_func; + p->m_FreeFunc = bmp_free_func; + p->bmp_ptr = nullptr; + p->parent_ptr = (void*)this; + p->child_ptr = pModule; + p->bmp_ptr = bmp_create_decompress(); + if (!p->bmp_ptr) { + FX_Free(p); + return nullptr; + } + p->bmp_ptr->context_ptr = (void*)p; + p->bmp_ptr->err_ptr = m_szLastError; + p->bmp_ptr->bmp_error_fn = bmp_error_data; + p->bmp_ptr->bmp_get_row_fn = bmp_read_scanline; + p->bmp_ptr->bmp_get_data_position_fn = bmp_get_data_position; + return p; +} + +void CCodec_BmpModule::Finish(FXBMP_Context* ctx) { + if (ctx) { + bmp_destroy_decompress(&ctx->bmp_ptr); + ctx->m_FreeFunc(ctx); + } +} +int32_t CCodec_BmpModule::ReadHeader(FXBMP_Context* ctx, + int32_t* width, + int32_t* height, + bool* tb_flag, + int32_t* components, + int32_t* pal_num, + uint32_t** pal_pp, + CFX_DIBAttribute* pAttribute) { + if (setjmp(ctx->bmp_ptr->jmpbuf)) { + return 0; + } + int32_t ret = bmp_read_header(ctx->bmp_ptr); + if (ret != 1) { + return ret; + } + *width = ctx->bmp_ptr->width; + *height = ctx->bmp_ptr->height; + *tb_flag = ctx->bmp_ptr->imgTB_flag; + *components = ctx->bmp_ptr->components; + *pal_num = ctx->bmp_ptr->pal_num; + *pal_pp = ctx->bmp_ptr->pal_ptr; + if (pAttribute) { + pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER; + pAttribute->m_nXDPI = ctx->bmp_ptr->dpi_x; + pAttribute->m_nYDPI = ctx->bmp_ptr->dpi_y; + pAttribute->m_nBmpCompressType = ctx->bmp_ptr->compress_flag; + } + return 1; +} + +int32_t CCodec_BmpModule::LoadImage(FXBMP_Context* ctx) { + if (setjmp(ctx->bmp_ptr->jmpbuf)) + return 0; + return bmp_decode_image(ctx->bmp_ptr); +} + +uint32_t CCodec_BmpModule::GetAvailInput(FXBMP_Context* ctx, + uint8_t** avail_buf_ptr) { + return bmp_get_avail_input(ctx->bmp_ptr, avail_buf_ptr); +} + +void CCodec_BmpModule::Input(FXBMP_Context* ctx, + const uint8_t* src_buf, + uint32_t src_size) { + bmp_input_buffer(ctx->bmp_ptr, (uint8_t*)src_buf, src_size); +} diff --git a/core/fxcodec/codec/ccodec_gifmodule.cpp b/core/fxcodec/codec/ccodec_gifmodule.cpp new file mode 100644 index 0000000000..e3b2648c43 --- /dev/null +++ b/core/fxcodec/codec/ccodec_gifmodule.cpp @@ -0,0 +1,189 @@ +// 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/fx_gif.h" +#include "core/fxge/fx_dib.h" + +struct FXGIF_Context { + gif_decompress_struct_p gif_ptr; + void* parent_ptr; + void* child_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 FX_CHAR* err_msg) { + FXSYS_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->AskLocalPaletteBufCallback( + p->child_ptr, 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->RecordCurrentPositionCallback(p->child_ptr, *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->ReadScanlineCallback(p->child_ptr, 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->InputRecordPositionBufCallback( + p->child_ptr, cur_pos, FX_RECT(left, top, left + width, top + height), + pal_num, pal_ptr, delay_time, user_input, trans_index, disposal_method, + interlace); +} + +FXGIF_Context* CCodec_GifModule::Start(void* pModule) { + FXGIF_Context* p = FX_Alloc(FXGIF_Context, 1); + if (!p) + return nullptr; + + FXSYS_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 = (void*)this; + p->child_ptr = pModule; + p->gif_ptr = gif_create_decompress(); + if (!p->gif_ptr) { + FX_Free(p); + return nullptr; + } + p->gif_ptr->context_ptr = (void*)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; + return p; +} + +void CCodec_GifModule::Finish(FXGIF_Context* ctx) { + if (ctx) { + gif_destroy_decompress(&ctx->gif_ptr); + ctx->m_FreeFunc(ctx); + } +} + +int32_t 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->gif_ptr->jmpbuf)) + return 0; + + int32_t ret = gif_read_header(ctx->gif_ptr); + if (ret != 1) + 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; + return 1; +} + +int32_t CCodec_GifModule::LoadFrameInfo(FXGIF_Context* ctx, int* frame_num) { + if (setjmp(ctx->gif_ptr->jmpbuf)) + return 0; + + int32_t ret = gif_get_frame(ctx->gif_ptr); + if (ret != 1) + return ret; + + *frame_num = gif_get_frame_num(ctx->gif_ptr); + return 1; +} + +int32_t CCodec_GifModule::LoadFrame(FXGIF_Context* ctx, + int frame_num, + CFX_DIBAttribute* pAttribute) { + if (setjmp(ctx->gif_ptr->jmpbuf)) + return 0; + + int32_t ret = gif_load_frame(ctx->gif_ptr, frame_num); + if (ret == 1) { + if (pAttribute) { + pAttribute->m_nGifLeft = + (*ctx->gif_ptr->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) { + 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(); + if (len > 21) { + uint8_t size = *buf++; + if (size) { + pAttribute->m_strAuthor = CFX_ByteString(buf, size); + } else { + pAttribute->m_strAuthor.clear(); + } + buf += size; + size = *buf++; + if (size == 20) { + FXSYS_memcpy(pAttribute->m_strTime, buf, size); + } + } + } + } + } + return ret; +} + +uint32_t CCodec_GifModule::GetAvailInput(FXGIF_Context* ctx, + uint8_t** avail_buf_ptr) { + return gif_get_avail_input(ctx->gif_ptr, 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); +} diff --git a/core/fxcodec/codec/ccodec_gifmodule.h b/core/fxcodec/codec/ccodec_gifmodule.h index fac621d256..21ac92d6c7 100644 --- a/core/fxcodec/codec/ccodec_gifmodule.h +++ b/core/fxcodec/codec/ccodec_gifmodule.h @@ -7,8 +7,10 @@ #ifndef CORE_FXCODEC_CODEC_CCODEC_GIFMODULE_H_ #define CORE_FXCODEC_CODEC_CCODEC_GIFMODULE_H_ +#include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_system.h" +class CFX_DIBAttribute; struct FXGIF_Context; class CCodec_GifModule { diff --git a/core/fxcodec/codec/ccodec_pngmodule.cpp b/core/fxcodec/codec/ccodec_pngmodule.cpp new file mode 100644 index 0000000000..d3e24cd9ea --- /dev/null +++ b/core/fxcodec/codec/ccodec_pngmodule.cpp @@ -0,0 +1,258 @@ +// 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_pngmodule.h" + +#include + +#include "core/fxcodec/codec/codec_int.h" +#include "core/fxcodec/fx_codec.h" +#include "core/fxge/fx_dib.h" + +extern "C" { +#undef FAR +#include "third_party/libpng16/png.h" +} + +static void _png_error_data(png_structp png_ptr, png_const_charp error_msg) { + if (png_get_error_ptr(png_ptr)) { + FXSYS_strncpy((char*)png_get_error_ptr(png_ptr), error_msg, + PNG_ERROR_SIZE - 1); + } + longjmp(png_jmpbuf(png_ptr), 1); +} +static void _png_warning_data(png_structp png_ptr, png_const_charp error_msg) {} +static void _png_load_bmp_attribute(png_structp png_ptr, + png_infop info_ptr, + CFX_DIBAttribute* pAttribute) { + if (pAttribute) { +#if defined(PNG_pHYs_SUPPORTED) + pAttribute->m_nXDPI = png_get_x_pixels_per_meter(png_ptr, info_ptr); + pAttribute->m_nYDPI = png_get_y_pixels_per_meter(png_ptr, info_ptr); + png_uint_32 res_x, res_y; + int unit_type; + png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type); + switch (unit_type) { + case PNG_RESOLUTION_METER: + pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER; + break; + default: + pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_NONE; + } +#endif +#if defined(PNG_iCCP_SUPPORTED) + png_charp icc_name; + png_bytep icc_profile; + png_uint_32 icc_proflen; + int compress_type; + png_get_iCCP(png_ptr, info_ptr, &icc_name, &compress_type, &icc_profile, + &icc_proflen); +#endif + int bTime = 0; +#if defined(PNG_tIME_SUPPORTED) + png_timep t = nullptr; + png_get_tIME(png_ptr, info_ptr, &t); + if (t) { + FXSYS_memset(pAttribute->m_strTime, 0, sizeof(pAttribute->m_strTime)); + FXSYS_snprintf((FX_CHAR*)pAttribute->m_strTime, + sizeof(pAttribute->m_strTime), "%4u:%2u:%2u %2u:%2u:%2u", + t->year, t->month, t->day, t->hour, t->minute, t->second); + pAttribute->m_strTime[sizeof(pAttribute->m_strTime) - 1] = 0; + bTime = 1; + } +#endif +#if defined(PNG_TEXT_SUPPORTED) + int i; + FX_STRSIZE len; + const FX_CHAR* buf; + int num_text; + png_textp text = nullptr; + png_get_text(png_ptr, info_ptr, &text, &num_text); + for (i = 0; i < num_text; i++) { + len = FXSYS_strlen(text[i].key); + buf = "Time"; + if (!FXSYS_memcmp(buf, text[i].key, std::min(len, FXSYS_strlen(buf)))) { + if (!bTime) { + FXSYS_memset(pAttribute->m_strTime, 0, sizeof(pAttribute->m_strTime)); + FXSYS_memcpy( + pAttribute->m_strTime, text[i].text, + std::min(sizeof(pAttribute->m_strTime) - 1, text[i].text_length)); + } + } else { + buf = "Author"; + if (!FXSYS_memcmp(buf, text[i].key, std::min(len, FXSYS_strlen(buf)))) { + pAttribute->m_strAuthor = + CFX_ByteString(reinterpret_cast(text[i].text), + static_cast(text[i].text_length)); + } + } + } +#endif + } +} +struct FXPNG_Context { + png_structp png_ptr; + png_infop info_ptr; + void* parent_ptr; + void* child_ptr; + + void* (*m_AllocFunc)(unsigned int); + void (*m_FreeFunc)(void*); +}; +extern "C" { +static void* _png_alloc_func(unsigned int size) { + return FX_Alloc(char, size); +} +static void _png_free_func(void* p) { + FX_Free(p); +} +}; +static void _png_get_header_func(png_structp png_ptr, png_infop info_ptr) { + FXPNG_Context* p = (FXPNG_Context*)png_get_progressive_ptr(png_ptr); + if (!p) + return; + + CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; + if (!pModule) + return; + + png_uint_32 width = 0, height = 0; + int bpc = 0, color_type = 0, color_type1 = 0, pass = 0; + double gamma = 1.0; + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bpc, &color_type, nullptr, + nullptr, nullptr); + color_type1 = color_type; + if (bpc > 8) { + png_set_strip_16(png_ptr); + } else if (bpc < 8) { + png_set_expand_gray_1_2_4_to_8(png_ptr); + } + bpc = 8; + if (color_type == PNG_COLOR_TYPE_PALETTE) { + png_set_palette_to_rgb(png_ptr); + } + pass = png_set_interlace_handling(png_ptr); + if (!pModule->ReadHeaderCallback(p->child_ptr, width, height, bpc, pass, + &color_type, &gamma)) { + png_error(p->png_ptr, "Read Header Callback Error"); + } + int intent; + if (png_get_sRGB(png_ptr, info_ptr, &intent)) { + png_set_gamma(png_ptr, gamma, 0.45455); + } else { + double image_gamma; + if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) { + png_set_gamma(png_ptr, gamma, image_gamma); + } else { + png_set_gamma(png_ptr, gamma, 0.45455); + } + } + switch (color_type) { + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_GRAY_ALPHA: { + if (color_type1 & PNG_COLOR_MASK_COLOR) { + png_set_rgb_to_gray(png_ptr, 1, 0.299, 0.587); + } + } break; + case PNG_COLOR_TYPE_PALETTE: + if (color_type1 != PNG_COLOR_TYPE_PALETTE) { + png_error(p->png_ptr, "Not Support Output Palette Now"); + } + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_RGB_ALPHA: + if (!(color_type1 & PNG_COLOR_MASK_COLOR)) { + png_set_gray_to_rgb(png_ptr); + } + png_set_bgr(png_ptr); + break; + } + if (!(color_type & PNG_COLOR_MASK_ALPHA)) { + png_set_strip_alpha(png_ptr); + } + if (color_type & PNG_COLOR_MASK_ALPHA && + !(color_type1 & PNG_COLOR_MASK_ALPHA)) { + png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); + } + png_read_update_info(png_ptr, info_ptr); +} +static void _png_get_end_func(png_structp png_ptr, png_infop info_ptr) {} +static void _png_get_row_func(png_structp png_ptr, + png_bytep new_row, + png_uint_32 row_num, + int pass) { + FXPNG_Context* p = (FXPNG_Context*)png_get_progressive_ptr(png_ptr); + if (!p) + return; + + CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; + uint8_t* src_buf = nullptr; + if (!pModule->AskScanlineBufCallback(p->child_ptr, row_num, src_buf)) { + png_error(png_ptr, "Ask Scanline buffer Callback Error"); + } + if (src_buf) { + png_progressive_combine_row(png_ptr, src_buf, new_row); + } + pModule->FillScanlineBufCompletedCallback(p->child_ptr, pass, row_num); +} + +FXPNG_Context* CCodec_PngModule::Start(void* pModule) { + FXPNG_Context* p = FX_Alloc(FXPNG_Context, 1); + if (!p) + return nullptr; + + p->m_AllocFunc = _png_alloc_func; + p->m_FreeFunc = _png_free_func; + p->png_ptr = nullptr; + p->info_ptr = nullptr; + p->parent_ptr = (void*)this; + p->child_ptr = pModule; + p->png_ptr = + png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + if (!p->png_ptr) { + FX_Free(p); + return nullptr; + } + p->info_ptr = png_create_info_struct(p->png_ptr); + if (!p->info_ptr) { + png_destroy_read_struct(&(p->png_ptr), nullptr, nullptr); + FX_Free(p); + return nullptr; + } + if (setjmp(png_jmpbuf(p->png_ptr))) { + if (p) { + png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), nullptr); + FX_Free(p); + } + return nullptr; + } + png_set_progressive_read_fn(p->png_ptr, p, _png_get_header_func, + _png_get_row_func, _png_get_end_func); + png_set_error_fn(p->png_ptr, m_szLastError, (png_error_ptr)_png_error_data, + (png_error_ptr)_png_warning_data); + return p; +} + +void CCodec_PngModule::Finish(FXPNG_Context* ctx) { + if (ctx) { + png_destroy_read_struct(&(ctx->png_ptr), &(ctx->info_ptr), nullptr); + ctx->m_FreeFunc(ctx); + } +} + +bool CCodec_PngModule::Input(FXPNG_Context* ctx, + const uint8_t* src_buf, + uint32_t src_size, + CFX_DIBAttribute* pAttribute) { + if (setjmp(png_jmpbuf(ctx->png_ptr))) { + if (pAttribute && + 0 == FXSYS_strcmp(m_szLastError, "Read Header Callback Error")) { + _png_load_bmp_attribute(ctx->png_ptr, ctx->info_ptr, pAttribute); + } + return false; + } + png_process_data(ctx->png_ptr, ctx->info_ptr, (uint8_t*)src_buf, src_size); + return true; +} diff --git a/core/fxcodec/codec/ccodec_progressivedecoder.h b/core/fxcodec/codec/ccodec_progressivedecoder.h index 614146f79d..e97d1b9f78 100644 --- a/core/fxcodec/codec/ccodec_progressivedecoder.h +++ b/core/fxcodec/codec/ccodec_progressivedecoder.h @@ -171,6 +171,7 @@ class CCodec_ProgressiveDecoder { FXCODEC_STATUS m_status; protected: +#ifdef PDF_ENABLE_XFA_PNG static bool PngReadHeaderFunc(void* pModule, int width, int height, @@ -182,6 +183,9 @@ class CCodec_ProgressiveDecoder { static void PngFillScanlineBufCompletedFunc(void* pModule, int pass, int line); +#endif // PDF_ENABLE_XFA_PNG + +#ifdef PDF_ENABLE_XFA_GIF static void GifRecordCurrentPositionCallback(void* pModule, uint32_t& cur_pos); static uint8_t* GifAskLocalPaletteBufCallback(void* pModule, @@ -200,10 +204,25 @@ class CCodec_ProgressiveDecoder { static void GifReadScanlineCallback(void* pModule, int32_t row_num, uint8_t* row_buf); + bool GifReadMoreData(CCodec_GifModule* pGifModule, + FXCODEC_STATUS& err_status); + void GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, + double scale_y, + int des_row); +#endif // PDF_ENABLE_XFA_GIF + +#ifdef PDF_ENABLE_XFA_BMP static bool BmpInputImagePositionBufCallback(void* pModule, uint32_t rcd_pos); static void BmpReadScanlineCallback(void* pModule, int32_t row_num, uint8_t* row_buf); + void PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, + int32_t des_line, + uint8_t* src_scan, + FXCodec_Format src_format); + bool BmpReadMoreData(CCodec_BmpModule* pBmpModule, + FXCODEC_STATUS& err_status); +#endif // PDF_ENABLE_XFA_BMP bool DetectImageType(FXCODEC_IMAGE_TYPE imageType, CFX_DIBAttribute* pAttribute); @@ -220,17 +239,6 @@ class CCodec_ProgressiveDecoder { void ResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); bool JpegReadMoreData(CCodec_JpegModule* pJpegModule, FXCODEC_STATUS& err_status); - void PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, - int32_t des_line, - uint8_t* src_scan, - FXCodec_Format src_format); - bool GifReadMoreData(CCodec_GifModule* pGifModule, - FXCODEC_STATUS& err_status); - void GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, - double scale_y, - int des_row); - bool BmpReadMoreData(CCodec_BmpModule* pBmpModule, - FXCODEC_STATUS& err_status); void ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); }; diff --git a/core/fxcodec/codec/ccodec_tiffmodule.cpp b/core/fxcodec/codec/ccodec_tiffmodule.cpp new file mode 100644 index 0000000000..736772892a --- /dev/null +++ b/core/fxcodec/codec/ccodec_tiffmodule.cpp @@ -0,0 +1,504 @@ +// 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_tiffmodule.h" + +#include + +#include "core/fxcodec/codec/codec_int.h" +#include "core/fxcodec/fx_codec.h" +#include "core/fxcrt/cfx_retain_ptr.h" +#include "core/fxcrt/fx_safe_types.h" +#include "core/fxge/fx_dib.h" +#include "third_party/base/ptr_util.h" + +extern "C" { +#include "third_party/libtiff/tiffiop.h" +} + +class CCodec_TiffContext { + public: + CCodec_TiffContext(); + ~CCodec_TiffContext(); + + bool InitDecoder(const CFX_RetainPtr& file_ptr); + bool LoadFrameInfo(int32_t frame, + int32_t* width, + int32_t* height, + int32_t* comps, + int32_t* bpc, + CFX_DIBAttribute* pAttribute); + bool Decode(CFX_DIBitmap* pDIBitmap); + + CFX_RetainPtr io_in() const { return m_io_in; } + uint32_t offset() const { return m_offset; } + void set_offset(uint32_t offset) { m_offset = offset; } + + private: + bool IsSupport(const CFX_DIBitmap* pDIBitmap) const; + void SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps); + bool Decode1bppRGB(CFX_DIBitmap* pDIBitmap, + int32_t height, + int32_t width, + uint16_t bps, + uint16_t spp); + bool Decode8bppRGB(CFX_DIBitmap* pDIBitmap, + int32_t height, + int32_t width, + uint16_t bps, + uint16_t spp); + bool Decode24bppRGB(CFX_DIBitmap* pDIBitmap, + int32_t height, + int32_t width, + uint16_t bps, + uint16_t spp); + + CFX_RetainPtr m_io_in; + uint32_t m_offset; + TIFF* m_tif_ctx; +}; + +void* _TIFFmalloc(tmsize_t size) { + return FXMEM_DefaultAlloc(size, 0); +} + +void _TIFFfree(void* ptr) { + FXMEM_DefaultFree(ptr, 0); +} + +void* _TIFFrealloc(void* ptr, tmsize_t size) { + return FXMEM_DefaultRealloc(ptr, size, 0); +} + +void _TIFFmemset(void* ptr, int val, tmsize_t size) { + FXSYS_memset(ptr, val, (size_t)size); +} + +void _TIFFmemcpy(void* des, const void* src, tmsize_t size) { + FXSYS_memcpy(des, src, (size_t)size); +} + +int _TIFFmemcmp(const void* ptr1, const void* ptr2, tmsize_t size) { + return FXSYS_memcmp(ptr1, ptr2, (size_t)size); +} + +int _TIFFIfMultiplicationOverflow(tmsize_t op1, tmsize_t op2) { + return op1 > std::numeric_limits::max() / op2; +} + +TIFFErrorHandler _TIFFwarningHandler = nullptr; +TIFFErrorHandler _TIFFerrorHandler = nullptr; + +namespace { + +tsize_t tiff_read(thandle_t context, tdata_t buf, tsize_t length) { + CCodec_TiffContext* pTiffContext = + reinterpret_cast(context); + FX_SAFE_UINT32 increment = pTiffContext->offset(); + increment += length; + if (!increment.IsValid()) + return 0; + + FX_FILESIZE offset = pTiffContext->offset(); + if (!pTiffContext->io_in()->ReadBlock(buf, offset, length)) + return 0; + + pTiffContext->set_offset(increment.ValueOrDie()); + if (offset + length > pTiffContext->io_in()->GetSize()) + return pTiffContext->io_in()->GetSize() - offset; + + return length; +} + +tsize_t tiff_write(thandle_t context, tdata_t buf, tsize_t length) { + ASSERT(false); + return 0; +} + +toff_t tiff_seek(thandle_t context, toff_t offset, int whence) { + CCodec_TiffContext* pTiffContext = + reinterpret_cast(context); + FX_SAFE_FILESIZE safe_offset = offset; + if (!safe_offset.IsValid()) + return static_cast(-1); + FX_FILESIZE file_offset = safe_offset.ValueOrDie(); + + switch (whence) { + case 0: { + if (file_offset > pTiffContext->io_in()->GetSize()) + return static_cast(-1); + pTiffContext->set_offset(file_offset); + return pTiffContext->offset(); + } + case 1: { + FX_SAFE_UINT32 new_increment = pTiffContext->offset(); + new_increment += file_offset; + if (!new_increment.IsValid()) + return static_cast(-1); + pTiffContext->set_offset(new_increment.ValueOrDie()); + return pTiffContext->offset(); + } + case 2: { + if (pTiffContext->io_in()->GetSize() < file_offset) + return static_cast(-1); + pTiffContext->set_offset(pTiffContext->io_in()->GetSize() - file_offset); + return pTiffContext->offset(); + } + default: + return static_cast(-1); + } +} + +int tiff_close(thandle_t context) { + return 0; +} + +toff_t tiff_get_size(thandle_t context) { + CCodec_TiffContext* pTiffContext = + reinterpret_cast(context); + return static_cast(pTiffContext->io_in()->GetSize()); +} + +int tiff_map(thandle_t context, tdata_t*, toff_t*) { + return 0; +} + +void tiff_unmap(thandle_t context, tdata_t, toff_t) {} + +TIFF* tiff_open(void* context, const char* mode) { + TIFF* tif = TIFFClientOpen("Tiff Image", mode, (thandle_t)context, tiff_read, + tiff_write, tiff_seek, tiff_close, tiff_get_size, + tiff_map, tiff_unmap); + if (tif) { + tif->tif_fd = (int)(intptr_t)context; + } + return tif; +} + +template +bool Tiff_Exif_GetInfo(TIFF* tif_ctx, ttag_t tag, CFX_DIBAttribute* pAttr) { + T val = 0; + TIFFGetField(tif_ctx, tag, &val); + if (!val) + return false; + T* ptr = FX_Alloc(T, 1); + *ptr = val; + pAttr->m_Exif[tag] = (void*)ptr; + return true; +} + +void Tiff_Exif_GetStringInfo(TIFF* tif_ctx, + ttag_t tag, + CFX_DIBAttribute* pAttr) { + FX_CHAR* buf = nullptr; + TIFFGetField(tif_ctx, tag, &buf); + if (!buf) + return; + FX_STRSIZE size = FXSYS_strlen(buf); + uint8_t* ptr = FX_Alloc(uint8_t, size + 1); + FXSYS_memcpy(ptr, buf, size); + ptr[size] = 0; + pAttr->m_Exif[tag] = ptr; +} + +void TiffBGRA2RGBA(uint8_t* pBuf, int32_t pixel, int32_t spp) { + for (int32_t n = 0; n < pixel; n++) { + uint8_t tmp = pBuf[0]; + pBuf[0] = pBuf[2]; + pBuf[2] = tmp; + pBuf += spp; + } +} + +} // namespace + +CCodec_TiffContext::CCodec_TiffContext() + : m_io_in(nullptr), m_offset(0), m_tif_ctx(nullptr) {} + +CCodec_TiffContext::~CCodec_TiffContext() { + if (m_tif_ctx) + TIFFClose(m_tif_ctx); +} + +bool CCodec_TiffContext::InitDecoder( + const CFX_RetainPtr& file_ptr) { + m_io_in = file_ptr; + m_tif_ctx = tiff_open(this, "r"); + return !!m_tif_ctx; +} + +bool CCodec_TiffContext::LoadFrameInfo(int32_t frame, + int32_t* width, + int32_t* height, + int32_t* comps, + int32_t* bpc, + CFX_DIBAttribute* pAttribute) { + if (!TIFFSetDirectory(m_tif_ctx, (uint16)frame)) + return false; + + uint32_t tif_width = 0; + uint32_t tif_height = 0; + uint16_t tif_comps = 0; + uint16_t tif_bpc = 0; + uint32_t tif_rps = 0; + TIFFGetField(m_tif_ctx, TIFFTAG_IMAGEWIDTH, &tif_width); + TIFFGetField(m_tif_ctx, TIFFTAG_IMAGELENGTH, &tif_height); + TIFFGetField(m_tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &tif_comps); + TIFFGetField(m_tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc); + TIFFGetField(m_tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps); + + if (pAttribute) { + pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH; + if (TIFFGetField(m_tif_ctx, TIFFTAG_RESOLUTIONUNIT, + &pAttribute->m_wDPIUnit)) { + pAttribute->m_wDPIUnit--; + } + Tiff_Exif_GetInfo(m_tif_ctx, TIFFTAG_ORIENTATION, pAttribute); + if (Tiff_Exif_GetInfo(m_tif_ctx, TIFFTAG_XRESOLUTION, + pAttribute)) { + void* val = pAttribute->m_Exif[TIFFTAG_XRESOLUTION]; + FX_FLOAT fDpi = val ? *reinterpret_cast(val) : 0; + pAttribute->m_nXDPI = (int32_t)(fDpi + 0.5f); + } + if (Tiff_Exif_GetInfo(m_tif_ctx, TIFFTAG_YRESOLUTION, + pAttribute)) { + void* val = pAttribute->m_Exif[TIFFTAG_YRESOLUTION]; + FX_FLOAT fDpi = val ? *reinterpret_cast(val) : 0; + pAttribute->m_nYDPI = (int32_t)(fDpi + 0.5f); + } + Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pAttribute); + Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_MAKE, pAttribute); + Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_MODEL, pAttribute); + } + pdfium::base::CheckedNumeric checked_width = tif_width; + pdfium::base::CheckedNumeric checked_height = tif_height; + if (!checked_width.IsValid() || !checked_height.IsValid()) + return false; + + *width = checked_width.ValueOrDie(); + *height = checked_height.ValueOrDie(); + *comps = tif_comps; + *bpc = tif_bpc; + if (tif_rps > tif_height) { + tif_rps = tif_height; + TIFFSetField(m_tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps); + } + return true; +} + +bool CCodec_TiffContext::IsSupport(const CFX_DIBitmap* pDIBitmap) const { + if (TIFFIsTiled(m_tif_ctx)) + return false; + + uint16_t photometric = 0; + if (!TIFFGetField(m_tif_ctx, TIFFTAG_PHOTOMETRIC, &photometric)) + return false; + + switch (pDIBitmap->GetBPP()) { + case 1: + case 8: + if (photometric != PHOTOMETRIC_PALETTE) { + return false; + } + break; + case 24: + if (photometric != PHOTOMETRIC_RGB) { + return false; + } + break; + default: + return false; + } + uint16_t planarconfig = 0; + if (!TIFFGetFieldDefaulted(m_tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig)) + return false; + + return planarconfig != PLANARCONFIG_SEPARATE; +} + +void CCodec_TiffContext::SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps) { + uint16_t* red_orig = nullptr; + uint16_t* green_orig = nullptr; + uint16_t* blue_orig = nullptr; + TIFFGetField(m_tif_ctx, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig); + for (int32_t i = (1L << bps) - 1; i >= 0; i--) { +#define CVT(x) ((uint16_t)((x) >> 8)) + red_orig[i] = CVT(red_orig[i]); + green_orig[i] = CVT(green_orig[i]); + blue_orig[i] = CVT(blue_orig[i]); +#undef CVT + } + int32_t len = 1 << bps; + for (int32_t index = 0; index < len; index++) { + uint32_t r = red_orig[index] & 0xFF; + uint32_t g = green_orig[index] & 0xFF; + uint32_t b = blue_orig[index] & 0xFF; + uint32_t color = (uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16) | + (((uint32)0xffL) << 24); + pDIBitmap->SetPaletteEntry(index, color); + } +} + +bool CCodec_TiffContext::Decode1bppRGB(CFX_DIBitmap* pDIBitmap, + int32_t height, + int32_t width, + uint16_t bps, + uint16_t spp) { + if (pDIBitmap->GetBPP() != 1 || spp != 1 || bps != 1 || + !IsSupport(pDIBitmap)) { + return false; + } + SetPalette(pDIBitmap, bps); + int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx); + uint8_t* buf = (uint8_t*)_TIFFmalloc(size); + if (!buf) { + TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer"); + return false; + } + uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); + uint32_t pitch = pDIBitmap->GetPitch(); + for (int32_t row = 0; row < height; row++) { + TIFFReadScanline(m_tif_ctx, buf, row, 0); + for (int32_t j = 0; j < size; j++) { + bitMapbuffer[row * pitch + j] = buf[j]; + } + } + _TIFFfree(buf); + return true; +} + +bool CCodec_TiffContext::Decode8bppRGB(CFX_DIBitmap* pDIBitmap, + int32_t height, + int32_t width, + uint16_t bps, + uint16_t spp) { + if (pDIBitmap->GetBPP() != 8 || spp != 1 || (bps != 4 && bps != 8) || + !IsSupport(pDIBitmap)) { + return false; + } + SetPalette(pDIBitmap, bps); + int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx); + uint8_t* buf = (uint8_t*)_TIFFmalloc(size); + if (!buf) { + TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer"); + return false; + } + uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); + uint32_t pitch = pDIBitmap->GetPitch(); + for (int32_t row = 0; row < height; row++) { + TIFFReadScanline(m_tif_ctx, buf, row, 0); + for (int32_t j = 0; j < size; j++) { + switch (bps) { + case 4: + bitMapbuffer[row * pitch + 2 * j + 0] = (buf[j] & 0xF0) >> 4; + bitMapbuffer[row * pitch + 2 * j + 1] = (buf[j] & 0x0F) >> 0; + break; + case 8: + bitMapbuffer[row * pitch + j] = buf[j]; + break; + } + } + } + _TIFFfree(buf); + return true; +} + +bool CCodec_TiffContext::Decode24bppRGB(CFX_DIBitmap* pDIBitmap, + int32_t height, + int32_t width, + uint16_t bps, + uint16_t spp) { + if (pDIBitmap->GetBPP() != 24 || !IsSupport(pDIBitmap)) + return false; + + int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx); + uint8_t* buf = (uint8_t*)_TIFFmalloc(size); + if (!buf) { + TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer"); + return false; + } + uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); + uint32_t pitch = pDIBitmap->GetPitch(); + for (int32_t row = 0; row < height; row++) { + TIFFReadScanline(m_tif_ctx, buf, row, 0); + for (int32_t j = 0; j < size - 2; j += 3) { + bitMapbuffer[row * pitch + j + 0] = buf[j + 2]; + bitMapbuffer[row * pitch + j + 1] = buf[j + 1]; + bitMapbuffer[row * pitch + j + 2] = buf[j + 0]; + } + } + _TIFFfree(buf); + return true; +} + +bool CCodec_TiffContext::Decode(CFX_DIBitmap* pDIBitmap) { + uint32_t img_wid = pDIBitmap->GetWidth(); + uint32_t img_hei = pDIBitmap->GetHeight(); + uint32_t width = 0; + uint32_t height = 0; + TIFFGetField(m_tif_ctx, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(m_tif_ctx, TIFFTAG_IMAGELENGTH, &height); + if (img_wid != width || img_hei != height) + return false; + + if (pDIBitmap->GetBPP() == 32) { + uint16_t rotation = ORIENTATION_TOPLEFT; + TIFFGetField(m_tif_ctx, TIFFTAG_ORIENTATION, &rotation); + if (TIFFReadRGBAImageOriented(m_tif_ctx, img_wid, img_hei, + (uint32*)pDIBitmap->GetBuffer(), rotation, + 1)) { + for (uint32_t row = 0; row < img_hei; row++) { + uint8_t* row_buf = (uint8_t*)pDIBitmap->GetScanline(row); + TiffBGRA2RGBA(row_buf, img_wid, 4); + } + return true; + } + } + uint16_t spp = 0; + uint16_t bps = 0; + TIFFGetField(m_tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp); + TIFFGetField(m_tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps); + FX_SAFE_UINT32 safe_bpp = bps; + safe_bpp *= spp; + if (!safe_bpp.IsValid()) + return false; + uint32_t bpp = safe_bpp.ValueOrDie(); + if (bpp == 1) + return Decode1bppRGB(pDIBitmap, height, width, bps, spp); + if (bpp <= 8) + return Decode8bppRGB(pDIBitmap, height, width, bps, spp); + if (bpp <= 24) + return Decode24bppRGB(pDIBitmap, height, width, bps, spp); + return false; +} + +CCodec_TiffContext* CCodec_TiffModule::CreateDecoder( + const CFX_RetainPtr& file_ptr) { + auto pDecoder = pdfium::MakeUnique(); + if (!pDecoder->InitDecoder(file_ptr)) + return nullptr; + + return pDecoder.release(); +} + +bool CCodec_TiffModule::LoadFrameInfo(CCodec_TiffContext* ctx, + int32_t frame, + int32_t* width, + int32_t* height, + int32_t* comps, + int32_t* bpc, + CFX_DIBAttribute* pAttribute) { + return ctx->LoadFrameInfo(frame, width, height, comps, bpc, pAttribute); +} + +bool CCodec_TiffModule::Decode(CCodec_TiffContext* ctx, + class CFX_DIBitmap* pDIBitmap) { + return ctx->Decode(pDIBitmap); +} + +void CCodec_TiffModule::DestroyDecoder(CCodec_TiffContext* ctx) { + delete ctx; +} diff --git a/core/fxcodec/codec/fx_codec.cpp b/core/fxcodec/codec/fx_codec.cpp index 3edf8924c3..d9a36a6c5a 100644 --- a/core/fxcodec/codec/fx_codec.cpp +++ b/core/fxcodec/codec/fx_codec.cpp @@ -24,12 +24,18 @@ CCodec_ModuleMgr::CCodec_ModuleMgr() m_pJpxModule(new CCodec_JpxModule), m_pJbig2Module(new CCodec_Jbig2Module), m_pIccModule(new CCodec_IccModule), -#ifdef PDF_ENABLE_XFA - m_pPngModule(new CCodec_PngModule), - m_pGifModule(new CCodec_GifModule), +#ifdef PDF_ENABLE_XFA_BMP m_pBmpModule(new CCodec_BmpModule), +#endif // PDF_ENABLE_XFA_BMP +#ifdef PDF_ENABLE_XFA_GIF + m_pGifModule(new CCodec_GifModule), +#endif // PDF_ENABLE_XFA_GIF +#ifdef PDF_ENABLE_XFA_PNG + m_pPngModule(new CCodec_PngModule), +#endif // PDF_ENABLE_XFA_PNG +#ifdef PDF_ENABLE_XFA_TIFF m_pTiffModule(new CCodec_TiffModule), -#endif // PDF_ENABLE_XFA +#endif // PDF_ENABLE_XFA_TIFF m_pFlateModule(new CCodec_FlateModule) { } diff --git a/core/fxcodec/codec/fx_codec_bmp.cpp b/core/fxcodec/codec/fx_codec_bmp.cpp deleted file mode 100644 index ae83d3f1ef..0000000000 --- a/core/fxcodec/codec/fx_codec_bmp.cpp +++ /dev/null @@ -1,124 +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/codec/codec_int.h" -#include "core/fxcodec/fx_codec.h" -#include "core/fxcodec/lbmp/fx_bmp.h" -#include "core/fxge/fx_dib.h" -struct FXBMP_Context { - bmp_decompress_struct_p bmp_ptr; - void* parent_ptr; - void* child_ptr; - - void* (*m_AllocFunc)(unsigned int); - void (*m_FreeFunc)(void*); -}; -extern "C" { -static void* bmp_alloc_func(unsigned int size) { - return FX_Alloc(char, size); -} -static void bmp_free_func(void* p) { - FX_Free(p); -} -}; -static void bmp_error_data(bmp_decompress_struct_p bmp_ptr, - const FX_CHAR* err_msg) { - FXSYS_strncpy((char*)bmp_ptr->err_ptr, err_msg, BMP_MAX_ERROR_SIZE - 1); - longjmp(bmp_ptr->jmpbuf, 1); -} -static void bmp_read_scanline(bmp_decompress_struct_p bmp_ptr, - int32_t row_num, - uint8_t* row_buf) { - FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr; - CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr; - pModule->ReadScanlineCallback(p->child_ptr, row_num, row_buf); -} -static bool bmp_get_data_position(bmp_decompress_struct_p bmp_ptr, - uint32_t rcd_pos) { - FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr; - CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr; - return pModule->InputImagePositionBufCallback(p->child_ptr, rcd_pos); -} - -FXBMP_Context* CCodec_BmpModule::Start(void* pModule) { - FXBMP_Context* p = FX_Alloc(FXBMP_Context, 1); - if (!p) - return nullptr; - - FXSYS_memset(p, 0, sizeof(FXBMP_Context)); - if (!p) - return nullptr; - - p->m_AllocFunc = bmp_alloc_func; - p->m_FreeFunc = bmp_free_func; - p->bmp_ptr = nullptr; - p->parent_ptr = (void*)this; - p->child_ptr = pModule; - p->bmp_ptr = bmp_create_decompress(); - if (!p->bmp_ptr) { - FX_Free(p); - return nullptr; - } - p->bmp_ptr->context_ptr = (void*)p; - p->bmp_ptr->err_ptr = m_szLastError; - p->bmp_ptr->bmp_error_fn = bmp_error_data; - p->bmp_ptr->bmp_get_row_fn = bmp_read_scanline; - p->bmp_ptr->bmp_get_data_position_fn = bmp_get_data_position; - return p; -} - -void CCodec_BmpModule::Finish(FXBMP_Context* ctx) { - if (ctx) { - bmp_destroy_decompress(&ctx->bmp_ptr); - ctx->m_FreeFunc(ctx); - } -} -int32_t CCodec_BmpModule::ReadHeader(FXBMP_Context* ctx, - int32_t* width, - int32_t* height, - bool* tb_flag, - int32_t* components, - int32_t* pal_num, - uint32_t** pal_pp, - CFX_DIBAttribute* pAttribute) { - if (setjmp(ctx->bmp_ptr->jmpbuf)) { - return 0; - } - int32_t ret = bmp_read_header(ctx->bmp_ptr); - if (ret != 1) { - return ret; - } - *width = ctx->bmp_ptr->width; - *height = ctx->bmp_ptr->height; - *tb_flag = ctx->bmp_ptr->imgTB_flag; - *components = ctx->bmp_ptr->components; - *pal_num = ctx->bmp_ptr->pal_num; - *pal_pp = ctx->bmp_ptr->pal_ptr; - if (pAttribute) { - pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER; - pAttribute->m_nXDPI = ctx->bmp_ptr->dpi_x; - pAttribute->m_nYDPI = ctx->bmp_ptr->dpi_y; - pAttribute->m_nBmpCompressType = ctx->bmp_ptr->compress_flag; - } - return 1; -} - -int32_t CCodec_BmpModule::LoadImage(FXBMP_Context* ctx) { - if (setjmp(ctx->bmp_ptr->jmpbuf)) - return 0; - return bmp_decode_image(ctx->bmp_ptr); -} - -uint32_t CCodec_BmpModule::GetAvailInput(FXBMP_Context* ctx, - uint8_t** avail_buf_ptr) { - return bmp_get_avail_input(ctx->bmp_ptr, avail_buf_ptr); -} - -void CCodec_BmpModule::Input(FXBMP_Context* ctx, - const uint8_t* src_buf, - uint32_t src_size) { - bmp_input_buffer(ctx->bmp_ptr, (uint8_t*)src_buf, src_size); -} diff --git a/core/fxcodec/codec/fx_codec_gif.cpp b/core/fxcodec/codec/fx_codec_gif.cpp deleted file mode 100644 index fadf18f251..0000000000 --- a/core/fxcodec/codec/fx_codec_gif.cpp +++ /dev/null @@ -1,186 +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/codec/codec_int.h" -#include "core/fxcodec/fx_codec.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* child_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 FX_CHAR* err_msg) { - FXSYS_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->AskLocalPaletteBufCallback( - p->child_ptr, 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->RecordCurrentPositionCallback(p->child_ptr, *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->ReadScanlineCallback(p->child_ptr, 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->InputRecordPositionBufCallback( - p->child_ptr, cur_pos, FX_RECT(left, top, left + width, top + height), - pal_num, pal_ptr, delay_time, user_input, trans_index, disposal_method, - interlace); -} - -FXGIF_Context* CCodec_GifModule::Start(void* pModule) { - FXGIF_Context* p = FX_Alloc(FXGIF_Context, 1); - if (!p) - return nullptr; - - FXSYS_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 = (void*)this; - p->child_ptr = pModule; - p->gif_ptr = gif_create_decompress(); - if (!p->gif_ptr) { - FX_Free(p); - return nullptr; - } - p->gif_ptr->context_ptr = (void*)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; - return p; -} - -void CCodec_GifModule::Finish(FXGIF_Context* ctx) { - if (ctx) { - gif_destroy_decompress(&ctx->gif_ptr); - ctx->m_FreeFunc(ctx); - } -} - -int32_t 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->gif_ptr->jmpbuf)) - return 0; - - int32_t ret = gif_read_header(ctx->gif_ptr); - if (ret != 1) - 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; - return 1; -} - -int32_t CCodec_GifModule::LoadFrameInfo(FXGIF_Context* ctx, int* frame_num) { - if (setjmp(ctx->gif_ptr->jmpbuf)) - return 0; - - int32_t ret = gif_get_frame(ctx->gif_ptr); - if (ret != 1) - return ret; - - *frame_num = gif_get_frame_num(ctx->gif_ptr); - return 1; -} - -int32_t CCodec_GifModule::LoadFrame(FXGIF_Context* ctx, - int frame_num, - CFX_DIBAttribute* pAttribute) { - if (setjmp(ctx->gif_ptr->jmpbuf)) - return 0; - - int32_t ret = gif_load_frame(ctx->gif_ptr, frame_num); - if (ret == 1) { - if (pAttribute) { - pAttribute->m_nGifLeft = - (*ctx->gif_ptr->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) { - 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(); - if (len > 21) { - uint8_t size = *buf++; - if (size) { - pAttribute->m_strAuthor = CFX_ByteString(buf, size); - } else { - pAttribute->m_strAuthor.clear(); - } - buf += size; - size = *buf++; - if (size == 20) { - FXSYS_memcpy(pAttribute->m_strTime, buf, size); - } - } - } - } - } - return ret; -} - -uint32_t CCodec_GifModule::GetAvailInput(FXGIF_Context* ctx, - uint8_t** avail_buf_ptr) { - return gif_get_avail_input(ctx->gif_ptr, 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); -} diff --git a/core/fxcodec/codec/fx_codec_png.cpp b/core/fxcodec/codec/fx_codec_png.cpp deleted file mode 100644 index 579c85bf09..0000000000 --- a/core/fxcodec/codec/fx_codec_png.cpp +++ /dev/null @@ -1,256 +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 - -#include "core/fxcodec/codec/codec_int.h" -#include "core/fxcodec/fx_codec.h" -#include "core/fxge/fx_dib.h" - -extern "C" { -#undef FAR -#include "third_party/libpng16/png.h" -} - -static void _png_error_data(png_structp png_ptr, png_const_charp error_msg) { - if (png_get_error_ptr(png_ptr)) { - FXSYS_strncpy((char*)png_get_error_ptr(png_ptr), error_msg, - PNG_ERROR_SIZE - 1); - } - longjmp(png_jmpbuf(png_ptr), 1); -} -static void _png_warning_data(png_structp png_ptr, png_const_charp error_msg) {} -static void _png_load_bmp_attribute(png_structp png_ptr, - png_infop info_ptr, - CFX_DIBAttribute* pAttribute) { - if (pAttribute) { -#if defined(PNG_pHYs_SUPPORTED) - pAttribute->m_nXDPI = png_get_x_pixels_per_meter(png_ptr, info_ptr); - pAttribute->m_nYDPI = png_get_y_pixels_per_meter(png_ptr, info_ptr); - png_uint_32 res_x, res_y; - int unit_type; - png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type); - switch (unit_type) { - case PNG_RESOLUTION_METER: - pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER; - break; - default: - pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_NONE; - } -#endif -#if defined(PNG_iCCP_SUPPORTED) - png_charp icc_name; - png_bytep icc_profile; - png_uint_32 icc_proflen; - int compress_type; - png_get_iCCP(png_ptr, info_ptr, &icc_name, &compress_type, &icc_profile, - &icc_proflen); -#endif - int bTime = 0; -#if defined(PNG_tIME_SUPPORTED) - png_timep t = nullptr; - png_get_tIME(png_ptr, info_ptr, &t); - if (t) { - FXSYS_memset(pAttribute->m_strTime, 0, sizeof(pAttribute->m_strTime)); - FXSYS_snprintf((FX_CHAR*)pAttribute->m_strTime, - sizeof(pAttribute->m_strTime), "%4u:%2u:%2u %2u:%2u:%2u", - t->year, t->month, t->day, t->hour, t->minute, t->second); - pAttribute->m_strTime[sizeof(pAttribute->m_strTime) - 1] = 0; - bTime = 1; - } -#endif -#if defined(PNG_TEXT_SUPPORTED) - int i; - FX_STRSIZE len; - const FX_CHAR* buf; - int num_text; - png_textp text = nullptr; - png_get_text(png_ptr, info_ptr, &text, &num_text); - for (i = 0; i < num_text; i++) { - len = FXSYS_strlen(text[i].key); - buf = "Time"; - if (!FXSYS_memcmp(buf, text[i].key, std::min(len, FXSYS_strlen(buf)))) { - if (!bTime) { - FXSYS_memset(pAttribute->m_strTime, 0, sizeof(pAttribute->m_strTime)); - FXSYS_memcpy( - pAttribute->m_strTime, text[i].text, - std::min(sizeof(pAttribute->m_strTime) - 1, text[i].text_length)); - } - } else { - buf = "Author"; - if (!FXSYS_memcmp(buf, text[i].key, std::min(len, FXSYS_strlen(buf)))) { - pAttribute->m_strAuthor = - CFX_ByteString(reinterpret_cast(text[i].text), - static_cast(text[i].text_length)); - } - } - } -#endif - } -} -struct FXPNG_Context { - png_structp png_ptr; - png_infop info_ptr; - void* parent_ptr; - void* child_ptr; - - void* (*m_AllocFunc)(unsigned int); - void (*m_FreeFunc)(void*); -}; -extern "C" { -static void* _png_alloc_func(unsigned int size) { - return FX_Alloc(char, size); -} -static void _png_free_func(void* p) { - FX_Free(p); -} -}; -static void _png_get_header_func(png_structp png_ptr, png_infop info_ptr) { - FXPNG_Context* p = (FXPNG_Context*)png_get_progressive_ptr(png_ptr); - if (!p) - return; - - CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; - if (!pModule) - return; - - png_uint_32 width = 0, height = 0; - int bpc = 0, color_type = 0, color_type1 = 0, pass = 0; - double gamma = 1.0; - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bpc, &color_type, nullptr, - nullptr, nullptr); - color_type1 = color_type; - if (bpc > 8) { - png_set_strip_16(png_ptr); - } else if (bpc < 8) { - png_set_expand_gray_1_2_4_to_8(png_ptr); - } - bpc = 8; - if (color_type == PNG_COLOR_TYPE_PALETTE) { - png_set_palette_to_rgb(png_ptr); - } - pass = png_set_interlace_handling(png_ptr); - if (!pModule->ReadHeaderCallback(p->child_ptr, width, height, bpc, pass, - &color_type, &gamma)) { - png_error(p->png_ptr, "Read Header Callback Error"); - } - int intent; - if (png_get_sRGB(png_ptr, info_ptr, &intent)) { - png_set_gamma(png_ptr, gamma, 0.45455); - } else { - double image_gamma; - if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) { - png_set_gamma(png_ptr, gamma, image_gamma); - } else { - png_set_gamma(png_ptr, gamma, 0.45455); - } - } - switch (color_type) { - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_GRAY_ALPHA: { - if (color_type1 & PNG_COLOR_MASK_COLOR) { - png_set_rgb_to_gray(png_ptr, 1, 0.299, 0.587); - } - } break; - case PNG_COLOR_TYPE_PALETTE: - if (color_type1 != PNG_COLOR_TYPE_PALETTE) { - png_error(p->png_ptr, "Not Support Output Palette Now"); - } - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - if (!(color_type1 & PNG_COLOR_MASK_COLOR)) { - png_set_gray_to_rgb(png_ptr); - } - png_set_bgr(png_ptr); - break; - } - if (!(color_type & PNG_COLOR_MASK_ALPHA)) { - png_set_strip_alpha(png_ptr); - } - if (color_type & PNG_COLOR_MASK_ALPHA && - !(color_type1 & PNG_COLOR_MASK_ALPHA)) { - png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); - } - png_read_update_info(png_ptr, info_ptr); -} -static void _png_get_end_func(png_structp png_ptr, png_infop info_ptr) {} -static void _png_get_row_func(png_structp png_ptr, - png_bytep new_row, - png_uint_32 row_num, - int pass) { - FXPNG_Context* p = (FXPNG_Context*)png_get_progressive_ptr(png_ptr); - if (!p) - return; - - CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; - uint8_t* src_buf = nullptr; - if (!pModule->AskScanlineBufCallback(p->child_ptr, row_num, src_buf)) { - png_error(png_ptr, "Ask Scanline buffer Callback Error"); - } - if (src_buf) { - png_progressive_combine_row(png_ptr, src_buf, new_row); - } - pModule->FillScanlineBufCompletedCallback(p->child_ptr, pass, row_num); -} - -FXPNG_Context* CCodec_PngModule::Start(void* pModule) { - FXPNG_Context* p = FX_Alloc(FXPNG_Context, 1); - if (!p) - return nullptr; - - p->m_AllocFunc = _png_alloc_func; - p->m_FreeFunc = _png_free_func; - p->png_ptr = nullptr; - p->info_ptr = nullptr; - p->parent_ptr = (void*)this; - p->child_ptr = pModule; - p->png_ptr = - png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!p->png_ptr) { - FX_Free(p); - return nullptr; - } - p->info_ptr = png_create_info_struct(p->png_ptr); - if (!p->info_ptr) { - png_destroy_read_struct(&(p->png_ptr), nullptr, nullptr); - FX_Free(p); - return nullptr; - } - if (setjmp(png_jmpbuf(p->png_ptr))) { - if (p) { - png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), nullptr); - FX_Free(p); - } - return nullptr; - } - png_set_progressive_read_fn(p->png_ptr, p, _png_get_header_func, - _png_get_row_func, _png_get_end_func); - png_set_error_fn(p->png_ptr, m_szLastError, (png_error_ptr)_png_error_data, - (png_error_ptr)_png_warning_data); - return p; -} - -void CCodec_PngModule::Finish(FXPNG_Context* ctx) { - if (ctx) { - png_destroy_read_struct(&(ctx->png_ptr), &(ctx->info_ptr), nullptr); - ctx->m_FreeFunc(ctx); - } -} - -bool CCodec_PngModule::Input(FXPNG_Context* ctx, - const uint8_t* src_buf, - uint32_t src_size, - CFX_DIBAttribute* pAttribute) { - if (setjmp(png_jmpbuf(ctx->png_ptr))) { - if (pAttribute && - 0 == FXSYS_strcmp(m_szLastError, "Read Header Callback Error")) { - _png_load_bmp_attribute(ctx->png_ptr, ctx->info_ptr, pAttribute); - } - return false; - } - png_process_data(ctx->png_ptr, ctx->info_ptr, (uint8_t*)src_buf, src_size); - return true; -} diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp index 4a1719f0f7..e4996c887a 100644 --- a/core/fxcodec/codec/fx_codec_progress.cpp +++ b/core/fxcodec/codec/fx_codec_progress.cpp @@ -17,11 +17,13 @@ namespace { +#ifdef PDF_ENABLE_XFA_PNG #if _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_ const double kPngGamma = 1.7; -#else +#else // _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_ const double kPngGamma = 2.2; -#endif +#endif // _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_ +#endif // PDF_ENABLE_XFA_PNG void RGB2BGR(uint8_t* buffer, int width = 1) { if (buffer && width > 0) { @@ -299,14 +301,22 @@ CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() { m_pFile = nullptr; if (m_pJpegContext) m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext); - if (m_pPngContext) - m_pCodecMgr->GetPngModule()->Finish(m_pPngContext); - if (m_pGifContext) - m_pCodecMgr->GetGifModule()->Finish(m_pGifContext); +#ifdef PDF_ENABLE_XFA_BMP if (m_pBmpContext) m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext); +#endif // PDF_ENABLE_XFA_BMP +#ifdef PDF_ENABLE_XFA_GIF + if (m_pGifContext) + m_pCodecMgr->GetGifModule()->Finish(m_pGifContext); +#endif // PDF_ENABLE_XFA_GIF +#ifdef PDF_ENABLE_XFA_PNG + if (m_pPngContext) + m_pCodecMgr->GetPngModule()->Finish(m_pPngContext); +#endif // PDF_ENABLE_XFA_PNG +#ifdef PDF_ENABLE_XFA_TIFF if (m_pTiffContext) m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext); +#endif // PDF_ENABLE_XFA_TIFF FX_Free(m_pSrcBuf); FX_Free(m_pDecodeBuf); FX_Free(m_pSrcPalette); @@ -349,6 +359,7 @@ bool CCodec_ProgressiveDecoder::JpegReadMoreData(CCodec_JpegModule* pJpegModule, return true; } +#ifdef PDF_ENABLE_XFA_PNG bool CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, int width, int height, @@ -584,7 +595,9 @@ void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, } } } +#endif // PDF_ENABLE_XFA_PNG +#ifdef PDF_ENABLE_XFA_GIF bool CCodec_ProgressiveDecoder::GifReadMoreData(CCodec_GifModule* pGifModule, FXCODEC_STATUS& err_status) { uint32_t dwSize = (uint32_t)m_pFile->GetSize(); @@ -874,7 +887,9 @@ void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert( GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y); } } +#endif // PDF_ENABLE_XFA_GIF +#ifdef PDF_ENABLE_XFA_BMP bool CCodec_ProgressiveDecoder::BmpReadMoreData(CCodec_BmpModule* pBmpModule, FXCODEC_STATUS& err_status) { uint32_t dwSize = (uint32_t)m_pFile->GetSize(); @@ -954,6 +969,7 @@ void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, } pCodec->ResampleVertBT(pDIBitmap, scale_y, des_row); } +#endif // PDF_ENABLE_XFA_BMP void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, double scale_y, @@ -1051,6 +1067,7 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, FXSYS_memset(m_pSrcBuf, 0, size); m_SrcSize = size; switch (imageType) { +#ifdef PDF_ENABLE_XFA_BMP case FXCODEC_IMAGE_BMP: { CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); if (!pBmpModule) { @@ -1106,6 +1123,7 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, m_status = FXCODEC_STATUS_ERR_FORMAT; return false; } +#endif // PDF_ENABLE_XFA_BMP case FXCODEC_IMAGE_JPG: { CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); if (!pJpegModule) { @@ -1149,6 +1167,7 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, m_status = FXCODEC_STATUS_ERR_FORMAT; return false; } +#ifdef PDF_ENABLE_XFA_PNG case FXCODEC_IMAGE_PNG: { CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); if (!pPngModule) { @@ -1211,6 +1230,8 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, } return true; } +#endif // PDF_ENABLE_XFA_PNG +#ifdef PDF_ENABLE_XFA_GIF case FXCODEC_IMAGE_GIF: { CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); if (!pGifModule) { @@ -1263,6 +1284,8 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, m_status = FXCODEC_STATUS_ERR_FORMAT; return false; } +#endif // PDF_XFA_ENABLE_GIF +#ifdef PDF_ENABLE_XFA_TIFF case FXCODEC_IMAGE_TIF: { CCodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); if (!pTiffModule) { @@ -1288,6 +1311,7 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, } return true; } +#endif // PDF_ENABLE_XFA_TIFF default: m_status = FXCODEC_STATUS_ERR_FORMAT; return false; @@ -1832,13 +1856,20 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames, return FXCODEC_STATUS_ERROR; } switch (m_imagType) { - case FXCODEC_IMAGE_BMP: case FXCODEC_IMAGE_JPG: +#ifdef PDF_ENABLE_XFA_BMP + case FXCODEC_IMAGE_BMP: +#endif +#ifdef PDF_ENABLE_XFA_PNG case FXCODEC_IMAGE_PNG: +#endif +#ifdef PDF_ENABLE_XFA_TIFF case FXCODEC_IMAGE_TIF: +#endif frames = m_FrameNumber = 1; m_status = FXCODEC_STATUS_DECODE_READY; return m_status; +#ifdef PDF_ENABLE_XFA_GIF case FXCODEC_IMAGE_GIF: { CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); while (true) { @@ -1868,6 +1899,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames, return m_status; } } +#endif // PDF_ENABLE_XFA_GIF default: return FXCODEC_STATUS_ERROR; } @@ -1968,6 +2000,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; return m_status; } +#ifdef PDF_ENABLE_XFA_PNG case FXCODEC_IMAGE_PNG: { CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); if (!pPngModule) { @@ -2020,6 +2053,8 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; return m_status; } +#endif // PDF_ENABLE_XFA_PNG +#ifdef PDF_ENABLE_XFA_GIF case FXCODEC_IMAGE_GIF: { CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); if (!pGifModule) { @@ -2041,6 +2076,8 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; return m_status; } +#endif // PDF_ENABLE_XFA_GIF +#ifdef PDF_ENABLE_XFA_BMP case FXCODEC_IMAGE_BMP: { CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); if (!pBmpModule) { @@ -2071,9 +2108,12 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; return m_status; } +#endif // PDF_ENABLE_XFA_BMP +#ifdef PDF_ENABLE_XFA_TIFF case FXCODEC_IMAGE_TIF: m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; return m_status; +#endif // PDF_ENABLE_XFA_TIFF default: return FXCODEC_STATUS_ERROR; } @@ -2116,6 +2156,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { } } } +#ifdef PDF_ENABLE_XFA_PNG case FXCODEC_IMAGE_PNG: { CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); while (true) { @@ -2160,6 +2201,8 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { } } } +#endif // PDF_ENABLE_XFA_PNG +#ifdef PDF_ENABLE_XFA_GIF case FXCODEC_IMAGE_GIF: { CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); while (true) { @@ -2191,6 +2234,8 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { return m_status; } } +#endif // PDF_ENABLE_XFA_GIF +#ifdef PDF_ENABLE_XFA_BMP case FXCODEC_IMAGE_BMP: { CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); while (true) { @@ -2221,6 +2266,8 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { return m_status; } }; +#endif // PDF_ENABLE_XFA_BMP +#ifdef PDF_ENABLE_XFA_TIFF case FXCODEC_IMAGE_TIF: { CCodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); bool ret = false; @@ -2364,6 +2411,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { m_status = FXCODEC_STATUS_DECODE_FINISH; return m_status; } +#endif // PDF_ENABLE_XFA_TIFF default: return FXCODEC_STATUS_ERROR; } diff --git a/core/fxcodec/codec/fx_codec_tiff.cpp b/core/fxcodec/codec/fx_codec_tiff.cpp deleted file mode 100644 index 7818a34ec6..0000000000 --- a/core/fxcodec/codec/fx_codec_tiff.cpp +++ /dev/null @@ -1,502 +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 - -#include "core/fxcodec/codec/codec_int.h" -#include "core/fxcodec/fx_codec.h" -#include "core/fxcrt/cfx_retain_ptr.h" -#include "core/fxcrt/fx_safe_types.h" -#include "core/fxge/fx_dib.h" -#include "third_party/base/ptr_util.h" - -extern "C" { -#include "third_party/libtiff/tiffiop.h" -} - -class CCodec_TiffContext { - public: - CCodec_TiffContext(); - ~CCodec_TiffContext(); - - bool InitDecoder(const CFX_RetainPtr& file_ptr); - bool LoadFrameInfo(int32_t frame, - int32_t* width, - int32_t* height, - int32_t* comps, - int32_t* bpc, - CFX_DIBAttribute* pAttribute); - bool Decode(CFX_DIBitmap* pDIBitmap); - - CFX_RetainPtr io_in() const { return m_io_in; } - uint32_t offset() const { return m_offset; } - void set_offset(uint32_t offset) { m_offset = offset; } - - private: - bool IsSupport(const CFX_DIBitmap* pDIBitmap) const; - void SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps); - bool Decode1bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp); - bool Decode8bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp); - bool Decode24bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp); - - CFX_RetainPtr m_io_in; - uint32_t m_offset; - TIFF* m_tif_ctx; -}; - -void* _TIFFmalloc(tmsize_t size) { - return FXMEM_DefaultAlloc(size, 0); -} - -void _TIFFfree(void* ptr) { - FXMEM_DefaultFree(ptr, 0); -} - -void* _TIFFrealloc(void* ptr, tmsize_t size) { - return FXMEM_DefaultRealloc(ptr, size, 0); -} - -void _TIFFmemset(void* ptr, int val, tmsize_t size) { - FXSYS_memset(ptr, val, (size_t)size); -} - -void _TIFFmemcpy(void* des, const void* src, tmsize_t size) { - FXSYS_memcpy(des, src, (size_t)size); -} - -int _TIFFmemcmp(const void* ptr1, const void* ptr2, tmsize_t size) { - return FXSYS_memcmp(ptr1, ptr2, (size_t)size); -} - -int _TIFFIfMultiplicationOverflow(tmsize_t op1, tmsize_t op2) { - return op1 > std::numeric_limits::max() / op2; -} - -TIFFErrorHandler _TIFFwarningHandler = nullptr; -TIFFErrorHandler _TIFFerrorHandler = nullptr; - -namespace { - -tsize_t tiff_read(thandle_t context, tdata_t buf, tsize_t length) { - CCodec_TiffContext* pTiffContext = - reinterpret_cast(context); - FX_SAFE_UINT32 increment = pTiffContext->offset(); - increment += length; - if (!increment.IsValid()) - return 0; - - FX_FILESIZE offset = pTiffContext->offset(); - if (!pTiffContext->io_in()->ReadBlock(buf, offset, length)) - return 0; - - pTiffContext->set_offset(increment.ValueOrDie()); - if (offset + length > pTiffContext->io_in()->GetSize()) - return pTiffContext->io_in()->GetSize() - offset; - - return length; -} - -tsize_t tiff_write(thandle_t context, tdata_t buf, tsize_t length) { - ASSERT(false); - return 0; -} - -toff_t tiff_seek(thandle_t context, toff_t offset, int whence) { - CCodec_TiffContext* pTiffContext = - reinterpret_cast(context); - FX_SAFE_FILESIZE safe_offset = offset; - if (!safe_offset.IsValid()) - return static_cast(-1); - FX_FILESIZE file_offset = safe_offset.ValueOrDie(); - - switch (whence) { - case 0: { - if (file_offset > pTiffContext->io_in()->GetSize()) - return static_cast(-1); - pTiffContext->set_offset(file_offset); - return pTiffContext->offset(); - } - case 1: { - FX_SAFE_UINT32 new_increment = pTiffContext->offset(); - new_increment += file_offset; - if (!new_increment.IsValid()) - return static_cast(-1); - pTiffContext->set_offset(new_increment.ValueOrDie()); - return pTiffContext->offset(); - } - case 2: { - if (pTiffContext->io_in()->GetSize() < file_offset) - return static_cast(-1); - pTiffContext->set_offset(pTiffContext->io_in()->GetSize() - file_offset); - return pTiffContext->offset(); - } - default: - return static_cast(-1); - } -} - -int tiff_close(thandle_t context) { - return 0; -} - -toff_t tiff_get_size(thandle_t context) { - CCodec_TiffContext* pTiffContext = - reinterpret_cast(context); - return static_cast(pTiffContext->io_in()->GetSize()); -} - -int tiff_map(thandle_t context, tdata_t*, toff_t*) { - return 0; -} - -void tiff_unmap(thandle_t context, tdata_t, toff_t) {} - -TIFF* tiff_open(void* context, const char* mode) { - TIFF* tif = TIFFClientOpen("Tiff Image", mode, (thandle_t)context, tiff_read, - tiff_write, tiff_seek, tiff_close, tiff_get_size, - tiff_map, tiff_unmap); - if (tif) { - tif->tif_fd = (int)(intptr_t)context; - } - return tif; -} - -template -bool Tiff_Exif_GetInfo(TIFF* tif_ctx, ttag_t tag, CFX_DIBAttribute* pAttr) { - T val = 0; - TIFFGetField(tif_ctx, tag, &val); - if (!val) - return false; - T* ptr = FX_Alloc(T, 1); - *ptr = val; - pAttr->m_Exif[tag] = (void*)ptr; - return true; -} - -void Tiff_Exif_GetStringInfo(TIFF* tif_ctx, - ttag_t tag, - CFX_DIBAttribute* pAttr) { - FX_CHAR* buf = nullptr; - TIFFGetField(tif_ctx, tag, &buf); - if (!buf) - return; - FX_STRSIZE size = FXSYS_strlen(buf); - uint8_t* ptr = FX_Alloc(uint8_t, size + 1); - FXSYS_memcpy(ptr, buf, size); - ptr[size] = 0; - pAttr->m_Exif[tag] = ptr; -} - -void TiffBGRA2RGBA(uint8_t* pBuf, int32_t pixel, int32_t spp) { - for (int32_t n = 0; n < pixel; n++) { - uint8_t tmp = pBuf[0]; - pBuf[0] = pBuf[2]; - pBuf[2] = tmp; - pBuf += spp; - } -} - -} // namespace - -CCodec_TiffContext::CCodec_TiffContext() - : m_io_in(nullptr), m_offset(0), m_tif_ctx(nullptr) {} - -CCodec_TiffContext::~CCodec_TiffContext() { - if (m_tif_ctx) - TIFFClose(m_tif_ctx); -} - -bool CCodec_TiffContext::InitDecoder( - const CFX_RetainPtr& file_ptr) { - m_io_in = file_ptr; - m_tif_ctx = tiff_open(this, "r"); - return !!m_tif_ctx; -} - -bool CCodec_TiffContext::LoadFrameInfo(int32_t frame, - int32_t* width, - int32_t* height, - int32_t* comps, - int32_t* bpc, - CFX_DIBAttribute* pAttribute) { - if (!TIFFSetDirectory(m_tif_ctx, (uint16)frame)) - return false; - - uint32_t tif_width = 0; - uint32_t tif_height = 0; - uint16_t tif_comps = 0; - uint16_t tif_bpc = 0; - uint32_t tif_rps = 0; - TIFFGetField(m_tif_ctx, TIFFTAG_IMAGEWIDTH, &tif_width); - TIFFGetField(m_tif_ctx, TIFFTAG_IMAGELENGTH, &tif_height); - TIFFGetField(m_tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &tif_comps); - TIFFGetField(m_tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc); - TIFFGetField(m_tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps); - - if (pAttribute) { - pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH; - if (TIFFGetField(m_tif_ctx, TIFFTAG_RESOLUTIONUNIT, - &pAttribute->m_wDPIUnit)) { - pAttribute->m_wDPIUnit--; - } - Tiff_Exif_GetInfo(m_tif_ctx, TIFFTAG_ORIENTATION, pAttribute); - if (Tiff_Exif_GetInfo(m_tif_ctx, TIFFTAG_XRESOLUTION, - pAttribute)) { - void* val = pAttribute->m_Exif[TIFFTAG_XRESOLUTION]; - FX_FLOAT fDpi = val ? *reinterpret_cast(val) : 0; - pAttribute->m_nXDPI = (int32_t)(fDpi + 0.5f); - } - if (Tiff_Exif_GetInfo(m_tif_ctx, TIFFTAG_YRESOLUTION, - pAttribute)) { - void* val = pAttribute->m_Exif[TIFFTAG_YRESOLUTION]; - FX_FLOAT fDpi = val ? *reinterpret_cast(val) : 0; - pAttribute->m_nYDPI = (int32_t)(fDpi + 0.5f); - } - Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pAttribute); - Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_MAKE, pAttribute); - Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_MODEL, pAttribute); - } - pdfium::base::CheckedNumeric checked_width = tif_width; - pdfium::base::CheckedNumeric checked_height = tif_height; - if (!checked_width.IsValid() || !checked_height.IsValid()) - return false; - - *width = checked_width.ValueOrDie(); - *height = checked_height.ValueOrDie(); - *comps = tif_comps; - *bpc = tif_bpc; - if (tif_rps > tif_height) { - tif_rps = tif_height; - TIFFSetField(m_tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps); - } - return true; -} - -bool CCodec_TiffContext::IsSupport(const CFX_DIBitmap* pDIBitmap) const { - if (TIFFIsTiled(m_tif_ctx)) - return false; - - uint16_t photometric = 0; - if (!TIFFGetField(m_tif_ctx, TIFFTAG_PHOTOMETRIC, &photometric)) - return false; - - switch (pDIBitmap->GetBPP()) { - case 1: - case 8: - if (photometric != PHOTOMETRIC_PALETTE) { - return false; - } - break; - case 24: - if (photometric != PHOTOMETRIC_RGB) { - return false; - } - break; - default: - return false; - } - uint16_t planarconfig = 0; - if (!TIFFGetFieldDefaulted(m_tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig)) - return false; - - return planarconfig != PLANARCONFIG_SEPARATE; -} - -void CCodec_TiffContext::SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps) { - uint16_t* red_orig = nullptr; - uint16_t* green_orig = nullptr; - uint16_t* blue_orig = nullptr; - TIFFGetField(m_tif_ctx, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig); - for (int32_t i = (1L << bps) - 1; i >= 0; i--) { -#define CVT(x) ((uint16_t)((x) >> 8)) - red_orig[i] = CVT(red_orig[i]); - green_orig[i] = CVT(green_orig[i]); - blue_orig[i] = CVT(blue_orig[i]); -#undef CVT - } - int32_t len = 1 << bps; - for (int32_t index = 0; index < len; index++) { - uint32_t r = red_orig[index] & 0xFF; - uint32_t g = green_orig[index] & 0xFF; - uint32_t b = blue_orig[index] & 0xFF; - uint32_t color = (uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16) | - (((uint32)0xffL) << 24); - pDIBitmap->SetPaletteEntry(index, color); - } -} - -bool CCodec_TiffContext::Decode1bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp) { - if (pDIBitmap->GetBPP() != 1 || spp != 1 || bps != 1 || - !IsSupport(pDIBitmap)) { - return false; - } - SetPalette(pDIBitmap, bps); - int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx); - uint8_t* buf = (uint8_t*)_TIFFmalloc(size); - if (!buf) { - TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer"); - return false; - } - uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); - uint32_t pitch = pDIBitmap->GetPitch(); - for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(m_tif_ctx, buf, row, 0); - for (int32_t j = 0; j < size; j++) { - bitMapbuffer[row * pitch + j] = buf[j]; - } - } - _TIFFfree(buf); - return true; -} - -bool CCodec_TiffContext::Decode8bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp) { - if (pDIBitmap->GetBPP() != 8 || spp != 1 || (bps != 4 && bps != 8) || - !IsSupport(pDIBitmap)) { - return false; - } - SetPalette(pDIBitmap, bps); - int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx); - uint8_t* buf = (uint8_t*)_TIFFmalloc(size); - if (!buf) { - TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer"); - return false; - } - uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); - uint32_t pitch = pDIBitmap->GetPitch(); - for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(m_tif_ctx, buf, row, 0); - for (int32_t j = 0; j < size; j++) { - switch (bps) { - case 4: - bitMapbuffer[row * pitch + 2 * j + 0] = (buf[j] & 0xF0) >> 4; - bitMapbuffer[row * pitch + 2 * j + 1] = (buf[j] & 0x0F) >> 0; - break; - case 8: - bitMapbuffer[row * pitch + j] = buf[j]; - break; - } - } - } - _TIFFfree(buf); - return true; -} - -bool CCodec_TiffContext::Decode24bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp) { - if (pDIBitmap->GetBPP() != 24 || !IsSupport(pDIBitmap)) - return false; - - int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx); - uint8_t* buf = (uint8_t*)_TIFFmalloc(size); - if (!buf) { - TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer"); - return false; - } - uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); - uint32_t pitch = pDIBitmap->GetPitch(); - for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(m_tif_ctx, buf, row, 0); - for (int32_t j = 0; j < size - 2; j += 3) { - bitMapbuffer[row * pitch + j + 0] = buf[j + 2]; - bitMapbuffer[row * pitch + j + 1] = buf[j + 1]; - bitMapbuffer[row * pitch + j + 2] = buf[j + 0]; - } - } - _TIFFfree(buf); - return true; -} - -bool CCodec_TiffContext::Decode(CFX_DIBitmap* pDIBitmap) { - uint32_t img_wid = pDIBitmap->GetWidth(); - uint32_t img_hei = pDIBitmap->GetHeight(); - uint32_t width = 0; - uint32_t height = 0; - TIFFGetField(m_tif_ctx, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(m_tif_ctx, TIFFTAG_IMAGELENGTH, &height); - if (img_wid != width || img_hei != height) - return false; - - if (pDIBitmap->GetBPP() == 32) { - uint16_t rotation = ORIENTATION_TOPLEFT; - TIFFGetField(m_tif_ctx, TIFFTAG_ORIENTATION, &rotation); - if (TIFFReadRGBAImageOriented(m_tif_ctx, img_wid, img_hei, - (uint32*)pDIBitmap->GetBuffer(), rotation, - 1)) { - for (uint32_t row = 0; row < img_hei; row++) { - uint8_t* row_buf = (uint8_t*)pDIBitmap->GetScanline(row); - TiffBGRA2RGBA(row_buf, img_wid, 4); - } - return true; - } - } - uint16_t spp = 0; - uint16_t bps = 0; - TIFFGetField(m_tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp); - TIFFGetField(m_tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps); - FX_SAFE_UINT32 safe_bpp = bps; - safe_bpp *= spp; - if (!safe_bpp.IsValid()) - return false; - uint32_t bpp = safe_bpp.ValueOrDie(); - if (bpp == 1) - return Decode1bppRGB(pDIBitmap, height, width, bps, spp); - if (bpp <= 8) - return Decode8bppRGB(pDIBitmap, height, width, bps, spp); - if (bpp <= 24) - return Decode24bppRGB(pDIBitmap, height, width, bps, spp); - return false; -} - -CCodec_TiffContext* CCodec_TiffModule::CreateDecoder( - const CFX_RetainPtr& file_ptr) { - auto pDecoder = pdfium::MakeUnique(); - if (!pDecoder->InitDecoder(file_ptr)) - return nullptr; - - return pDecoder.release(); -} - -bool CCodec_TiffModule::LoadFrameInfo(CCodec_TiffContext* ctx, - int32_t frame, - int32_t* width, - int32_t* height, - int32_t* comps, - int32_t* bpc, - CFX_DIBAttribute* pAttribute) { - return ctx->LoadFrameInfo(frame, width, height, comps, bpc, pAttribute); -} - -bool CCodec_TiffModule::Decode(CCodec_TiffContext* ctx, - class CFX_DIBitmap* pDIBitmap) { - return ctx->Decode(pDIBitmap); -} - -void CCodec_TiffModule::DestroyDecoder(CCodec_TiffContext* ctx) { - delete ctx; -} -- cgit v1.2.3