From 94293688e82ee6a979478fa983e217549c44e3c2 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 27 Jan 2016 18:27:56 -0800 Subject: XFA: Fix DOS newlines, final round. TBR=tsepez@chromium.org Review URL: https://codereview.chromium.org/1641963002 . --- .../fpdf_parser/fpdf_parser_objects_unittest.cpp | 320 +- core/src/fxcodec/codec/fx_codec_bmp.cpp | 254 +- core/src/fxcodec/codec/fx_codec_gif.cpp | 378 +- core/src/fxcodec/codec/fx_codec_png.cpp | 512 +-- core/src/fxcodec/codec/fx_codec_progress.cpp | 4708 ++++++++++---------- core/src/fxcodec/codec/fx_codec_progress.h | 446 +- core/src/fxcodec/codec/fx_codec_tiff.cpp | 1088 ++--- core/src/fxcodec/lbmp/fx_bmp.cpp | 1950 ++++---- core/src/fxcodec/lbmp/fx_bmp.h | 310 +- core/src/fxcodec/lgif/fx_gif.cpp | 2852 ++++++------ core/src/fxcodec/lgif/fx_gif.h | 664 +-- fpdfsdk/include/fpdfxfa/fpdfxfa_app.h | 194 +- fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h | 456 +- fpdfsdk/include/fpdfxfa/fpdfxfa_page.h | 132 +- fpdfsdk/include/fpdfxfa/fpdfxfa_util.h | 80 +- fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp | 1074 ++--- fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp | 2530 +++++------ fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp | 510 +-- fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp | 130 +- 19 files changed, 9294 insertions(+), 9294 deletions(-) diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp index 10cfecf042..3965399254 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp @@ -1,160 +1,160 @@ -// Copyright 2016 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. - -#include "core/include/fpdfapi/fpdf_objects.h" - -#include -#include - -#include "core/include/fxcrt/fx_basic.h" -#include "testing/gtest/include/gtest/gtest.h" - -class PDFObjectsTest : public testing::Test { - public: - void SetUp() override { - // Initialize different kinds of objects. - // Boolean objects. - CPDF_Boolean* boolean_false_obj = new CPDF_Boolean(false); - CPDF_Boolean* boolean_true_obj = new CPDF_Boolean(true); - // Number objects. - CPDF_Number* number_int_obj = new CPDF_Number(1245); - CPDF_Number* number_float_obj = new CPDF_Number(9.00345f); - // String objects. - CPDF_String* str_reg_obj = new CPDF_String(L"A simple test"); - CPDF_String* str_spec_obj = new CPDF_String(L"\t\n"); - // Name object. - CPDF_Name* name_obj = new CPDF_Name("space"); - // Array object. - CPDF_Array* array_obj = new CPDF_Array; - array_obj->InsertAt(0, new CPDF_Number(8902)); - array_obj->InsertAt(1, new CPDF_Name("address")); - // Dictionary object. - m_DictObj = new CPDF_Dictionary; - m_DictObj->SetAt("bool", new CPDF_Boolean(false)); - m_DictObj->SetAt("num", new CPDF_Number(0.23f)); - // Stream object. - const char content[] = "abcdefghijklmnopqrstuvwxyz"; - size_t buf_len = FX_ArraySize(content); - uint8_t* buf = reinterpret_cast(malloc(buf_len)); - memcpy(buf, content, buf_len); - m_StreamDictObj = new CPDF_Dictionary; - m_StreamDictObj->SetAt("key1", new CPDF_String(L" test dict")); - m_StreamDictObj->SetAt("key2", new CPDF_Number(-1)); - CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj); - // Null Object. - CPDF_Null* null_obj = new CPDF_Null; - // All direct objects. - CPDF_Object* objs[] = {boolean_false_obj, boolean_true_obj, number_int_obj, - number_float_obj, str_reg_obj, str_spec_obj, - name_obj, array_obj, m_DictObj, - stream_obj, null_obj}; - for (int i = 0; i < FX_ArraySize(objs); ++i) - m_DirectObjs.emplace_back(objs[i]); - - // Indirect references to indirect objects. - m_ObjHolder.reset(new CPDF_IndirectObjectHolder(nullptr)); - CPDF_Object* referred_objs[] = { - boolean_true_obj, number_int_obj, str_spec_obj, name_obj, - array_obj, m_DictObj, stream_obj}; - for (int i = 0; i < FX_ArraySize(referred_objs); ++i) { - m_ObjHolder->AddIndirectObject(referred_objs[i]); - m_RefObjs.emplace_back( - new CPDF_Reference(m_ObjHolder.get(), referred_objs[i]->GetObjNum())); - } - } - - protected: - using ScopedObj = std::unique_ptr>; - - // m_ObjHolder needs to be declared first and destructed last since it also - // refers to some objects in m_DirectObjs. - std::unique_ptr m_ObjHolder; - std::vector m_DirectObjs; - std::vector m_RefObjs; - CPDF_Dictionary* m_DictObj; - CPDF_Dictionary* m_StreamDictObj; -}; - -TEST_F(PDFObjectsTest, GetString) { - const char* direct_obj_results[] = { - "false", "true", "1245", "9.00345", "A simple test", "\t\n", "space", - "", "", "", ""}; - // Check for direct objects. - for (int i = 0; i < m_DirectObjs.size(); ++i) - EXPECT_STREQ(m_DirectObjs[i]->GetString().c_str(), direct_obj_results[i]); - - // Check indirect references. - const char* indirect_obj_results[] = {"true", "1245", "\t\n", "space", - "", "", ""}; - for (int i = 0; i < m_RefObjs.size(); ++i) { - EXPECT_STREQ(m_RefObjs[i]->GetString().c_str(), indirect_obj_results[i]); - } -} - -TEST_F(PDFObjectsTest, GetConstString) { - const char* direct_obj_results[] = { - nullptr, nullptr, nullptr, nullptr, "A simple test", "\t\n", - "space", nullptr, nullptr, nullptr, nullptr}; - // Check for direct objects. - for (int i = 0; i < m_DirectObjs.size(); ++i) { - if (!direct_obj_results[i]) { - EXPECT_EQ(m_DirectObjs[i]->GetConstString().GetCStr(), - direct_obj_results[i]); - } else { - EXPECT_STREQ(m_DirectObjs[i]->GetConstString().GetCStr(), - direct_obj_results[i]); - } - } - // Check indirect references. - const char* indirect_obj_results[] = {nullptr, nullptr, "\t\n", "space", - nullptr, nullptr, nullptr}; - for (int i = 0; i < m_RefObjs.size(); ++i) { - if (!indirect_obj_results[i]) - EXPECT_EQ(m_RefObjs[i]->GetConstString().GetCStr(), nullptr); - else { - EXPECT_STREQ(m_RefObjs[i]->GetConstString().GetCStr(), - indirect_obj_results[i]); - } - } -} - -TEST_F(PDFObjectsTest, GetNumber) { - const FX_FLOAT direct_obj_results[] = {0, 0, 1245, 9.00345f, 0, 0, - 0, 0, 0, 0, 0}; - // Check for direct objects. - for (int i = 0; i < m_DirectObjs.size(); ++i) - EXPECT_EQ(m_DirectObjs[i]->GetNumber(), direct_obj_results[i]); - - // Check indirect references. - const FX_FLOAT indirect_obj_results[] = {0, 1245, 0, 0, 0, 0, 0}; - for (int i = 0; i < m_RefObjs.size(); ++i) - EXPECT_EQ(m_RefObjs[i]->GetNumber(), indirect_obj_results[i]); -} - -TEST_F(PDFObjectsTest, GetInteger) { - const int direct_obj_results[] = {0, 1, 1245, 9, 0, 0, 0, 0, 0, 0, 0}; - // Check for direct objects. - for (int i = 0; i < m_DirectObjs.size(); ++i) - EXPECT_EQ(m_DirectObjs[i]->GetInteger(), direct_obj_results[i]); - - // Check indirect references. - const int indirect_obj_results[] = {1, 1245, 0, 0, 0, 0, 0}; - for (int i = 0; i < m_RefObjs.size(); ++i) - EXPECT_EQ(m_RefObjs[i]->GetInteger(), indirect_obj_results[i]); -} - -TEST_F(PDFObjectsTest, GetDict) { - const CPDF_Dictionary* direct_obj_results[] = { - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, m_DictObj, m_StreamDictObj, nullptr}; - // Check for direct objects. - for (int i = 0; i < m_DirectObjs.size(); ++i) - EXPECT_EQ(m_DirectObjs[i]->GetDict(), direct_obj_results[i]); - - // Check indirect references. - const CPDF_Dictionary* indirect_obj_results[] = { - nullptr, nullptr, nullptr, nullptr, nullptr, m_DictObj, m_StreamDictObj}; - for (int i = 0; i < m_RefObjs.size(); ++i) - EXPECT_EQ(m_RefObjs[i]->GetDict(), indirect_obj_results[i]); -} +// Copyright 2016 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. + +#include "core/include/fpdfapi/fpdf_objects.h" + +#include +#include + +#include "core/include/fxcrt/fx_basic.h" +#include "testing/gtest/include/gtest/gtest.h" + +class PDFObjectsTest : public testing::Test { + public: + void SetUp() override { + // Initialize different kinds of objects. + // Boolean objects. + CPDF_Boolean* boolean_false_obj = new CPDF_Boolean(false); + CPDF_Boolean* boolean_true_obj = new CPDF_Boolean(true); + // Number objects. + CPDF_Number* number_int_obj = new CPDF_Number(1245); + CPDF_Number* number_float_obj = new CPDF_Number(9.00345f); + // String objects. + CPDF_String* str_reg_obj = new CPDF_String(L"A simple test"); + CPDF_String* str_spec_obj = new CPDF_String(L"\t\n"); + // Name object. + CPDF_Name* name_obj = new CPDF_Name("space"); + // Array object. + CPDF_Array* array_obj = new CPDF_Array; + array_obj->InsertAt(0, new CPDF_Number(8902)); + array_obj->InsertAt(1, new CPDF_Name("address")); + // Dictionary object. + m_DictObj = new CPDF_Dictionary; + m_DictObj->SetAt("bool", new CPDF_Boolean(false)); + m_DictObj->SetAt("num", new CPDF_Number(0.23f)); + // Stream object. + const char content[] = "abcdefghijklmnopqrstuvwxyz"; + size_t buf_len = FX_ArraySize(content); + uint8_t* buf = reinterpret_cast(malloc(buf_len)); + memcpy(buf, content, buf_len); + m_StreamDictObj = new CPDF_Dictionary; + m_StreamDictObj->SetAt("key1", new CPDF_String(L" test dict")); + m_StreamDictObj->SetAt("key2", new CPDF_Number(-1)); + CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj); + // Null Object. + CPDF_Null* null_obj = new CPDF_Null; + // All direct objects. + CPDF_Object* objs[] = {boolean_false_obj, boolean_true_obj, number_int_obj, + number_float_obj, str_reg_obj, str_spec_obj, + name_obj, array_obj, m_DictObj, + stream_obj, null_obj}; + for (int i = 0; i < FX_ArraySize(objs); ++i) + m_DirectObjs.emplace_back(objs[i]); + + // Indirect references to indirect objects. + m_ObjHolder.reset(new CPDF_IndirectObjectHolder(nullptr)); + CPDF_Object* referred_objs[] = { + boolean_true_obj, number_int_obj, str_spec_obj, name_obj, + array_obj, m_DictObj, stream_obj}; + for (int i = 0; i < FX_ArraySize(referred_objs); ++i) { + m_ObjHolder->AddIndirectObject(referred_objs[i]); + m_RefObjs.emplace_back( + new CPDF_Reference(m_ObjHolder.get(), referred_objs[i]->GetObjNum())); + } + } + + protected: + using ScopedObj = std::unique_ptr>; + + // m_ObjHolder needs to be declared first and destructed last since it also + // refers to some objects in m_DirectObjs. + std::unique_ptr m_ObjHolder; + std::vector m_DirectObjs; + std::vector m_RefObjs; + CPDF_Dictionary* m_DictObj; + CPDF_Dictionary* m_StreamDictObj; +}; + +TEST_F(PDFObjectsTest, GetString) { + const char* direct_obj_results[] = { + "false", "true", "1245", "9.00345", "A simple test", "\t\n", "space", + "", "", "", ""}; + // Check for direct objects. + for (int i = 0; i < m_DirectObjs.size(); ++i) + EXPECT_STREQ(m_DirectObjs[i]->GetString().c_str(), direct_obj_results[i]); + + // Check indirect references. + const char* indirect_obj_results[] = {"true", "1245", "\t\n", "space", + "", "", ""}; + for (int i = 0; i < m_RefObjs.size(); ++i) { + EXPECT_STREQ(m_RefObjs[i]->GetString().c_str(), indirect_obj_results[i]); + } +} + +TEST_F(PDFObjectsTest, GetConstString) { + const char* direct_obj_results[] = { + nullptr, nullptr, nullptr, nullptr, "A simple test", "\t\n", + "space", nullptr, nullptr, nullptr, nullptr}; + // Check for direct objects. + for (int i = 0; i < m_DirectObjs.size(); ++i) { + if (!direct_obj_results[i]) { + EXPECT_EQ(m_DirectObjs[i]->GetConstString().GetCStr(), + direct_obj_results[i]); + } else { + EXPECT_STREQ(m_DirectObjs[i]->GetConstString().GetCStr(), + direct_obj_results[i]); + } + } + // Check indirect references. + const char* indirect_obj_results[] = {nullptr, nullptr, "\t\n", "space", + nullptr, nullptr, nullptr}; + for (int i = 0; i < m_RefObjs.size(); ++i) { + if (!indirect_obj_results[i]) + EXPECT_EQ(m_RefObjs[i]->GetConstString().GetCStr(), nullptr); + else { + EXPECT_STREQ(m_RefObjs[i]->GetConstString().GetCStr(), + indirect_obj_results[i]); + } + } +} + +TEST_F(PDFObjectsTest, GetNumber) { + const FX_FLOAT direct_obj_results[] = {0, 0, 1245, 9.00345f, 0, 0, + 0, 0, 0, 0, 0}; + // Check for direct objects. + for (int i = 0; i < m_DirectObjs.size(); ++i) + EXPECT_EQ(m_DirectObjs[i]->GetNumber(), direct_obj_results[i]); + + // Check indirect references. + const FX_FLOAT indirect_obj_results[] = {0, 1245, 0, 0, 0, 0, 0}; + for (int i = 0; i < m_RefObjs.size(); ++i) + EXPECT_EQ(m_RefObjs[i]->GetNumber(), indirect_obj_results[i]); +} + +TEST_F(PDFObjectsTest, GetInteger) { + const int direct_obj_results[] = {0, 1, 1245, 9, 0, 0, 0, 0, 0, 0, 0}; + // Check for direct objects. + for (int i = 0; i < m_DirectObjs.size(); ++i) + EXPECT_EQ(m_DirectObjs[i]->GetInteger(), direct_obj_results[i]); + + // Check indirect references. + const int indirect_obj_results[] = {1, 1245, 0, 0, 0, 0, 0}; + for (int i = 0; i < m_RefObjs.size(); ++i) + EXPECT_EQ(m_RefObjs[i]->GetInteger(), indirect_obj_results[i]); +} + +TEST_F(PDFObjectsTest, GetDict) { + const CPDF_Dictionary* direct_obj_results[] = { + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, m_DictObj, m_StreamDictObj, nullptr}; + // Check for direct objects. + for (int i = 0; i < m_DirectObjs.size(); ++i) + EXPECT_EQ(m_DirectObjs[i]->GetDict(), direct_obj_results[i]); + + // Check indirect references. + const CPDF_Dictionary* indirect_obj_results[] = { + nullptr, nullptr, nullptr, nullptr, nullptr, m_DictObj, m_StreamDictObj}; + for (int i = 0; i < m_RefObjs.size(); ++i) + EXPECT_EQ(m_RefObjs[i]->GetDict(), indirect_obj_results[i]); +} diff --git a/core/src/fxcodec/codec/fx_codec_bmp.cpp b/core/src/fxcodec/codec/fx_codec_bmp.cpp index 08b2f480df..2396f36c1a 100644 --- a/core/src/fxcodec/codec/fx_codec_bmp.cpp +++ b/core/src/fxcodec/codec/fx_codec_bmp.cpp @@ -1,127 +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/include/fxcodec/fx_codec.h" -#include "core/include/fxge/fx_dib.h" -#include "codec_int.h" -#include "core/src/fxcodec/lbmp/fx_bmp.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) { - if (p != NULL) { - 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 FX_BOOL _bmp_get_data_position(bmp_decompress_struct_p bmp_ptr, - FX_DWORD 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); -} -void* CCodec_BmpModule::Start(void* pModule) { - FXBMP_Context* p = (FXBMP_Context*)FX_Alloc(uint8_t, sizeof(FXBMP_Context)); - if (p == NULL) { - return NULL; - } - FXSYS_memset(p, 0, sizeof(FXBMP_Context)); - if (p == NULL) { - return NULL; - } - p->m_AllocFunc = _bmp_alloc_func; - p->m_FreeFunc = _bmp_free_func; - p->bmp_ptr = NULL; - p->parent_ptr = (void*)this; - p->child_ptr = pModule; - p->bmp_ptr = _bmp_create_decompress(); - if (p->bmp_ptr == NULL) { - FX_Free(p); - return NULL; - } - 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(void* pContext) { - FXBMP_Context* p = (FXBMP_Context*)pContext; - if (p != NULL) { - _bmp_destroy_decompress(&p->bmp_ptr); - p->m_FreeFunc(p); - } -} -int32_t CCodec_BmpModule::ReadHeader(void* pContext, - int32_t* width, - int32_t* height, - FX_BOOL* tb_flag, - int32_t* components, - int32_t* pal_num, - FX_DWORD** pal_pp, - CFX_DIBAttribute* pAttribute) { - FXBMP_Context* p = (FXBMP_Context*)pContext; - if (setjmp(p->bmp_ptr->jmpbuf)) { - return 0; - } - int32_t ret = _bmp_read_header(p->bmp_ptr); - if (ret != 1) { - return ret; - } - *width = p->bmp_ptr->width; - *height = p->bmp_ptr->height; - *tb_flag = p->bmp_ptr->imgTB_flag; - *components = p->bmp_ptr->components; - *pal_num = p->bmp_ptr->pal_num; - *pal_pp = p->bmp_ptr->pal_ptr; - if (pAttribute) { - pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER; - pAttribute->m_nXDPI = p->bmp_ptr->dpi_x; - pAttribute->m_nYDPI = p->bmp_ptr->dpi_y; - pAttribute->m_nBmpCompressType = p->bmp_ptr->compress_flag; - } - return 1; -} -int32_t CCodec_BmpModule::LoadImage(void* pContext) { - FXBMP_Context* p = (FXBMP_Context*)pContext; - if (setjmp(p->bmp_ptr->jmpbuf)) { - return 0; - } - return _bmp_decode_image(p->bmp_ptr); -} -FX_DWORD CCodec_BmpModule::GetAvailInput(void* pContext, - uint8_t** avial_buf_ptr) { - FXBMP_Context* p = (FXBMP_Context*)pContext; - return _bmp_get_avail_input(p->bmp_ptr, avial_buf_ptr); -} -void CCodec_BmpModule::Input(void* pContext, - const uint8_t* src_buf, - FX_DWORD src_size) { - FXBMP_Context* p = (FXBMP_Context*)pContext; - _bmp_input_buffer(p->bmp_ptr, (uint8_t*)src_buf, src_size); -} +// 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/include/fxcodec/fx_codec.h" +#include "core/include/fxge/fx_dib.h" +#include "codec_int.h" +#include "core/src/fxcodec/lbmp/fx_bmp.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) { + if (p != NULL) { + 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 FX_BOOL _bmp_get_data_position(bmp_decompress_struct_p bmp_ptr, + FX_DWORD 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); +} +void* CCodec_BmpModule::Start(void* pModule) { + FXBMP_Context* p = (FXBMP_Context*)FX_Alloc(uint8_t, sizeof(FXBMP_Context)); + if (p == NULL) { + return NULL; + } + FXSYS_memset(p, 0, sizeof(FXBMP_Context)); + if (p == NULL) { + return NULL; + } + p->m_AllocFunc = _bmp_alloc_func; + p->m_FreeFunc = _bmp_free_func; + p->bmp_ptr = NULL; + p->parent_ptr = (void*)this; + p->child_ptr = pModule; + p->bmp_ptr = _bmp_create_decompress(); + if (p->bmp_ptr == NULL) { + FX_Free(p); + return NULL; + } + 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(void* pContext) { + FXBMP_Context* p = (FXBMP_Context*)pContext; + if (p != NULL) { + _bmp_destroy_decompress(&p->bmp_ptr); + p->m_FreeFunc(p); + } +} +int32_t CCodec_BmpModule::ReadHeader(void* pContext, + int32_t* width, + int32_t* height, + FX_BOOL* tb_flag, + int32_t* components, + int32_t* pal_num, + FX_DWORD** pal_pp, + CFX_DIBAttribute* pAttribute) { + FXBMP_Context* p = (FXBMP_Context*)pContext; + if (setjmp(p->bmp_ptr->jmpbuf)) { + return 0; + } + int32_t ret = _bmp_read_header(p->bmp_ptr); + if (ret != 1) { + return ret; + } + *width = p->bmp_ptr->width; + *height = p->bmp_ptr->height; + *tb_flag = p->bmp_ptr->imgTB_flag; + *components = p->bmp_ptr->components; + *pal_num = p->bmp_ptr->pal_num; + *pal_pp = p->bmp_ptr->pal_ptr; + if (pAttribute) { + pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER; + pAttribute->m_nXDPI = p->bmp_ptr->dpi_x; + pAttribute->m_nYDPI = p->bmp_ptr->dpi_y; + pAttribute->m_nBmpCompressType = p->bmp_ptr->compress_flag; + } + return 1; +} +int32_t CCodec_BmpModule::LoadImage(void* pContext) { + FXBMP_Context* p = (FXBMP_Context*)pContext; + if (setjmp(p->bmp_ptr->jmpbuf)) { + return 0; + } + return _bmp_decode_image(p->bmp_ptr); +} +FX_DWORD CCodec_BmpModule::GetAvailInput(void* pContext, + uint8_t** avial_buf_ptr) { + FXBMP_Context* p = (FXBMP_Context*)pContext; + return _bmp_get_avail_input(p->bmp_ptr, avial_buf_ptr); +} +void CCodec_BmpModule::Input(void* pContext, + const uint8_t* src_buf, + FX_DWORD src_size) { + FXBMP_Context* p = (FXBMP_Context*)pContext; + _bmp_input_buffer(p->bmp_ptr, (uint8_t*)src_buf, src_size); +} diff --git a/core/src/fxcodec/codec/fx_codec_gif.cpp b/core/src/fxcodec/codec/fx_codec_gif.cpp index 45aeb09c41..d61ccc6f70 100644 --- a/core/src/fxcodec/codec/fx_codec_gif.cpp +++ b/core/src/fxcodec/codec/fx_codec_gif.cpp @@ -1,189 +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/include/fxcodec/fx_codec.h" -#include "core/include/fxge/fx_dib.h" -#include "codec_int.h" -#include "core/src/fxcodec/lgif/fx_gif.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) { - if (p != NULL) { - 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, - FX_DWORD* 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 FX_BOOL _gif_get_record_position(gif_decompress_struct_p gif_ptr, - FX_DWORD 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, - FX_BOOL user_input, - int32_t trans_index, - int32_t disposal_method, - FX_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); -} -void* CCodec_GifModule::Start(void* pModule) { - FXGIF_Context* p = (FXGIF_Context*)FX_Alloc(uint8_t, sizeof(FXGIF_Context)); - if (p == NULL) { - return NULL; - } - FXSYS_memset(p, 0, sizeof(FXGIF_Context)); - p->m_AllocFunc = _gif_alloc_func; - p->m_FreeFunc = _gif_free_func; - p->gif_ptr = NULL; - p->parent_ptr = (void*)this; - p->child_ptr = pModule; - p->gif_ptr = _gif_create_decompress(); - if (p->gif_ptr == NULL) { - FX_Free(p); - return NULL; - } - 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(void* pContext) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - if (p != NULL) { - _gif_destroy_decompress(&p->gif_ptr); - p->m_FreeFunc(p); - } -} -int32_t CCodec_GifModule::ReadHeader(void* pContext, - int* width, - int* height, - int* pal_num, - void** pal_pp, - int* bg_index, - CFX_DIBAttribute* pAttribute) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - if (setjmp(p->gif_ptr->jmpbuf)) { - return 0; - } - int32_t ret = _gif_read_header(p->gif_ptr); - if (ret != 1) { - return ret; - } - if (pAttribute) { - } - *width = p->gif_ptr->width; - *height = p->gif_ptr->height; - *pal_num = p->gif_ptr->global_pal_num; - *pal_pp = p->gif_ptr->global_pal_ptr; - *bg_index = p->gif_ptr->bc_index; - return 1; -} -int32_t CCodec_GifModule::LoadFrameInfo(void* pContext, int* frame_num) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - if (setjmp(p->gif_ptr->jmpbuf)) { - return 0; - } - int32_t ret = _gif_get_frame(p->gif_ptr); - if (ret != 1) { - return ret; - } - *frame_num = _gif_get_frame_num(p->gif_ptr); - return 1; -} -int32_t CCodec_GifModule::LoadFrame(void* pContext, - int frame_num, - CFX_DIBAttribute* pAttribute) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - if (setjmp(p->gif_ptr->jmpbuf)) { - return 0; - } - int32_t ret = _gif_load_frame(p->gif_ptr, frame_num); - if (ret == 1) { - if (pAttribute) { - pAttribute->m_nGifLeft = - p->gif_ptr->img_ptr_arr_ptr->GetAt(frame_num)->image_info_ptr->left; - pAttribute->m_nGifTop = - p->gif_ptr->img_ptr_arr_ptr->GetAt(frame_num)->image_info_ptr->top; - pAttribute->m_fAspectRatio = p->gif_ptr->pixel_aspect; - if (p->gif_ptr->cmt_data_ptr) { - const uint8_t* buf = - (const uint8_t*)p->gif_ptr->cmt_data_ptr->GetBuffer(0); - FX_DWORD len = p->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.Empty(); - } - buf += size; - size = *buf++; - if (size == 20) { - FXSYS_memcpy(pAttribute->m_strTime, buf, size); - } - } - } - } - } - return ret; -} -FX_DWORD CCodec_GifModule::GetAvailInput(void* pContext, - uint8_t** avial_buf_ptr) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - return _gif_get_avail_input(p->gif_ptr, avial_buf_ptr); -} -void CCodec_GifModule::Input(void* pContext, - const uint8_t* src_buf, - FX_DWORD src_size) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - _gif_input_buffer(p->gif_ptr, (uint8_t*)src_buf, src_size); -} +// 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/include/fxcodec/fx_codec.h" +#include "core/include/fxge/fx_dib.h" +#include "codec_int.h" +#include "core/src/fxcodec/lgif/fx_gif.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) { + if (p != NULL) { + 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, + FX_DWORD* 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 FX_BOOL _gif_get_record_position(gif_decompress_struct_p gif_ptr, + FX_DWORD 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, + FX_BOOL user_input, + int32_t trans_index, + int32_t disposal_method, + FX_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); +} +void* CCodec_GifModule::Start(void* pModule) { + FXGIF_Context* p = (FXGIF_Context*)FX_Alloc(uint8_t, sizeof(FXGIF_Context)); + if (p == NULL) { + return NULL; + } + FXSYS_memset(p, 0, sizeof(FXGIF_Context)); + p->m_AllocFunc = _gif_alloc_func; + p->m_FreeFunc = _gif_free_func; + p->gif_ptr = NULL; + p->parent_ptr = (void*)this; + p->child_ptr = pModule; + p->gif_ptr = _gif_create_decompress(); + if (p->gif_ptr == NULL) { + FX_Free(p); + return NULL; + } + 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(void* pContext) { + FXGIF_Context* p = (FXGIF_Context*)pContext; + if (p != NULL) { + _gif_destroy_decompress(&p->gif_ptr); + p->m_FreeFunc(p); + } +} +int32_t CCodec_GifModule::ReadHeader(void* pContext, + int* width, + int* height, + int* pal_num, + void** pal_pp, + int* bg_index, + CFX_DIBAttribute* pAttribute) { + FXGIF_Context* p = (FXGIF_Context*)pContext; + if (setjmp(p->gif_ptr->jmpbuf)) { + return 0; + } + int32_t ret = _gif_read_header(p->gif_ptr); + if (ret != 1) { + return ret; + } + if (pAttribute) { + } + *width = p->gif_ptr->width; + *height = p->gif_ptr->height; + *pal_num = p->gif_ptr->global_pal_num; + *pal_pp = p->gif_ptr->global_pal_ptr; + *bg_index = p->gif_ptr->bc_index; + return 1; +} +int32_t CCodec_GifModule::LoadFrameInfo(void* pContext, int* frame_num) { + FXGIF_Context* p = (FXGIF_Context*)pContext; + if (setjmp(p->gif_ptr->jmpbuf)) { + return 0; + } + int32_t ret = _gif_get_frame(p->gif_ptr); + if (ret != 1) { + return ret; + } + *frame_num = _gif_get_frame_num(p->gif_ptr); + return 1; +} +int32_t CCodec_GifModule::LoadFrame(void* pContext, + int frame_num, + CFX_DIBAttribute* pAttribute) { + FXGIF_Context* p = (FXGIF_Context*)pContext; + if (setjmp(p->gif_ptr->jmpbuf)) { + return 0; + } + int32_t ret = _gif_load_frame(p->gif_ptr, frame_num); + if (ret == 1) { + if (pAttribute) { + pAttribute->m_nGifLeft = + p->gif_ptr->img_ptr_arr_ptr->GetAt(frame_num)->image_info_ptr->left; + pAttribute->m_nGifTop = + p->gif_ptr->img_ptr_arr_ptr->GetAt(frame_num)->image_info_ptr->top; + pAttribute->m_fAspectRatio = p->gif_ptr->pixel_aspect; + if (p->gif_ptr->cmt_data_ptr) { + const uint8_t* buf = + (const uint8_t*)p->gif_ptr->cmt_data_ptr->GetBuffer(0); + FX_DWORD len = p->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.Empty(); + } + buf += size; + size = *buf++; + if (size == 20) { + FXSYS_memcpy(pAttribute->m_strTime, buf, size); + } + } + } + } + } + return ret; +} +FX_DWORD CCodec_GifModule::GetAvailInput(void* pContext, + uint8_t** avial_buf_ptr) { + FXGIF_Context* p = (FXGIF_Context*)pContext; + return _gif_get_avail_input(p->gif_ptr, avial_buf_ptr); +} +void CCodec_GifModule::Input(void* pContext, + const uint8_t* src_buf, + FX_DWORD src_size) { + FXGIF_Context* p = (FXGIF_Context*)pContext; + _gif_input_buffer(p->gif_ptr, (uint8_t*)src_buf, src_size); +} diff --git a/core/src/fxcodec/codec/fx_codec_png.cpp b/core/src/fxcodec/codec/fx_codec_png.cpp index 9e08473339..32b0d3d48f 100644 --- a/core/src/fxcodec/codec/fx_codec_png.cpp +++ b/core/src/fxcodec/codec/fx_codec_png.cpp @@ -1,256 +1,256 @@ -// 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/include/fxcodec/fx_codec.h" -#include "core/include/fxge/fx_dib.h" -#include "codec_int.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 = NULL; - 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), "%4d:%2d:%2d %2d:%2d:%2d", - 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 = NULL; - 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.Empty(); - pAttribute->m_strAuthor.Load((uint8_t*)text[i].text, - (FX_STRSIZE)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) { - if (p != NULL) { - 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 == NULL) { - return; - } - CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; - if (pModule == NULL) { - 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, NULL, - NULL, NULL); - 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 == NULL) { - return; - } - CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; - uint8_t* src_buf = NULL; - if (!pModule->AskScanlineBufCallback(p->child_ptr, row_num, src_buf)) { - png_error(png_ptr, "Ask Scanline buffer Callback Error"); - } - if (src_buf != NULL) { - png_progressive_combine_row(png_ptr, src_buf, new_row); - } - pModule->FillScanlineBufCompletedCallback(p->child_ptr, pass, row_num); -} -void* CCodec_PngModule::Start(void* pModule) { - FXPNG_Context* p = (FXPNG_Context*)FX_Alloc(uint8_t, sizeof(FXPNG_Context)); - if (p == NULL) { - return NULL; - } - p->m_AllocFunc = _png_alloc_func; - p->m_FreeFunc = _png_free_func; - p->png_ptr = NULL; - p->info_ptr = NULL; - p->parent_ptr = (void*)this; - p->child_ptr = pModule; - p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (p->png_ptr == NULL) { - FX_Free(p); - return NULL; - } - p->info_ptr = png_create_info_struct(p->png_ptr); - if (p->info_ptr == NULL) { - png_destroy_read_struct(&(p->png_ptr), (png_infopp)NULL, (png_infopp)NULL); - FX_Free(p); - return NULL; - } - if (setjmp(png_jmpbuf(p->png_ptr))) { - if (p != NULL) { - png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), (png_infopp)NULL); - FX_Free(p); - } - return NULL; - } - 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(void* pContext) { - FXPNG_Context* p = (FXPNG_Context*)pContext; - if (p != NULL) { - png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), (png_infopp)NULL); - p->m_FreeFunc(p); - } -} -FX_BOOL CCodec_PngModule::Input(void* pContext, - const uint8_t* src_buf, - FX_DWORD src_size, - CFX_DIBAttribute* pAttribute) { - FXPNG_Context* p = (FXPNG_Context*)pContext; - if (setjmp(png_jmpbuf(p->png_ptr))) { - if (pAttribute && - 0 == FXSYS_strcmp(m_szLastError, "Read Header Callback Error")) { - _png_load_bmp_attribute(p->png_ptr, p->info_ptr, pAttribute); - } - return FALSE; - } - png_process_data(p->png_ptr, p->info_ptr, (uint8_t*)src_buf, src_size); - return TRUE; -} +// 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/include/fxcodec/fx_codec.h" +#include "core/include/fxge/fx_dib.h" +#include "codec_int.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 = NULL; + 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), "%4d:%2d:%2d %2d:%2d:%2d", + 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 = NULL; + 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.Empty(); + pAttribute->m_strAuthor.Load((uint8_t*)text[i].text, + (FX_STRSIZE)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) { + if (p != NULL) { + 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 == NULL) { + return; + } + CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; + if (pModule == NULL) { + 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, NULL, + NULL, NULL); + 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 == NULL) { + return; + } + CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; + uint8_t* src_buf = NULL; + if (!pModule->AskScanlineBufCallback(p->child_ptr, row_num, src_buf)) { + png_error(png_ptr, "Ask Scanline buffer Callback Error"); + } + if (src_buf != NULL) { + png_progressive_combine_row(png_ptr, src_buf, new_row); + } + pModule->FillScanlineBufCompletedCallback(p->child_ptr, pass, row_num); +} +void* CCodec_PngModule::Start(void* pModule) { + FXPNG_Context* p = (FXPNG_Context*)FX_Alloc(uint8_t, sizeof(FXPNG_Context)); + if (p == NULL) { + return NULL; + } + p->m_AllocFunc = _png_alloc_func; + p->m_FreeFunc = _png_free_func; + p->png_ptr = NULL; + p->info_ptr = NULL; + p->parent_ptr = (void*)this; + p->child_ptr = pModule; + p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (p->png_ptr == NULL) { + FX_Free(p); + return NULL; + } + p->info_ptr = png_create_info_struct(p->png_ptr); + if (p->info_ptr == NULL) { + png_destroy_read_struct(&(p->png_ptr), (png_infopp)NULL, (png_infopp)NULL); + FX_Free(p); + return NULL; + } + if (setjmp(png_jmpbuf(p->png_ptr))) { + if (p != NULL) { + png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), (png_infopp)NULL); + FX_Free(p); + } + return NULL; + } + 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(void* pContext) { + FXPNG_Context* p = (FXPNG_Context*)pContext; + if (p != NULL) { + png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), (png_infopp)NULL); + p->m_FreeFunc(p); + } +} +FX_BOOL CCodec_PngModule::Input(void* pContext, + const uint8_t* src_buf, + FX_DWORD src_size, + CFX_DIBAttribute* pAttribute) { + FXPNG_Context* p = (FXPNG_Context*)pContext; + if (setjmp(png_jmpbuf(p->png_ptr))) { + if (pAttribute && + 0 == FXSYS_strcmp(m_szLastError, "Read Header Callback Error")) { + _png_load_bmp_attribute(p->png_ptr, p->info_ptr, pAttribute); + } + return FALSE; + } + png_process_data(p->png_ptr, p->info_ptr, (uint8_t*)src_buf, src_size); + return TRUE; +} diff --git a/core/src/fxcodec/codec/fx_codec_progress.cpp b/core/src/fxcodec/codec/fx_codec_progress.cpp index 383e3ed93d..5dbc19b4b6 100644 --- a/core/src/fxcodec/codec/fx_codec_progress.cpp +++ b/core/src/fxcodec/codec/fx_codec_progress.cpp @@ -1,2354 +1,2354 @@ -// 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/include/fxge/fx_dib.h" -#include "core/include/fxcodec/fx_codec.h" -#include "fx_codec_progress.h" -void CFXCODEC_WeightTable::Calc(int dest_len, - int dest_min, - int dest_max, - int src_len, - int src_min, - int src_max, - FX_BOOL bInterpol) { - if (m_pWeightTables) { - FX_Free(m_pWeightTables); - } - double scale, base; - scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len)); - if (dest_len < 0) { - base = (FX_FLOAT)(src_len); - } else { - base = 0.0f; - } - m_ItemSize = - (int)(sizeof(int) * 2 + - sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + 1)); - m_DestMin = dest_min; - m_pWeightTables = FX_Alloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4); - if (m_pWeightTables == NULL) { - return; - } - if (FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { - for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { - PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); - double src_pos = dest_pixel * scale + scale / 2 + base; - if (bInterpol) { - pixel_weights.m_SrcStart = - (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); - pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); - if (pixel_weights.m_SrcStart < src_min) { - pixel_weights.m_SrcStart = src_min; - } - if (pixel_weights.m_SrcEnd >= src_max) { - pixel_weights.m_SrcEnd = src_max - 1; - } - if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { - pixel_weights.m_Weights[0] = 65536; - } else { - pixel_weights.m_Weights[1] = FXSYS_round( - (FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * - 65536); - pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1]; - } - } else { - pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = - (int)FXSYS_floor((FX_FLOAT)src_pos); - pixel_weights.m_Weights[0] = 65536; - } - } - return; - } - for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { - PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); - double src_start = dest_pixel * scale + base; - double src_end = src_start + scale; - int start_i, end_i; - if (src_start < src_end) { - start_i = (int)FXSYS_floor((FX_FLOAT)src_start); - end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); - } else { - start_i = (int)FXSYS_floor((FX_FLOAT)src_end); - end_i = (int)FXSYS_ceil((FX_FLOAT)src_start); - } - if (start_i < src_min) { - start_i = src_min; - } - if (end_i >= src_max) { - end_i = src_max - 1; - } - if (start_i > end_i) { - pixel_weights.m_SrcStart = start_i; - pixel_weights.m_SrcEnd = start_i; - continue; - } - pixel_weights.m_SrcStart = start_i; - pixel_weights.m_SrcEnd = end_i; - for (int j = start_i; j <= end_i; j++) { - double dest_start = FXSYS_Div((FX_FLOAT)(j)-base, scale); - double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale); - if (dest_start > dest_end) { - double temp = dest_start; - dest_start = dest_end; - dest_end = temp; - } - double area_start = dest_start > (FX_FLOAT)(dest_pixel) - ? dest_start - : (FX_FLOAT)(dest_pixel); - double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) - ? (FX_FLOAT)(dest_pixel + 1) - : dest_end; - double weight = area_start >= area_end ? 0.0f : area_end - area_start; - if (weight == 0 && j == end_i) { - pixel_weights.m_SrcEnd--; - break; - } - pixel_weights.m_Weights[j - start_i] = - FXSYS_round((FX_FLOAT)(weight * 65536)); - } - } -} -void CFXCODEC_HorzTable::Calc(int dest_len, int src_len, FX_BOOL bInterpol) { - if (m_pWeightTables) { - FX_Free(m_pWeightTables); - } - double scale = (double)dest_len / (double)src_len; - m_ItemSize = sizeof(int) * 4; - int size = dest_len * m_ItemSize + 4; - m_pWeightTables = FX_Alloc(uint8_t, size); - if (m_pWeightTables == NULL) { - return; - } - FXSYS_memset(m_pWeightTables, 0, size); - if (scale > 1) { - int pre_des_col = 0; - for (int src_col = 0; src_col < src_len; src_col++) { - double des_col_f = src_col * scale; - int des_col = FXSYS_round((FX_FLOAT)des_col_f); - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize); - pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - if (src_col == src_len - 1 && des_col < dest_len - 1) { - for (int des_col_index = pre_des_col + 1; des_col_index < dest_len; - des_col_index++) { - pWeight = - (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize); - pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - } - return; - } - int des_col_len = des_col - pre_des_col; - for (int des_col_index = pre_des_col + 1; des_col_index < des_col; - des_col_index++) { - pWeight = (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize); - pWeight->m_SrcStart = src_col - 1; - pWeight->m_SrcEnd = src_col; - pWeight->m_Weights[0] = - bInterpol ? FXSYS_round((FX_FLOAT)( - ((FX_FLOAT)des_col - (FX_FLOAT)des_col_index) / - (FX_FLOAT)des_col_len * 65536)) - : 65536; - pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; - } - pre_des_col = des_col; - } - return; - } - for (int des_col = 0; des_col < dest_len; des_col++) { - double src_col_f = des_col / scale; - int src_col = FXSYS_round((FX_FLOAT)src_col_f); - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize); - pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - } -} -void CFXCODEC_VertTable::Calc(int dest_len, int src_len) { - if (m_pWeightTables) { - FX_Free(m_pWeightTables); - } - double scale = (double)dest_len / (double)src_len; - m_ItemSize = sizeof(int) * 4; - int size = dest_len * m_ItemSize + 4; - m_pWeightTables = FX_Alloc(uint8_t, size); - if (m_pWeightTables == NULL) { - return; - } - FXSYS_memset(m_pWeightTables, 0, size); - if (scale > 1) { - double step = 0.0; - int src_row = 0; - while (step < (double)dest_len) { - int start_step = (int)step; - step = scale * (++src_row); - int end_step = (int)step; - if (end_step >= dest_len) { - end_step = dest_len; - for (int des_row = start_step; des_row < end_step; des_row++) { - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); - pWeight->m_SrcStart = start_step; - pWeight->m_SrcEnd = start_step; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - } - return; - } - int length = end_step - start_step; - { - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + start_step * m_ItemSize); - pWeight->m_SrcStart = start_step; - pWeight->m_SrcEnd = start_step; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - } - for (int des_row = start_step + 1; des_row < end_step; des_row++) { - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); - pWeight->m_SrcStart = start_step; - pWeight->m_SrcEnd = end_step; - pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) / - (FX_FLOAT)length * 65536); - pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; - } - } - } else { - for (int des_row = 0; des_row < dest_len; des_row++) { - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); - pWeight->m_SrcStart = des_row; - pWeight->m_SrcEnd = des_row; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - } - } -} -CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder( - CCodec_ModuleMgr* pCodecMgr) { - m_pFile = NULL; - m_pJpegContext = NULL; - m_pPngContext = NULL; - m_pGifContext = NULL; - m_pBmpContext = NULL; - m_pTiffContext = NULL; - m_pCodecMgr = NULL; - m_pSrcBuf = NULL; - m_pDecodeBuf = NULL; - m_pDeviceBitmap = NULL; - m_pSrcPalette = NULL; - m_pCodecMgr = pCodecMgr; - m_offSet = 0; - m_SrcSize = 0; - m_ScanlineSize = 0; - m_SrcWidth = m_SrcHeight = 0; - m_SrcComponents = 0; - m_SrcBPC = 0; - m_SrcPassNumber = 0; - m_clipBox = FX_RECT(0, 0, 0, 0); - m_imagType = FXCODEC_IMAGE_UNKNOWN; - m_status = FXCODEC_STATUS_DECODE_FINISH; - m_TransMethod = -1; - m_SrcRow = 0; - m_SrcFormat = FXCodec_Invalid; - m_bInterpol = TRUE; - m_FrameNumber = 0; - m_FrameCur = 0; - m_SrcPaletteNumber = 0; - m_GifPltNumber = 0; - m_GifBgIndex = 0; - m_pGifPalette = NULL; - m_GifTransIndex = -1; - m_GifFrameRect = FX_RECT(0, 0, 0, 0); - m_BmpIsTopBottom = FALSE; -} -CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() { - m_pFile = NULL; - if (m_pJpegContext != NULL) { - m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext); - } - if (m_pPngContext != NULL) { - m_pCodecMgr->GetPngModule()->Finish(m_pPngContext); - } - if (m_pGifContext != NULL) { - m_pCodecMgr->GetGifModule()->Finish(m_pGifContext); - } - if (m_pBmpContext != NULL) { - m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext); - } - if (m_pTiffContext != NULL) { - m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext); - } - if (m_pSrcBuf != NULL) { - FX_Free(m_pSrcBuf); - } - if (m_pDecodeBuf != NULL) { - FX_Free(m_pDecodeBuf); - } - if (m_pSrcPalette != NULL) { - FX_Free(m_pSrcPalette); - } -} -FX_BOOL CCodec_ProgressiveDecoder::JpegReadMoreData( - ICodec_JpegModule* pJpegModule, - FXCODEC_STATUS& err_status) { - FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); - if (dwSize <= m_offSet) { - return FALSE; - } - dwSize = dwSize - m_offSet; - FX_DWORD dwAvail = pJpegModule->GetAvailInput(m_pJpegContext, NULL); - if (dwAvail == m_SrcSize) { - if (dwSize > FXCODEC_BLOCK_SIZE) { - dwSize = FXCODEC_BLOCK_SIZE; - } - m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / - FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; - m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); - if (!m_pSrcBuf) { - err_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - } else { - FX_DWORD dwConsume = m_SrcSize - dwAvail; - if (dwAvail) { - FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); - } - if (dwSize > dwConsume) { - dwSize = dwConsume; - } - } - if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { - err_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += dwSize; - pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail); - return TRUE; -} -FX_BOOL CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, - int width, - int height, - int bpc, - int pass, - int* color_type, - double* gamma) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - if (pCodec->m_pDeviceBitmap == NULL) { - pCodec->m_SrcWidth = width; - pCodec->m_SrcHeight = height; - pCodec->m_SrcBPC = bpc; - pCodec->m_SrcPassNumber = pass; - pCodec->m_SrcComponents = - *color_type == 0 ? 1 : *color_type == 2 - ? 3 - : *color_type == 3 - ? 4 - : *color_type == 4 - ? 2 - : *color_type == 6 ? 4 : 0; - pCodec->m_clipBox = FX_RECT(0, 0, width, height); - return FALSE; - } - FXDIB_Format format = pCodec->m_pDeviceBitmap->GetFormat(); - switch (format) { - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - ASSERT(FALSE); - return FALSE; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: - *color_type = 0; - break; - case FXDIB_Rgb: - *color_type = 2; - break; - case FXDIB_Rgb32: - case FXDIB_Argb: - *color_type = 6; - break; - default: - ASSERT(FALSE); - return FALSE; - } - *gamma = FXCODEC_PNG_GAMMA; - return TRUE; -} -FX_BOOL CCodec_ProgressiveDecoder::PngAskScanlineBufFunc(void* pModule, - int line, - uint8_t*& src_buf) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; - ASSERT(pDIBitmap != NULL); - if (pDIBitmap == NULL) { - return FALSE; - } - if (line >= pCodec->m_clipBox.top && line < pCodec->m_clipBox.bottom) { - double scale_y = - (double)pCodec->m_sizeY / (double)pCodec->m_clipBox.Height(); - int32_t row = - (int32_t)((line - pCodec->m_clipBox.top) * scale_y) + pCodec->m_startY; - uint8_t* src_scan = (uint8_t*)pDIBitmap->GetScanline(row); - uint8_t* des_scan = pCodec->m_pDecodeBuf; - src_buf = pCodec->m_pDecodeBuf; - int32_t src_Bpp = pDIBitmap->GetBPP() >> 3; - int32_t des_Bpp = (pCodec->m_SrcFormat & 0xff) >> 3; - int32_t src_left = pCodec->m_startX; - int32_t des_left = pCodec->m_clipBox.left; - src_scan += src_left * src_Bpp; - des_scan += des_left * des_Bpp; - for (int32_t src_col = 0; src_col < pCodec->m_sizeX; src_col++) { - PixelWeight* pPixelWeights = - pCodec->m_WeightHorzOO.GetPixelWeight(src_col); - if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) { - continue; - } - switch (pDIBitmap->GetFormat()) { - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - ASSERT(FALSE); - return FALSE; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - if (pDIBitmap->GetPalette() != NULL) { - return FALSE; - } - FX_DWORD des_g = 0; - des_g += pPixelWeights->m_Weights[0] * src_scan[src_col]; - des_scan[pPixelWeights->m_SrcStart] = (uint8_t)(des_g >> 16); - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - const uint8_t* p = src_scan + src_col * src_Bpp; - des_b += pPixelWeights->m_Weights[0] * (*p++); - des_g += pPixelWeights->m_Weights[0] * (*p++); - des_r += pPixelWeights->m_Weights[0] * (*p); - uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; - *pDes++ = (uint8_t)((des_b) >> 16); - *pDes++ = (uint8_t)((des_g) >> 16); - *pDes = (uint8_t)((des_r) >> 16); - } break; - case FXDIB_Argb: { - FX_DWORD des_r = 0, des_g = 0, des_b = 0; - const uint8_t* p = src_scan + src_col * src_Bpp; - des_b += pPixelWeights->m_Weights[0] * (*p++); - des_g += pPixelWeights->m_Weights[0] * (*p++); - des_r += pPixelWeights->m_Weights[0] * (*p++); - uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; - *pDes++ = (uint8_t)((des_b) >> 16); - *pDes++ = (uint8_t)((des_g) >> 16); - *pDes++ = (uint8_t)((des_r) >> 16); - *pDes = *p; - } break; - default: - return FALSE; - } - } - } - return TRUE; -} -void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz( - CFX_DIBitmap* pDeviceBitmap, - int32_t des_line, - uint8_t* src_scan, - FXCodec_Format src_format) { - uint8_t* des_scan = (uint8_t*)pDeviceBitmap->GetScanline(des_line); - int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3; - int32_t des_Bpp = pDeviceBitmap->GetBPP() >> 3; - int32_t src_left = m_clipBox.left; - int32_t des_left = m_startX; - src_scan += src_left * src_Bpp; - des_scan += des_left * des_Bpp; - for (int32_t des_col = 0; des_col < m_sizeX; des_col++) { - PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(des_col); - switch (pDeviceBitmap->GetFormat()) { - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - ASSERT(FALSE); - return; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - if (pDeviceBitmap->GetPalette() != NULL) { - return; - } - FX_DWORD des_g = 0; - des_g += - pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart]; - des_g += - pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd]; - *des_scan++ = (uint8_t)(des_g >> 16); - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - const uint8_t* p = src_scan; - p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; - des_b += pPixelWeights->m_Weights[0] * (*p++); - des_g += pPixelWeights->m_Weights[0] * (*p++); - des_r += pPixelWeights->m_Weights[0] * (*p); - p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; - des_b += pPixelWeights->m_Weights[1] * (*p++); - des_g += pPixelWeights->m_Weights[1] * (*p++); - des_r += pPixelWeights->m_Weights[1] * (*p); - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - des_scan += des_Bpp - 3; - } break; - case FXDIB_Argb: { - FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; - const uint8_t* p = src_scan; - p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; - des_b += pPixelWeights->m_Weights[0] * (*p++); - des_g += pPixelWeights->m_Weights[0] * (*p++); - des_r += pPixelWeights->m_Weights[0] * (*p++); - des_a += pPixelWeights->m_Weights[0] * (*p); - p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; - des_b += pPixelWeights->m_Weights[1] * (*p++); - des_g += pPixelWeights->m_Weights[1] * (*p++); - des_r += pPixelWeights->m_Weights[1] * (*p++); - des_a += pPixelWeights->m_Weights[1] * (*p); - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - *des_scan++ = (uint8_t)((des_a) >> 16); - } break; - default: - return; - } - } -} -void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, - int pass, - int line) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; - ASSERT(pDIBitmap != NULL); - int src_top = pCodec->m_clipBox.top; - int src_bottom = pCodec->m_clipBox.bottom; - int des_top = pCodec->m_startY; - int src_hei = pCodec->m_clipBox.Height(); - int des_hei = pCodec->m_sizeY; - if (line >= src_top && line < src_bottom) { - double scale_y = (double)des_hei / (double)src_hei; - int src_row = line - src_top; - int des_row = (int)(src_row * scale_y) + des_top; - if (des_row >= des_top + des_hei) { - return; - } - pCodec->PngOneOneMapResampleHorz(pDIBitmap, des_row, pCodec->m_pDecodeBuf, - pCodec->m_SrcFormat); - if (pCodec->m_SrcPassNumber == 1 && scale_y > 1.0) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); - return; - } - if (pass == 6 && scale_y > 1.0) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); - } - } -} -FX_BOOL CCodec_ProgressiveDecoder::GifReadMoreData(ICodec_GifModule* pGifModule, - FXCODEC_STATUS& err_status) { - FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); - if (dwSize <= m_offSet) { - return FALSE; - } - dwSize = dwSize - m_offSet; - FX_DWORD dwAvail = pGifModule->GetAvailInput(m_pGifContext, NULL); - if (dwAvail == m_SrcSize) { - if (dwSize > FXCODEC_BLOCK_SIZE) { - dwSize = FXCODEC_BLOCK_SIZE; - } - m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / - FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; - m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); - if (!m_pSrcBuf) { - err_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - } else { - FX_DWORD dwConsume = m_SrcSize - dwAvail; - if (dwAvail) { - FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); - } - if (dwSize > dwConsume) { - dwSize = dwConsume; - } - } - if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { - err_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += dwSize; - pGifModule->Input(m_pGifContext, m_pSrcBuf, dwSize + dwAvail); - return TRUE; -} -void CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback( - void* pModule, - FX_DWORD& cur_pos) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - FX_DWORD remain_size = - pCodec->m_pCodecMgr->GetGifModule()->GetAvailInput(pCodec->m_pGifContext); - cur_pos = pCodec->m_offSet - remain_size; -} -uint8_t* CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback( - void* pModule, - int32_t frame_num, - int32_t pal_size) { - return FX_Alloc(uint8_t, pal_size); -} -FX_BOOL CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback( - void* pModule, - FX_DWORD rcd_pos, - const FX_RECT& img_rc, - int32_t pal_num, - void* pal_ptr, - int32_t delay_time, - FX_BOOL user_input, - int32_t trans_index, - int32_t disposal_method, - FX_BOOL interlace) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - pCodec->m_offSet = rcd_pos; - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; - if (!pCodec->GifReadMoreData(pCodec->m_pCodecMgr->GetGifModule(), - error_status)) { - return FALSE; - } - uint8_t* pPalette = NULL; - if (pal_num != 0 && pal_ptr) { - pPalette = (uint8_t*)pal_ptr; - } else { - pal_num = pCodec->m_GifPltNumber; - pPalette = pCodec->m_pGifPalette; - } - if (pCodec->m_pSrcPalette == NULL) { - pCodec->m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num); - } else if (pal_num > pCodec->m_SrcPaletteNumber) { - pCodec->m_pSrcPalette = FX_Realloc(FX_ARGB, pCodec->m_pSrcPalette, pal_num); - } - if (pCodec->m_pSrcPalette == NULL) { - return FALSE; - } - pCodec->m_SrcPaletteNumber = pal_num; - for (int i = 0; i < pal_num; i++) { - FX_DWORD j = i * 3; - pCodec->m_pSrcPalette[i] = - ArgbEncode(0xff, pPalette[j], pPalette[j + 1], pPalette[j + 2]); - } - pCodec->m_GifTransIndex = trans_index; - pCodec->m_GifFrameRect = img_rc; - pCodec->m_SrcPassNumber = interlace ? 4 : 1; - int32_t pal_index = pCodec->m_GifBgIndex; - CFX_DIBitmap* pDevice = pCodec->m_pDeviceBitmap; - if (trans_index >= pal_num) { - trans_index = -1; - } - if (trans_index != -1) { - pCodec->m_pSrcPalette[trans_index] &= 0x00ffffff; - if (pDevice->HasAlpha()) { - pal_index = trans_index; - } - } - int startX = pCodec->m_startX; - int startY = pCodec->m_startY; - int sizeX = pCodec->m_sizeX; - int sizeY = pCodec->m_sizeY; - int Bpp = pDevice->GetBPP() / 8; - FX_ARGB argb = pCodec->m_pSrcPalette[pal_index]; - for (int row = 0; row < sizeY; row++) { - uint8_t* pScanline = - (uint8_t*)pDevice->GetScanline(row + startY) + startX * Bpp; - switch (pCodec->m_TransMethod) { - case 3: { - uint8_t gray = - FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); - FXSYS_memset(pScanline, gray, sizeX); - break; - } - case 8: { - for (int col = 0; col < sizeX; col++) { - *pScanline++ = FXARGB_B(argb); - *pScanline++ = FXARGB_G(argb); - *pScanline++ = FXARGB_R(argb); - pScanline += Bpp - 3; - } - break; - } - case 12: { - for (int col = 0; col < sizeX; col++) { - FXARGB_SETDIB(pScanline, argb); - pScanline += 4; - } - break; - } - } - } - return TRUE; -} -void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; - ASSERT(pDIBitmap != NULL); - int32_t img_width = pCodec->m_GifFrameRect.Width(); - if (!pDIBitmap->HasAlpha()) { - uint8_t* byte_ptr = row_buf; - for (int i = 0; i < img_width; i++) { - if (*byte_ptr == pCodec->m_GifTransIndex) { - *byte_ptr = pCodec->m_GifBgIndex; - } - byte_ptr++; - } - } - int32_t pal_index = pCodec->m_GifBgIndex; - if (pCodec->m_GifTransIndex != -1 && pCodec->m_pDeviceBitmap->HasAlpha()) { - pal_index = pCodec->m_GifTransIndex; - } - FXSYS_memset(pCodec->m_pDecodeBuf, pal_index, pCodec->m_SrcWidth); - FX_BOOL bLastPass = (row_num % 2) == 1; - int32_t line = row_num + pCodec->m_GifFrameRect.top; - int32_t left = pCodec->m_GifFrameRect.left; - FXSYS_memcpy(pCodec->m_pDecodeBuf + left, row_buf, img_width); - int src_top = pCodec->m_clipBox.top; - int src_bottom = pCodec->m_clipBox.bottom; - int des_top = pCodec->m_startY; - int src_hei = pCodec->m_clipBox.Height(); - int des_hei = pCodec->m_sizeY; - if (line >= src_top && line < src_bottom) { - double scale_y = (double)des_hei / (double)src_hei; - int src_row = line - src_top; - int des_row = (int)(src_row * scale_y) + des_top; - if (des_row >= des_top + des_hei) { - return; - } - pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, - pCodec->m_SrcFormat); - if (scale_y > 1.0 && - (!pCodec->m_bInterpol || pCodec->m_SrcPassNumber == 1)) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); - return; - } - if (scale_y > 1.0) { - int des_bottom = des_top + pCodec->m_sizeY; - int des_Bpp = pDIBitmap->GetBPP() >> 3; - FX_DWORD des_ScanOffet = pCodec->m_startX * des_Bpp; - if (des_row + (int)scale_y >= des_bottom - 1) { - uint8_t* scan_src = - (uint8_t*)pDIBitmap->GetScanline(des_row) + des_ScanOffet; - int cur_row = des_row; - while (++cur_row < des_bottom) { - uint8_t* scan_des = - (uint8_t*)pDIBitmap->GetScanline(cur_row) + des_ScanOffet; - FX_DWORD size = pCodec->m_sizeX * des_Bpp; - FXSYS_memcpy(scan_des, scan_src, size); - } - } - if (bLastPass) { - pCodec->GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row); - } - } - } -} -void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert( - CFX_DIBitmap* pDeviceBitmap, - double scale_y, - int des_row) { - int des_Bpp = pDeviceBitmap->GetBPP() >> 3; - FX_DWORD des_ScanOffet = m_startX * des_Bpp; - int des_top = m_startY; - int des_row_1 = des_row - int(2 * scale_y); - if (des_row_1 < des_top) { - des_row_1 = des_top; - } - for (; des_row_1 < des_row; des_row_1++) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; - PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); - const uint8_t* scan_src1 = - pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + - des_ScanOffet; - const uint8_t* scan_src2 = - pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; - for (int des_col = 0; des_col < m_sizeX; des_col++) { - switch (pDeviceBitmap->GetFormat()) { - case FXDIB_Invalid: - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - return; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - if (pDeviceBitmap->GetPalette() != NULL) { - return; - } - int des_g = 0; - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)(des_g >> 16); - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - scan_src1 += des_Bpp - 3; - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - scan_src2 += des_Bpp - 3; - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - scan_des += des_Bpp - 3; - } break; - case FXDIB_Argb: { - FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - des_a += pWeight->m_Weights[0] * (*scan_src1++); - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - des_a += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - *scan_des++ = (uint8_t)((des_a) >> 16); - } break; - default: - return; - } - } - } - int des_bottom = des_top + m_sizeY - 1; - if (des_row + (int)(2 * scale_y) >= des_bottom && - des_row + (int)scale_y < des_bottom) { - GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y); - } -} -FX_BOOL CCodec_ProgressiveDecoder::BmpReadMoreData(ICodec_BmpModule* pBmpModule, - FXCODEC_STATUS& err_status) { - FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); - if (dwSize <= m_offSet) { - return FALSE; - } - dwSize = dwSize - m_offSet; - FX_DWORD dwAvail = pBmpModule->GetAvailInput(m_pBmpContext, NULL); - if (dwAvail == m_SrcSize) { - if (dwSize > FXCODEC_BLOCK_SIZE) { - dwSize = FXCODEC_BLOCK_SIZE; - } - m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / - FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; - m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); - if (!m_pSrcBuf) { - err_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - } else { - FX_DWORD dwConsume = m_SrcSize - dwAvail; - if (dwAvail) { - FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); - } - if (dwSize > dwConsume) { - dwSize = dwConsume; - } - } - if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { - err_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += dwSize; - pBmpModule->Input(m_pBmpContext, m_pSrcBuf, dwSize + dwAvail); - return TRUE; -} -FX_BOOL CCodec_ProgressiveDecoder::BmpInputImagePositionBufCallback( - void* pModule, - FX_DWORD rcd_pos) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - pCodec->m_offSet = rcd_pos; - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; - if (!pCodec->BmpReadMoreData(pCodec->m_pCodecMgr->GetBmpModule(), - error_status)) { - return FALSE; - } - return TRUE; -} -void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; - ASSERT(pDIBitmap != NULL); - FXSYS_memcpy(pCodec->m_pDecodeBuf, row_buf, pCodec->m_ScanlineSize); - int src_top = pCodec->m_clipBox.top; - int src_bottom = pCodec->m_clipBox.bottom; - int des_top = pCodec->m_startY; - int src_hei = pCodec->m_clipBox.Height(); - int des_hei = pCodec->m_sizeY; - if (row_num >= src_top && row_num < src_bottom) { - double scale_y = (double)des_hei / (double)src_hei; - int src_row = row_num - src_top; - int des_row = (int)(src_row * scale_y) + des_top; - if (des_row >= des_top + des_hei) { - return; - } - pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, - pCodec->m_SrcFormat); - if (scale_y > 1.0) { - if (pCodec->m_BmpIsTopBottom || !pCodec->m_bInterpol) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); - return; - } else { - pCodec->ResampleVertBT(pDIBitmap, scale_y, des_row); - } - } - } -} -void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, - double scale_y, - int des_row) { - int des_Bpp = pDeviceBitmap->GetBPP() >> 3; - FX_DWORD des_ScanOffet = m_startX * des_Bpp; - int des_top = m_startY; - int des_bottom = m_startY + m_sizeY; - int des_row_1 = des_row + int(scale_y); - if (des_row_1 >= des_bottom - 1) { - uint8_t* scan_src = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - while (++des_row < des_bottom) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - FX_DWORD size = m_sizeX * des_Bpp; - FXSYS_memcpy(scan_des, scan_src, size); - } - return; - } - for (; des_row_1 > des_row; des_row_1--) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; - PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); - const uint8_t* scan_src1 = - pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + - des_ScanOffet; - const uint8_t* scan_src2 = - pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; - for (int des_col = 0; des_col < m_sizeX; des_col++) { - switch (pDeviceBitmap->GetFormat()) { - case FXDIB_Invalid: - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - return; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - if (pDeviceBitmap->GetPalette() != NULL) { - return; - } - int des_g = 0; - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)(des_g >> 16); - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - scan_src1 += des_Bpp - 3; - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - scan_src2 += des_Bpp - 3; - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - scan_des += des_Bpp - 3; - } break; - case FXDIB_Argb: { - FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - des_a += pWeight->m_Weights[0] * (*scan_src1++); - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - des_a += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - *scan_des++ = (uint8_t)((des_a) >> 16); - } break; - default: - return; - } - } - } -} -FX_BOOL CCodec_ProgressiveDecoder::DetectImageType( - FXCODEC_IMAGE_TYPE imageType, - CFX_DIBAttribute* pAttribute) { - m_offSet = 0; - FX_DWORD size = (FX_DWORD)m_pFile->GetSize(); - if (size > FXCODEC_BLOCK_SIZE) { - size = FXCODEC_BLOCK_SIZE; - } - if (m_pSrcBuf != NULL) { - FX_Free(m_pSrcBuf); - m_pSrcBuf = NULL; - } - m_pSrcBuf = FX_Alloc(uint8_t, size); - if (m_pSrcBuf == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FXSYS_memset(m_pSrcBuf, 0, size); - m_SrcSize = size; - switch (imageType) { - case FXCODEC_IMAGE_BMP: { - ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); - if (pBmpModule == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - pBmpModule->InputImagePositionBufCallback = - BmpInputImagePositionBufCallback; - pBmpModule->ReadScanlineCallback = BmpReadScanlineCallback; - m_pBmpContext = pBmpModule->Start((void*)this); - if (m_pBmpContext == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); - if (!bResult) { - m_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += size; - pBmpModule->Input(m_pBmpContext, m_pSrcBuf, size); - FX_DWORD* pPalette = NULL; - int32_t readResult = pBmpModule->ReadHeader( - m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, - &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); - while (readResult == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; - if (!BmpReadMoreData(pBmpModule, error_status)) { - m_status = error_status; - return FALSE; - } - readResult = pBmpModule->ReadHeader( - m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, - &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); - } - if (readResult == 1) { - m_SrcBPC = 8; - m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); - if (m_pSrcPalette != NULL) { - FX_Free(m_pSrcPalette); - m_pSrcPalette = NULL; - } - if (m_SrcPaletteNumber) { - m_pSrcPalette = FX_Alloc(FX_ARGB, m_SrcPaletteNumber); - if (m_pSrcPalette == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FXSYS_memcpy(m_pSrcPalette, pPalette, - m_SrcPaletteNumber * sizeof(FX_DWORD)); - } - return TRUE; - } - if (m_pBmpContext != NULL) { - pBmpModule->Finish(m_pBmpContext); - m_pBmpContext = NULL; - } - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } break; - case FXCODEC_IMAGE_JPG: { - ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); - if (pJpegModule == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - m_pJpegContext = pJpegModule->Start(); - if (m_pJpegContext == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); - if (!bResult) { - m_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += size; - pJpegModule->Input(m_pJpegContext, m_pSrcBuf, size); - int32_t readResult = - pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, - &m_SrcComponents, pAttribute); - while (readResult == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; - if (!JpegReadMoreData(pJpegModule, error_status)) { - m_status = error_status; - return FALSE; - } - readResult = - pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, - &m_SrcComponents, pAttribute); - } - if (!readResult) { - m_SrcBPC = 8; - m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); - return TRUE; - } - if (m_pJpegContext != NULL) { - pJpegModule->Finish(m_pJpegContext); - m_pJpegContext = NULL; - } - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } break; - case FXCODEC_IMAGE_PNG: { - ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); - if (pPngModule == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - pPngModule->ReadHeaderCallback = - CCodec_ProgressiveDecoder::PngReadHeaderFunc; - pPngModule->AskScanlineBufCallback = - CCodec_ProgressiveDecoder::PngAskScanlineBufFunc; - pPngModule->FillScanlineBufCompletedCallback = - CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc; - m_pPngContext = pPngModule->Start((void*)this); - if (m_pPngContext == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); - if (!bResult) { - m_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += size; - bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, size, pAttribute); - while (bResult) { - FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; - FX_DWORD input_size = - remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; - if (input_size == 0) { - if (m_pPngContext != NULL) { - pPngModule->Finish(m_pPngContext); - } - m_pPngContext = NULL; - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } - if (m_pSrcBuf != NULL && input_size > m_SrcSize) { - FX_Free(m_pSrcBuf); - m_pSrcBuf = FX_Alloc(uint8_t, input_size); - if (m_pSrcBuf == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FXSYS_memset(m_pSrcBuf, 0, input_size); - m_SrcSize = input_size; - } - bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); - if (!bResult) { - m_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += input_size; - bResult = - pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, pAttribute); - } - ASSERT(!bResult); - if (m_pPngContext != NULL) { - pPngModule->Finish(m_pPngContext); - m_pPngContext = NULL; - } - if (m_SrcPassNumber == 0) { - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } - } break; - case FXCODEC_IMAGE_GIF: { - ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); - if (pGifModule == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - pGifModule->RecordCurrentPositionCallback = - CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback; - pGifModule->AskLocalPaletteBufCallback = - CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback; - pGifModule->InputRecordPositionBufCallback = - CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback; - pGifModule->ReadScanlineCallback = - CCodec_ProgressiveDecoder::GifReadScanlineCallback; - m_pGifContext = pGifModule->Start((void*)this); - if (m_pGifContext == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); - if (!bResult) { - m_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += size; - pGifModule->Input(m_pGifContext, m_pSrcBuf, size); - m_SrcComponents = 1; - int32_t readResult = pGifModule->ReadHeader( - m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, - (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); - while (readResult == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; - if (!GifReadMoreData(pGifModule, error_status)) { - m_status = error_status; - return FALSE; - } - readResult = pGifModule->ReadHeader( - m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, - (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); - } - if (readResult == 1) { - m_SrcBPC = 8; - m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); - return TRUE; - } - if (m_pGifContext != NULL) { - pGifModule->Finish(m_pGifContext); - m_pGifContext = NULL; - } - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } break; - case FXCODEC_IMAGE_TIF: { - ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); - if (pTiffModule == NULL) { - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } - m_pTiffContext = pTiffModule->CreateDecoder(m_pFile); - if (m_pTiffContext == NULL) { - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } - int32_t frames = 0; - pTiffModule->GetFrames(m_pTiffContext, frames); - FX_DWORD bpc; - FX_BOOL ret = pTiffModule->LoadFrameInfo( - m_pTiffContext, 0, (FX_DWORD&)m_SrcWidth, (FX_DWORD&)m_SrcHeight, - (FX_DWORD&)m_SrcComponents, bpc, pAttribute); - m_SrcComponents = 4; - m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); - if (!ret) { - pTiffModule->DestroyDecoder(m_pTiffContext); - (m_pTiffContext = NULL); - (m_status = FXCODEC_STATUS_ERR_FORMAT); - return FALSE; - } - } break; - default: - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } - return TRUE; -} -FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo( - IFX_FileRead* pFile, - FXCODEC_IMAGE_TYPE imageType, - CFX_DIBAttribute* pAttribute) { - switch (m_status) { - case FXCODEC_STATUS_FRAME_READY: - case FXCODEC_STATUS_FRAME_TOBECONTINUE: - case FXCODEC_STATUS_DECODE_READY: - case FXCODEC_STATUS_DECODE_TOBECONTINUE: - return FXCODEC_STATUS_ERROR; - default:; - } - if (pFile == NULL) { - m_status = FXCODEC_STATUS_ERR_PARAMS; - m_pFile = NULL; - return m_status; - } - m_pFile = pFile; - m_offSet = 0; - m_SrcWidth = m_SrcHeight = 0; - m_SrcComponents = m_SrcBPC = 0; - m_clipBox = FX_RECT(0, 0, 0, 0); - m_startX = m_startY = 0; - m_sizeX = m_sizeY = 0; - m_SrcPassNumber = 0; - if (imageType != FXCODEC_IMAGE_UNKNOWN && - DetectImageType(imageType, pAttribute)) { - m_imagType = imageType; - m_status = FXCODEC_STATUS_FRAME_READY; - return m_status; - } - for (int type = FXCODEC_IMAGE_BMP; type < FXCODEC_IMAGE_MAX; type++) { - if (DetectImageType((FXCODEC_IMAGE_TYPE)type, pAttribute)) { - m_imagType = (FXCODEC_IMAGE_TYPE)type; - m_status = FXCODEC_STATUS_FRAME_READY; - return m_status; - } - } - m_status = FXCODEC_STATUS_ERR_FORMAT; - m_pFile = NULL; - return m_status; -} -void CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip) { - if (m_status != FXCODEC_STATUS_FRAME_READY) { - return; - } - if (clip->IsEmpty()) { - m_clipBox = FX_RECT(0, 0, 0, 0); - return; - } - if (clip->left < 0) { - clip->left = 0; - } - if (clip->right > m_SrcWidth) { - clip->right = m_SrcWidth; - } - if (clip->top < 0) { - clip->top = 0; - } - if (clip->bottom > m_SrcHeight) { - clip->bottom = m_SrcHeight; - } - if (clip->IsEmpty()) { - m_clipBox = FX_RECT(0, 0, 0, 0); - return; - } - m_clipBox = *clip; -} -void CCodec_ProgressiveDecoder::GetDownScale(int& down_scale) { - down_scale = 1; - int ratio_w = m_clipBox.Width() / m_sizeX; - int ratio_h = m_clipBox.Height() / m_sizeY; - int ratio = (ratio_w > ratio_h) ? ratio_h : ratio_w; - if (ratio >= 8) { - down_scale = 8; - } else if (ratio >= 4) { - down_scale = 4; - } else if (ratio >= 2) { - down_scale = 2; - } - m_clipBox.left /= down_scale; - m_clipBox.right /= down_scale; - m_clipBox.top /= down_scale; - m_clipBox.bottom /= down_scale; - if (m_clipBox.right == m_clipBox.left) { - m_clipBox.right = m_clipBox.left + 1; - } - if (m_clipBox.bottom == m_clipBox.top) { - m_clipBox.bottom = m_clipBox.top + 1; - } -} -void CCodec_ProgressiveDecoder::GetTransMethod(FXDIB_Format des_format, - FXCodec_Format src_format) { - switch (des_format) { - case FXDIB_1bppMask: - case FXDIB_1bppRgb: { - switch (src_format) { - case FXCodec_1bppGray: - m_TransMethod = 0; - break; - default: - m_TransMethod = -1; - } - } break; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - switch (src_format) { - case FXCodec_1bppGray: - m_TransMethod = 1; - break; - case FXCodec_8bppGray: - m_TransMethod = 2; - break; - case FXCodec_1bppRgb: - case FXCodec_8bppRgb: - m_TransMethod = 3; - break; - case FXCodec_Rgb: - case FXCodec_Rgb32: - case FXCodec_Argb: - m_TransMethod = 4; - break; - case FXCodec_Cmyk: - m_TransMethod = 5; - break; - default: - m_TransMethod = -1; - } - } break; - case FXDIB_Rgb: { - switch (src_format) { - case FXCodec_1bppGray: - m_TransMethod = 6; - break; - case FXCodec_8bppGray: - m_TransMethod = 7; - break; - case FXCodec_1bppRgb: - case FXCodec_8bppRgb: - m_TransMethod = 8; - break; - case FXCodec_Rgb: - case FXCodec_Rgb32: - case FXCodec_Argb: - m_TransMethod = 9; - break; - case FXCodec_Cmyk: - m_TransMethod = 10; - break; - default: - m_TransMethod = -1; - } - } break; - case FXDIB_Rgb32: - case FXDIB_Argb: { - switch (src_format) { - case FXCodec_1bppGray: - m_TransMethod = 6; - break; - case FXCodec_8bppGray: - m_TransMethod = 7; - break; - case FXCodec_1bppRgb: - case FXCodec_8bppRgb: - if (des_format == FXDIB_Argb) { - m_TransMethod = 12; - } else { - m_TransMethod = 8; - } - break; - case FXCodec_Rgb: - case FXCodec_Rgb32: - m_TransMethod = 9; - break; - case FXCodec_Cmyk: - m_TransMethod = 10; - break; - case FXCodec_Argb: - m_TransMethod = 11; - break; - default: - m_TransMethod = -1; - } - } break; - default: - m_TransMethod = -1; - } -} -void _RGB2BGR(uint8_t* buffer, int width = 1) { - if (buffer && width > 0) { - uint8_t temp; - int i = 0; - int j = 0; - for (; i < width; i++, j += 3) { - temp = buffer[j]; - buffer[j] = buffer[j + 2]; - buffer[j + 2] = temp; - } - } -} -void CCodec_ProgressiveDecoder::ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, - int des_line, - uint8_t* src_scan, - FXCodec_Format src_format) { - int src_left = m_clipBox.left; - int des_left = m_startX; - uint8_t* des_scan = - pDeviceBitmap->GetBuffer() + des_line * pDeviceBitmap->GetPitch(); - int src_bpp = src_format & 0xff; - int des_bpp = pDeviceBitmap->GetBPP(); - int src_Bpp = src_bpp >> 3; - int des_Bpp = des_bpp >> 3; - src_scan += src_left * src_Bpp; - des_scan += des_left * des_Bpp; - for (int des_col = 0; des_col < m_sizeX; des_col++) { - PixelWeight* pPixelWeights = m_WeightHorz.GetPixelWeight(des_col); - switch (m_TransMethod) { - case -1: - return; - case 0: - return; - case 1: - return; - case 2: { - FX_DWORD des_g = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - des_g += pixel_weight * src_scan[j]; - } - *des_scan++ = (uint8_t)(des_g >> 16); - } break; - case 3: { - int des_r = 0, des_g = 0, des_b = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - unsigned long argb = m_pSrcPalette[src_scan[j]]; - des_r += pixel_weight * (uint8_t)(argb >> 16); - des_g += pixel_weight * (uint8_t)(argb >> 8); - des_b += pixel_weight * (uint8_t)argb; - } - *des_scan++ = - (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); - } break; - case 4: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * src_Bpp; - des_b += pixel_weight * (*src_pixel++); - des_g += pixel_weight * (*src_pixel++); - des_r += pixel_weight * (*src_pixel); - } - *des_scan++ = - (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); - } break; - case 5: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * src_Bpp; - uint8_t src_b = 0, src_g = 0, src_r = 0; - AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], - 255 - src_pixel[2], 255 - src_pixel[3], src_r, - src_g, src_b); - des_b += pixel_weight * src_b; - des_g += pixel_weight * src_g; - des_r += pixel_weight * src_r; - } - *des_scan++ = - (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); - } break; - case 6: - return; - case 7: { - FX_DWORD des_g = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - des_g += pixel_weight * src_scan[j]; - } - FXSYS_memset(des_scan, (uint8_t)(des_g >> 16), 3); - des_scan += des_Bpp; - } break; - case 8: { - int des_r = 0, des_g = 0, des_b = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - unsigned long argb = m_pSrcPalette[src_scan[j]]; - des_r += pixel_weight * (uint8_t)(argb >> 16); - des_g += pixel_weight * (uint8_t)(argb >> 8); - des_b += pixel_weight * (uint8_t)argb; - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - des_scan += des_Bpp - 3; - } break; - case 12: { - if (m_pBmpContext) { - int des_r = 0, des_g = 0, des_b = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - unsigned long argb = m_pSrcPalette[src_scan[j]]; - des_r += pixel_weight * (uint8_t)(argb >> 16); - des_g += pixel_weight * (uint8_t)(argb >> 8); - des_b += pixel_weight * (uint8_t)argb; - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - *des_scan++ = 0xFF; - } else { - int des_a = 0, des_r = 0, des_g = 0, des_b = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - unsigned long argb = m_pSrcPalette[src_scan[j]]; - des_a += pixel_weight * (uint8_t)(argb >> 24); - des_r += pixel_weight * (uint8_t)(argb >> 16); - des_g += pixel_weight * (uint8_t)(argb >> 8); - des_b += pixel_weight * (uint8_t)argb; - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - *des_scan++ = (uint8_t)((des_a) >> 16); - } - } break; - case 9: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * src_Bpp; - des_b += pixel_weight * (*src_pixel++); - des_g += pixel_weight * (*src_pixel++); - des_r += pixel_weight * (*src_pixel); - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - des_scan += des_Bpp - 3; - } break; - case 10: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * src_Bpp; - uint8_t src_b = 0, src_g = 0, src_r = 0; - AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], - 255 - src_pixel[2], 255 - src_pixel[3], src_r, - src_g, src_b); - des_b += pixel_weight * src_b; - des_g += pixel_weight * src_g; - des_r += pixel_weight * src_r; - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - des_scan += des_Bpp - 3; - } break; - case 11: { - FX_DWORD des_alpha = 0, des_r = 0, des_g = 0, des_b = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * src_Bpp; - pixel_weight = pixel_weight * src_pixel[3] / 255; - des_b += pixel_weight * (*src_pixel++); - des_g += pixel_weight * (*src_pixel++); - des_r += pixel_weight * (*src_pixel); - des_alpha += pixel_weight; - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - *des_scan++ = (uint8_t)((des_alpha * 255) >> 16); - } break; - default: - return; - } - } -} -void CCodec_ProgressiveDecoder::ResampleVert(CFX_DIBitmap* pDeviceBitmap, - double scale_y, - int des_row) { - int des_Bpp = pDeviceBitmap->GetBPP() >> 3; - FX_DWORD des_ScanOffet = m_startX * des_Bpp; - if (m_bInterpol) { - int des_top = m_startY; - int des_row_1 = des_row - int(scale_y); - if (des_row_1 < des_top) { - int des_bottom = des_top + m_sizeY; - if (des_row + (int)scale_y >= des_bottom - 1) { - uint8_t* scan_src = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - while (++des_row < des_bottom) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - FX_DWORD size = m_sizeX * des_Bpp; - FXSYS_memcpy(scan_des, scan_src, size); - } - } - return; - } - for (; des_row_1 < des_row; des_row_1++) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; - PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); - const uint8_t* scan_src1 = - pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + - des_ScanOffet; - const uint8_t* scan_src2 = - pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + - des_ScanOffet; - for (int des_col = 0; des_col < m_sizeX; des_col++) { - switch (pDeviceBitmap->GetFormat()) { - case FXDIB_Invalid: - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - return; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - if (pDeviceBitmap->GetPalette() != NULL) { - return; - } - int des_g = 0; - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)(des_g >> 16); - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - scan_src1 += des_Bpp - 3; - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - scan_src2 += des_Bpp - 3; - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - scan_des += des_Bpp - 3; - } break; - case FXDIB_Argb: { - FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - des_a += pWeight->m_Weights[0] * (*scan_src1++); - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - des_a += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - *scan_des++ = (uint8_t)((des_a) >> 16); - } break; - default: - return; - } - } - } - int des_bottom = des_top + m_sizeY; - if (des_row + (int)scale_y >= des_bottom - 1) { - uint8_t* scan_src = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - while (++des_row < des_bottom) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - FX_DWORD size = m_sizeX * des_Bpp; - FXSYS_memcpy(scan_des, scan_src, size); - } - } - return; - } - int multiple = (int)FXSYS_ceil((FX_FLOAT)scale_y - 1); - if (multiple > 0) { - uint8_t* scan_src = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - for (int i = 1; i <= multiple; i++) { - if (des_row + i >= m_startY + m_sizeY) { - return; - } - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row + i) + des_ScanOffet; - FX_DWORD size = m_sizeX * des_Bpp; - FXSYS_memcpy(scan_des, scan_src, size); - } - } -} -void CCodec_ProgressiveDecoder::Resample(CFX_DIBitmap* pDeviceBitmap, - int32_t src_line, - uint8_t* src_scan, - FXCodec_Format src_format) { - int src_top = m_clipBox.top; - int des_top = m_startY; - int src_hei = m_clipBox.Height(); - int des_hei = m_sizeY; - if (src_line >= src_top) { - double scale_y = (double)des_hei / (double)src_hei; - int src_row = src_line - src_top; - int des_row = (int)(src_row * scale_y) + des_top; - if (des_row >= des_top + des_hei) { - return; - } - ReSampleScanline(pDeviceBitmap, des_row, m_pDecodeBuf, src_format); - if (scale_y > 1.0) { - ResampleVert(pDeviceBitmap, scale_y, des_row); - } - } -} -FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames, - IFX_Pause* pPause) { - if (!(m_status == FXCODEC_STATUS_FRAME_READY || - m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) { - return FXCODEC_STATUS_ERROR; - } - switch (m_imagType) { - case FXCODEC_IMAGE_BMP: - case FXCODEC_IMAGE_JPG: - case FXCODEC_IMAGE_PNG: - case FXCODEC_IMAGE_TIF: - frames = m_FrameNumber = 1; - return m_status = FXCODEC_STATUS_DECODE_READY; - case FXCODEC_IMAGE_GIF: { - ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); - while (TRUE) { - int32_t readResult = - pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); - while (readResult == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ; - if (!GifReadMoreData(pGifModule, error_status)) { - return error_status; - } - if (pPause && pPause->NeedToPauseNow()) { - return m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE; - } - readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); - } - if (readResult == 1) { - frames = m_FrameNumber; - return m_status = FXCODEC_STATUS_DECODE_READY; - } - if (m_pGifContext != NULL) { - pGifModule->Finish(m_pGifContext); - m_pGifContext = NULL; - } - return m_status = FXCODEC_STATUS_ERROR; - } - } break; - default:; - } - return FXCODEC_STATUS_ERROR; -} -FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, - int start_x, - int start_y, - int size_x, - int size_y, - int32_t frames, - FX_BOOL bInterpol) { - if (m_status != FXCODEC_STATUS_DECODE_READY) { - return FXCODEC_STATUS_ERROR; - } - if (pDIBitmap == NULL || pDIBitmap->GetBPP() < 8 || frames < 0 || - frames >= m_FrameNumber) { - return FXCODEC_STATUS_ERR_PARAMS; - } - m_pDeviceBitmap = pDIBitmap; - if (m_clipBox.IsEmpty()) { - return FXCODEC_STATUS_ERR_PARAMS; - } - if (size_x <= 0 || size_x > 65535 || size_y <= 0 || size_y > 65535) { - return FXCODEC_STATUS_ERR_PARAMS; - } - FX_RECT device_rc = - FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y); - int32_t out_range_x = device_rc.right - pDIBitmap->GetWidth(); - int32_t out_range_y = device_rc.bottom - pDIBitmap->GetHeight(); - device_rc.Intersect( - FX_RECT(0, 0, pDIBitmap->GetWidth(), pDIBitmap->GetHeight())); - if (device_rc.IsEmpty()) { - return FXCODEC_STATUS_ERR_PARAMS; - } - m_startX = device_rc.left; - m_startY = device_rc.top; - m_sizeX = device_rc.Width(); - m_sizeY = device_rc.Height(); - m_bInterpol = bInterpol; - m_FrameCur = 0; - if (start_x < 0 || out_range_x > 0) { - FX_FLOAT scaleX = (FX_FLOAT)m_clipBox.Width() / (FX_FLOAT)size_x; - if (start_x < 0) { - m_clipBox.left -= (int32_t)FXSYS_ceil((FX_FLOAT)start_x * scaleX); - } - if (out_range_x > 0) { - m_clipBox.right -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_x * scaleX); - } - } - if (start_y < 0 || out_range_y > 0) { - FX_FLOAT scaleY = (FX_FLOAT)m_clipBox.Height() / (FX_FLOAT)size_y; - if (start_y < 0) { - m_clipBox.top -= (int32_t)FXSYS_ceil((FX_FLOAT)start_y * scaleY); - } - if (out_range_y > 0) { - m_clipBox.bottom -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_y * scaleY); - } - } - if (m_clipBox.IsEmpty()) { - return FXCODEC_STATUS_ERR_PARAMS; - } - switch (m_imagType) { - case FXCODEC_IMAGE_JPG: { - ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); - int down_scale = 1; - GetDownScale(down_scale); - FX_BOOL bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); - while (!bStart) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; - if (!JpegReadMoreData(pJpegModule, error_status)) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = error_status; - } - bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); - } - int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale; - scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4; - if (m_pDecodeBuf != NULL) { - FX_Free(m_pDecodeBuf); - m_pDecodeBuf = NULL; - } - m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); - if (m_pDecodeBuf == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - FXSYS_memset(m_pDecodeBuf, 0, scanline_size); - m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, - m_clipBox.Width(), m_bInterpol); - m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); - switch (m_SrcComponents) { - case 1: - m_SrcFormat = FXCodec_8bppGray; - break; - case 3: - m_SrcFormat = FXCodec_Rgb; - break; - case 4: - m_SrcFormat = FXCodec_Cmyk; - break; - } - GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat); - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } break; - case FXCODEC_IMAGE_PNG: { - ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); - if (pPngModule == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - if (m_pPngContext != NULL) { - pPngModule->Finish(m_pPngContext); - m_pPngContext = NULL; - } - m_pPngContext = pPngModule->Start((void*)this); - if (m_pPngContext == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - m_offSet = 0; - switch (m_pDeviceBitmap->GetFormat()) { - case FXDIB_8bppMask: - case FXDIB_8bppRgb: - m_SrcComponents = 1; - m_SrcFormat = FXCodec_8bppGray; - break; - case FXDIB_Rgb: - m_SrcComponents = 3; - m_SrcFormat = FXCodec_Rgb; - break; - case FXDIB_Rgb32: - case FXDIB_Argb: - m_SrcComponents = 4; - m_SrcFormat = FXCodec_Argb; - break; - default: { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_PARAMS; - } - } - GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); - int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; - if (m_pDecodeBuf != NULL) { - FX_Free(m_pDecodeBuf); - m_pDecodeBuf = NULL; - } - m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); - if (m_pDecodeBuf == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - FXSYS_memset(m_pDecodeBuf, 0, scanline_size); - m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width(), m_bInterpol); - m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } break; - case FXCODEC_IMAGE_GIF: { - ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); - if (pGifModule == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - m_SrcFormat = FXCodec_8bppRgb; - GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); - int scanline_size = (m_SrcWidth + 3) / 4 * 4; - if (m_pDecodeBuf != NULL) { - FX_Free(m_pDecodeBuf); - m_pDecodeBuf = NULL; - } - m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); - if (m_pDecodeBuf == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - FXSYS_memset(m_pDecodeBuf, 0, scanline_size); - m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, - m_clipBox.Width(), m_bInterpol); - m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); - m_FrameCur = frames; - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } break; - case FXCODEC_IMAGE_BMP: { - ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); - if (pBmpModule == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - switch (m_SrcComponents) { - case 1: - m_SrcFormat = FXCodec_8bppRgb; - break; - case 3: - m_SrcFormat = FXCodec_Rgb; - break; - case 4: - m_SrcFormat = FXCodec_Rgb32; - break; - } - GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); - m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; - if (m_pDecodeBuf != NULL) { - FX_Free(m_pDecodeBuf); - m_pDecodeBuf = NULL; - } - m_pDecodeBuf = FX_Alloc(uint8_t, m_ScanlineSize); - if (m_pDecodeBuf == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - FXSYS_memset(m_pDecodeBuf, 0, m_ScanlineSize); - m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, - m_clipBox.Width(), m_bInterpol); - m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } break; - case FXCODEC_IMAGE_TIF: - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - default: - break; - } - return FXCODEC_STATUS_ERROR; -} -FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { - if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE) { - return FXCODEC_STATUS_ERROR; - } - switch (m_imagType) { - case FXCODEC_IMAGE_JPG: { - ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); - while (TRUE) { - FX_BOOL readRes = - pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); - while (!readRes) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; - if (!JpegReadMoreData(pJpegModule, error_status)) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = error_status; - } - readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); - } - if (m_SrcFormat == FXCodec_Rgb) { - int src_Bpp = (m_SrcFormat & 0xff) >> 3; - _RGB2BGR(m_pDecodeBuf + m_clipBox.left * src_Bpp, m_clipBox.Width()); - } - if (m_SrcRow >= m_clipBox.bottom) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } - Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat); - m_SrcRow++; - if (pPause && pPause->NeedToPauseNow()) { - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } - } - } break; - case FXCODEC_IMAGE_PNG: { - ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); - while (TRUE) { - FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; - FX_DWORD input_size = - remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; - if (input_size == 0) { - if (m_pPngContext != NULL) { - pPngModule->Finish(m_pPngContext); - } - m_pPngContext = NULL; - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } - if (m_pSrcBuf != NULL && input_size > m_SrcSize) { - FX_Free(m_pSrcBuf); - m_pSrcBuf = FX_Alloc(uint8_t, input_size); - if (m_pSrcBuf == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - FXSYS_memset(m_pSrcBuf, 0, input_size); - m_SrcSize = input_size; - } - FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); - if (!bResult) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_READ; - } - m_offSet += input_size; - bResult = - pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, nullptr); - if (!bResult) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERROR; - } - if (pPause && pPause->NeedToPauseNow()) { - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } - } - } break; - case FXCODEC_IMAGE_GIF: { - ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); - while (TRUE) { - int32_t readRes = - pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); - while (readRes == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; - if (!GifReadMoreData(pGifModule, error_status)) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = error_status; - } - if (pPause && pPause->NeedToPauseNow()) { - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } - readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); - } - if (readRes == 1) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERROR; - } - } break; - case FXCODEC_IMAGE_BMP: { - ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); - while (TRUE) { - int32_t readRes = pBmpModule->LoadImage(m_pBmpContext); - while (readRes == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; - if (!BmpReadMoreData(pBmpModule, error_status)) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = error_status; - } - if (pPause && pPause->NeedToPauseNow()) { - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } - readRes = pBmpModule->LoadImage(m_pBmpContext); - } - if (readRes == 1) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERROR; - } - } break; - case FXCODEC_IMAGE_TIF: { - ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); - FX_BOOL ret = FALSE; - if (m_pDeviceBitmap->GetBPP() == 32 && - m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX && - m_pDeviceBitmap->GetHeight() == m_SrcHeight && - m_SrcHeight == m_sizeY && m_startX == 0 && m_startY == 0 && - m_clipBox.left == 0 && m_clipBox.top == 0 && - m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) { - ret = pTiffModule->Decode(m_pTiffContext, m_pDeviceBitmap); - m_pDeviceBitmap = NULL; - m_pFile = NULL; - if (!ret) { - return m_status = FXCODEC_STATUS_ERROR; - } - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } else { - CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; - pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb); - if (pDIBitmap->GetBuffer() == NULL) { - delete pDIBitmap; - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap); - if (!ret) { - delete pDIBitmap; - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERROR; - } - CFX_DIBitmap* pClipBitmap = - (m_clipBox.left == 0 && m_clipBox.top == 0 && - m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) - ? pDIBitmap - : pDIBitmap->Clone(&m_clipBox); - if (pDIBitmap != pClipBitmap) { - delete pDIBitmap; - } - if (pClipBitmap == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - CFX_DIBitmap* pFormatBitmap = NULL; - switch (m_pDeviceBitmap->GetFormat()) { - case FXDIB_8bppRgb: - pFormatBitmap = new CFX_DIBitmap; - pFormatBitmap->Create(pClipBitmap->GetWidth(), - pClipBitmap->GetHeight(), FXDIB_8bppRgb); - break; - case FXDIB_8bppMask: - pFormatBitmap = new CFX_DIBitmap; - pFormatBitmap->Create(pClipBitmap->GetWidth(), - pClipBitmap->GetHeight(), FXDIB_8bppMask); - break; - case FXDIB_Rgb: - pFormatBitmap = new CFX_DIBitmap; - pFormatBitmap->Create(pClipBitmap->GetWidth(), - pClipBitmap->GetHeight(), FXDIB_Rgb); - break; - case FXDIB_Rgb32: - pFormatBitmap = new CFX_DIBitmap; - pFormatBitmap->Create(pClipBitmap->GetWidth(), - pClipBitmap->GetHeight(), FXDIB_Rgb32); - break; - case FXDIB_Argb: - pFormatBitmap = pClipBitmap; - break; - default:; - } - switch (m_pDeviceBitmap->GetFormat()) { - case FXDIB_8bppRgb: - case FXDIB_8bppMask: { - for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { - uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); - uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); - for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { - uint8_t _a = 255 - src_line[3]; - uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; - uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; - uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; - *des_line++ = FXRGB2GRAY(r, g, b); - src_line += 4; - } - } - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - int32_t desBpp = - (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4; - for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { - uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); - uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); - for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { - uint8_t _a = 255 - src_line[3]; - uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; - uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; - uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; - *des_line++ = b; - *des_line++ = g; - *des_line++ = r; - des_line += desBpp - 3; - src_line += 4; - } - } - } break; - default:; - } - if (pClipBitmap != pFormatBitmap) { - delete pClipBitmap; - } - if (pFormatBitmap == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - CFX_DIBitmap* pStrechBitmap = pFormatBitmap->StretchTo( - m_sizeX, m_sizeY, m_bInterpol ? FXDIB_INTERPOL : FXDIB_DOWNSAMPLE); - delete pFormatBitmap; - pFormatBitmap = NULL; - if (pStrechBitmap == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY, - pStrechBitmap, 0, 0); - delete pStrechBitmap; - pStrechBitmap = NULL; - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } - } break; - default: - break; - } - return FXCODEC_STATUS_ERROR; -} -ICodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder() { - return new CCodec_ProgressiveDecoder(this); -} +// 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/include/fxge/fx_dib.h" +#include "core/include/fxcodec/fx_codec.h" +#include "fx_codec_progress.h" +void CFXCODEC_WeightTable::Calc(int dest_len, + int dest_min, + int dest_max, + int src_len, + int src_min, + int src_max, + FX_BOOL bInterpol) { + if (m_pWeightTables) { + FX_Free(m_pWeightTables); + } + double scale, base; + scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len)); + if (dest_len < 0) { + base = (FX_FLOAT)(src_len); + } else { + base = 0.0f; + } + m_ItemSize = + (int)(sizeof(int) * 2 + + sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + 1)); + m_DestMin = dest_min; + m_pWeightTables = FX_Alloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4); + if (m_pWeightTables == NULL) { + return; + } + if (FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { + for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { + PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); + double src_pos = dest_pixel * scale + scale / 2 + base; + if (bInterpol) { + pixel_weights.m_SrcStart = + (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); + pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); + if (pixel_weights.m_SrcStart < src_min) { + pixel_weights.m_SrcStart = src_min; + } + if (pixel_weights.m_SrcEnd >= src_max) { + pixel_weights.m_SrcEnd = src_max - 1; + } + if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { + pixel_weights.m_Weights[0] = 65536; + } else { + pixel_weights.m_Weights[1] = FXSYS_round( + (FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * + 65536); + pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1]; + } + } else { + pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = + (int)FXSYS_floor((FX_FLOAT)src_pos); + pixel_weights.m_Weights[0] = 65536; + } + } + return; + } + for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { + PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); + double src_start = dest_pixel * scale + base; + double src_end = src_start + scale; + int start_i, end_i; + if (src_start < src_end) { + start_i = (int)FXSYS_floor((FX_FLOAT)src_start); + end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); + } else { + start_i = (int)FXSYS_floor((FX_FLOAT)src_end); + end_i = (int)FXSYS_ceil((FX_FLOAT)src_start); + } + if (start_i < src_min) { + start_i = src_min; + } + if (end_i >= src_max) { + end_i = src_max - 1; + } + if (start_i > end_i) { + pixel_weights.m_SrcStart = start_i; + pixel_weights.m_SrcEnd = start_i; + continue; + } + pixel_weights.m_SrcStart = start_i; + pixel_weights.m_SrcEnd = end_i; + for (int j = start_i; j <= end_i; j++) { + double dest_start = FXSYS_Div((FX_FLOAT)(j)-base, scale); + double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale); + if (dest_start > dest_end) { + double temp = dest_start; + dest_start = dest_end; + dest_end = temp; + } + double area_start = dest_start > (FX_FLOAT)(dest_pixel) + ? dest_start + : (FX_FLOAT)(dest_pixel); + double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) + ? (FX_FLOAT)(dest_pixel + 1) + : dest_end; + double weight = area_start >= area_end ? 0.0f : area_end - area_start; + if (weight == 0 && j == end_i) { + pixel_weights.m_SrcEnd--; + break; + } + pixel_weights.m_Weights[j - start_i] = + FXSYS_round((FX_FLOAT)(weight * 65536)); + } + } +} +void CFXCODEC_HorzTable::Calc(int dest_len, int src_len, FX_BOOL bInterpol) { + if (m_pWeightTables) { + FX_Free(m_pWeightTables); + } + double scale = (double)dest_len / (double)src_len; + m_ItemSize = sizeof(int) * 4; + int size = dest_len * m_ItemSize + 4; + m_pWeightTables = FX_Alloc(uint8_t, size); + if (m_pWeightTables == NULL) { + return; + } + FXSYS_memset(m_pWeightTables, 0, size); + if (scale > 1) { + int pre_des_col = 0; + for (int src_col = 0; src_col < src_len; src_col++) { + double des_col_f = src_col * scale; + int des_col = FXSYS_round((FX_FLOAT)des_col_f); + PixelWeight* pWeight = + (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize); + pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; + pWeight->m_Weights[0] = 65536; + pWeight->m_Weights[1] = 0; + if (src_col == src_len - 1 && des_col < dest_len - 1) { + for (int des_col_index = pre_des_col + 1; des_col_index < dest_len; + des_col_index++) { + pWeight = + (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize); + pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; + pWeight->m_Weights[0] = 65536; + pWeight->m_Weights[1] = 0; + } + return; + } + int des_col_len = des_col - pre_des_col; + for (int des_col_index = pre_des_col + 1; des_col_index < des_col; + des_col_index++) { + pWeight = (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize); + pWeight->m_SrcStart = src_col - 1; + pWeight->m_SrcEnd = src_col; + pWeight->m_Weights[0] = + bInterpol ? FXSYS_round((FX_FLOAT)( + ((FX_FLOAT)des_col - (FX_FLOAT)des_col_index) / + (FX_FLOAT)des_col_len * 65536)) + : 65536; + pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; + } + pre_des_col = des_col; + } + return; + } + for (int des_col = 0; des_col < dest_len; des_col++) { + double src_col_f = des_col / scale; + int src_col = FXSYS_round((FX_FLOAT)src_col_f); + PixelWeight* pWeight = + (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize); + pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; + pWeight->m_Weights[0] = 65536; + pWeight->m_Weights[1] = 0; + } +} +void CFXCODEC_VertTable::Calc(int dest_len, int src_len) { + if (m_pWeightTables) { + FX_Free(m_pWeightTables); + } + double scale = (double)dest_len / (double)src_len; + m_ItemSize = sizeof(int) * 4; + int size = dest_len * m_ItemSize + 4; + m_pWeightTables = FX_Alloc(uint8_t, size); + if (m_pWeightTables == NULL) { + return; + } + FXSYS_memset(m_pWeightTables, 0, size); + if (scale > 1) { + double step = 0.0; + int src_row = 0; + while (step < (double)dest_len) { + int start_step = (int)step; + step = scale * (++src_row); + int end_step = (int)step; + if (end_step >= dest_len) { + end_step = dest_len; + for (int des_row = start_step; des_row < end_step; des_row++) { + PixelWeight* pWeight = + (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); + pWeight->m_SrcStart = start_step; + pWeight->m_SrcEnd = start_step; + pWeight->m_Weights[0] = 65536; + pWeight->m_Weights[1] = 0; + } + return; + } + int length = end_step - start_step; + { + PixelWeight* pWeight = + (PixelWeight*)(m_pWeightTables + start_step * m_ItemSize); + pWeight->m_SrcStart = start_step; + pWeight->m_SrcEnd = start_step; + pWeight->m_Weights[0] = 65536; + pWeight->m_Weights[1] = 0; + } + for (int des_row = start_step + 1; des_row < end_step; des_row++) { + PixelWeight* pWeight = + (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); + pWeight->m_SrcStart = start_step; + pWeight->m_SrcEnd = end_step; + pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) / + (FX_FLOAT)length * 65536); + pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; + } + } + } else { + for (int des_row = 0; des_row < dest_len; des_row++) { + PixelWeight* pWeight = + (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); + pWeight->m_SrcStart = des_row; + pWeight->m_SrcEnd = des_row; + pWeight->m_Weights[0] = 65536; + pWeight->m_Weights[1] = 0; + } + } +} +CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder( + CCodec_ModuleMgr* pCodecMgr) { + m_pFile = NULL; + m_pJpegContext = NULL; + m_pPngContext = NULL; + m_pGifContext = NULL; + m_pBmpContext = NULL; + m_pTiffContext = NULL; + m_pCodecMgr = NULL; + m_pSrcBuf = NULL; + m_pDecodeBuf = NULL; + m_pDeviceBitmap = NULL; + m_pSrcPalette = NULL; + m_pCodecMgr = pCodecMgr; + m_offSet = 0; + m_SrcSize = 0; + m_ScanlineSize = 0; + m_SrcWidth = m_SrcHeight = 0; + m_SrcComponents = 0; + m_SrcBPC = 0; + m_SrcPassNumber = 0; + m_clipBox = FX_RECT(0, 0, 0, 0); + m_imagType = FXCODEC_IMAGE_UNKNOWN; + m_status = FXCODEC_STATUS_DECODE_FINISH; + m_TransMethod = -1; + m_SrcRow = 0; + m_SrcFormat = FXCodec_Invalid; + m_bInterpol = TRUE; + m_FrameNumber = 0; + m_FrameCur = 0; + m_SrcPaletteNumber = 0; + m_GifPltNumber = 0; + m_GifBgIndex = 0; + m_pGifPalette = NULL; + m_GifTransIndex = -1; + m_GifFrameRect = FX_RECT(0, 0, 0, 0); + m_BmpIsTopBottom = FALSE; +} +CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() { + m_pFile = NULL; + if (m_pJpegContext != NULL) { + m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext); + } + if (m_pPngContext != NULL) { + m_pCodecMgr->GetPngModule()->Finish(m_pPngContext); + } + if (m_pGifContext != NULL) { + m_pCodecMgr->GetGifModule()->Finish(m_pGifContext); + } + if (m_pBmpContext != NULL) { + m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext); + } + if (m_pTiffContext != NULL) { + m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext); + } + if (m_pSrcBuf != NULL) { + FX_Free(m_pSrcBuf); + } + if (m_pDecodeBuf != NULL) { + FX_Free(m_pDecodeBuf); + } + if (m_pSrcPalette != NULL) { + FX_Free(m_pSrcPalette); + } +} +FX_BOOL CCodec_ProgressiveDecoder::JpegReadMoreData( + ICodec_JpegModule* pJpegModule, + FXCODEC_STATUS& err_status) { + FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); + if (dwSize <= m_offSet) { + return FALSE; + } + dwSize = dwSize - m_offSet; + FX_DWORD dwAvail = pJpegModule->GetAvailInput(m_pJpegContext, NULL); + if (dwAvail == m_SrcSize) { + if (dwSize > FXCODEC_BLOCK_SIZE) { + dwSize = FXCODEC_BLOCK_SIZE; + } + m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / + FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; + m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); + if (!m_pSrcBuf) { + err_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + } else { + FX_DWORD dwConsume = m_SrcSize - dwAvail; + if (dwAvail) { + FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); + } + if (dwSize > dwConsume) { + dwSize = dwConsume; + } + } + if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { + err_status = FXCODEC_STATUS_ERR_READ; + return FALSE; + } + m_offSet += dwSize; + pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail); + return TRUE; +} +FX_BOOL CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, + int width, + int height, + int bpc, + int pass, + int* color_type, + double* gamma) { + CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; + if (pCodec->m_pDeviceBitmap == NULL) { + pCodec->m_SrcWidth = width; + pCodec->m_SrcHeight = height; + pCodec->m_SrcBPC = bpc; + pCodec->m_SrcPassNumber = pass; + pCodec->m_SrcComponents = + *color_type == 0 ? 1 : *color_type == 2 + ? 3 + : *color_type == 3 + ? 4 + : *color_type == 4 + ? 2 + : *color_type == 6 ? 4 : 0; + pCodec->m_clipBox = FX_RECT(0, 0, width, height); + return FALSE; + } + FXDIB_Format format = pCodec->m_pDeviceBitmap->GetFormat(); + switch (format) { + case FXDIB_1bppMask: + case FXDIB_1bppRgb: + ASSERT(FALSE); + return FALSE; + case FXDIB_8bppMask: + case FXDIB_8bppRgb: + *color_type = 0; + break; + case FXDIB_Rgb: + *color_type = 2; + break; + case FXDIB_Rgb32: + case FXDIB_Argb: + *color_type = 6; + break; + default: + ASSERT(FALSE); + return FALSE; + } + *gamma = FXCODEC_PNG_GAMMA; + return TRUE; +} +FX_BOOL CCodec_ProgressiveDecoder::PngAskScanlineBufFunc(void* pModule, + int line, + uint8_t*& src_buf) { + CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; + CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; + ASSERT(pDIBitmap != NULL); + if (pDIBitmap == NULL) { + return FALSE; + } + if (line >= pCodec->m_clipBox.top && line < pCodec->m_clipBox.bottom) { + double scale_y = + (double)pCodec->m_sizeY / (double)pCodec->m_clipBox.Height(); + int32_t row = + (int32_t)((line - pCodec->m_clipBox.top) * scale_y) + pCodec->m_startY; + uint8_t* src_scan = (uint8_t*)pDIBitmap->GetScanline(row); + uint8_t* des_scan = pCodec->m_pDecodeBuf; + src_buf = pCodec->m_pDecodeBuf; + int32_t src_Bpp = pDIBitmap->GetBPP() >> 3; + int32_t des_Bpp = (pCodec->m_SrcFormat & 0xff) >> 3; + int32_t src_left = pCodec->m_startX; + int32_t des_left = pCodec->m_clipBox.left; + src_scan += src_left * src_Bpp; + des_scan += des_left * des_Bpp; + for (int32_t src_col = 0; src_col < pCodec->m_sizeX; src_col++) { + PixelWeight* pPixelWeights = + pCodec->m_WeightHorzOO.GetPixelWeight(src_col); + if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) { + continue; + } + switch (pDIBitmap->GetFormat()) { + case FXDIB_1bppMask: + case FXDIB_1bppRgb: + ASSERT(FALSE); + return FALSE; + case FXDIB_8bppMask: + case FXDIB_8bppRgb: { + if (pDIBitmap->GetPalette() != NULL) { + return FALSE; + } + FX_DWORD des_g = 0; + des_g += pPixelWeights->m_Weights[0] * src_scan[src_col]; + des_scan[pPixelWeights->m_SrcStart] = (uint8_t)(des_g >> 16); + } break; + case FXDIB_Rgb: + case FXDIB_Rgb32: { + FX_DWORD des_b = 0, des_g = 0, des_r = 0; + const uint8_t* p = src_scan + src_col * src_Bpp; + des_b += pPixelWeights->m_Weights[0] * (*p++); + des_g += pPixelWeights->m_Weights[0] * (*p++); + des_r += pPixelWeights->m_Weights[0] * (*p); + uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; + *pDes++ = (uint8_t)((des_b) >> 16); + *pDes++ = (uint8_t)((des_g) >> 16); + *pDes = (uint8_t)((des_r) >> 16); + } break; + case FXDIB_Argb: { + FX_DWORD des_r = 0, des_g = 0, des_b = 0; + const uint8_t* p = src_scan + src_col * src_Bpp; + des_b += pPixelWeights->m_Weights[0] * (*p++); + des_g += pPixelWeights->m_Weights[0] * (*p++); + des_r += pPixelWeights->m_Weights[0] * (*p++); + uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; + *pDes++ = (uint8_t)((des_b) >> 16); + *pDes++ = (uint8_t)((des_g) >> 16); + *pDes++ = (uint8_t)((des_r) >> 16); + *pDes = *p; + } break; + default: + return FALSE; + } + } + } + return TRUE; +} +void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz( + CFX_DIBitmap* pDeviceBitmap, + int32_t des_line, + uint8_t* src_scan, + FXCodec_Format src_format) { + uint8_t* des_scan = (uint8_t*)pDeviceBitmap->GetScanline(des_line); + int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3; + int32_t des_Bpp = pDeviceBitmap->GetBPP() >> 3; + int32_t src_left = m_clipBox.left; + int32_t des_left = m_startX; + src_scan += src_left * src_Bpp; + des_scan += des_left * des_Bpp; + for (int32_t des_col = 0; des_col < m_sizeX; des_col++) { + PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(des_col); + switch (pDeviceBitmap->GetFormat()) { + case FXDIB_1bppMask: + case FXDIB_1bppRgb: + ASSERT(FALSE); + return; + case FXDIB_8bppMask: + case FXDIB_8bppRgb: { + if (pDeviceBitmap->GetPalette() != NULL) { + return; + } + FX_DWORD des_g = 0; + des_g += + pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart]; + des_g += + pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd]; + *des_scan++ = (uint8_t)(des_g >> 16); + } break; + case FXDIB_Rgb: + case FXDIB_Rgb32: { + FX_DWORD des_b = 0, des_g = 0, des_r = 0; + const uint8_t* p = src_scan; + p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; + des_b += pPixelWeights->m_Weights[0] * (*p++); + des_g += pPixelWeights->m_Weights[0] * (*p++); + des_r += pPixelWeights->m_Weights[0] * (*p); + p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; + des_b += pPixelWeights->m_Weights[1] * (*p++); + des_g += pPixelWeights->m_Weights[1] * (*p++); + des_r += pPixelWeights->m_Weights[1] * (*p); + *des_scan++ = (uint8_t)((des_b) >> 16); + *des_scan++ = (uint8_t)((des_g) >> 16); + *des_scan++ = (uint8_t)((des_r) >> 16); + des_scan += des_Bpp - 3; + } break; + case FXDIB_Argb: { + FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; + const uint8_t* p = src_scan; + p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; + des_b += pPixelWeights->m_Weights[0] * (*p++); + des_g += pPixelWeights->m_Weights[0] * (*p++); + des_r += pPixelWeights->m_Weights[0] * (*p++); + des_a += pPixelWeights->m_Weights[0] * (*p); + p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; + des_b += pPixelWeights->m_Weights[1] * (*p++); + des_g += pPixelWeights->m_Weights[1] * (*p++); + des_r += pPixelWeights->m_Weights[1] * (*p++); + des_a += pPixelWeights->m_Weights[1] * (*p); + *des_scan++ = (uint8_t)((des_b) >> 16); + *des_scan++ = (uint8_t)((des_g) >> 16); + *des_scan++ = (uint8_t)((des_r) >> 16); + *des_scan++ = (uint8_t)((des_a) >> 16); + } break; + default: + return; + } + } +} +void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, + int pass, + int line) { + CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; + CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; + ASSERT(pDIBitmap != NULL); + int src_top = pCodec->m_clipBox.top; + int src_bottom = pCodec->m_clipBox.bottom; + int des_top = pCodec->m_startY; + int src_hei = pCodec->m_clipBox.Height(); + int des_hei = pCodec->m_sizeY; + if (line >= src_top && line < src_bottom) { + double scale_y = (double)des_hei / (double)src_hei; + int src_row = line - src_top; + int des_row = (int)(src_row * scale_y) + des_top; + if (des_row >= des_top + des_hei) { + return; + } + pCodec->PngOneOneMapResampleHorz(pDIBitmap, des_row, pCodec->m_pDecodeBuf, + pCodec->m_SrcFormat); + if (pCodec->m_SrcPassNumber == 1 && scale_y > 1.0) { + pCodec->ResampleVert(pDIBitmap, scale_y, des_row); + return; + } + if (pass == 6 && scale_y > 1.0) { + pCodec->ResampleVert(pDIBitmap, scale_y, des_row); + } + } +} +FX_BOOL CCodec_ProgressiveDecoder::GifReadMoreData(ICodec_GifModule* pGifModule, + FXCODEC_STATUS& err_status) { + FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); + if (dwSize <= m_offSet) { + return FALSE; + } + dwSize = dwSize - m_offSet; + FX_DWORD dwAvail = pGifModule->GetAvailInput(m_pGifContext, NULL); + if (dwAvail == m_SrcSize) { + if (dwSize > FXCODEC_BLOCK_SIZE) { + dwSize = FXCODEC_BLOCK_SIZE; + } + m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / + FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; + m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); + if (!m_pSrcBuf) { + err_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + } else { + FX_DWORD dwConsume = m_SrcSize - dwAvail; + if (dwAvail) { + FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); + } + if (dwSize > dwConsume) { + dwSize = dwConsume; + } + } + if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { + err_status = FXCODEC_STATUS_ERR_READ; + return FALSE; + } + m_offSet += dwSize; + pGifModule->Input(m_pGifContext, m_pSrcBuf, dwSize + dwAvail); + return TRUE; +} +void CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback( + void* pModule, + FX_DWORD& cur_pos) { + CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; + FX_DWORD remain_size = + pCodec->m_pCodecMgr->GetGifModule()->GetAvailInput(pCodec->m_pGifContext); + cur_pos = pCodec->m_offSet - remain_size; +} +uint8_t* CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback( + void* pModule, + int32_t frame_num, + int32_t pal_size) { + return FX_Alloc(uint8_t, pal_size); +} +FX_BOOL CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback( + void* pModule, + FX_DWORD rcd_pos, + const FX_RECT& img_rc, + int32_t pal_num, + void* pal_ptr, + int32_t delay_time, + FX_BOOL user_input, + int32_t trans_index, + int32_t disposal_method, + FX_BOOL interlace) { + CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; + pCodec->m_offSet = rcd_pos; + FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; + if (!pCodec->GifReadMoreData(pCodec->m_pCodecMgr->GetGifModule(), + error_status)) { + return FALSE; + } + uint8_t* pPalette = NULL; + if (pal_num != 0 && pal_ptr) { + pPalette = (uint8_t*)pal_ptr; + } else { + pal_num = pCodec->m_GifPltNumber; + pPalette = pCodec->m_pGifPalette; + } + if (pCodec->m_pSrcPalette == NULL) { + pCodec->m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num); + } else if (pal_num > pCodec->m_SrcPaletteNumber) { + pCodec->m_pSrcPalette = FX_Realloc(FX_ARGB, pCodec->m_pSrcPalette, pal_num); + } + if (pCodec->m_pSrcPalette == NULL) { + return FALSE; + } + pCodec->m_SrcPaletteNumber = pal_num; + for (int i = 0; i < pal_num; i++) { + FX_DWORD j = i * 3; + pCodec->m_pSrcPalette[i] = + ArgbEncode(0xff, pPalette[j], pPalette[j + 1], pPalette[j + 2]); + } + pCodec->m_GifTransIndex = trans_index; + pCodec->m_GifFrameRect = img_rc; + pCodec->m_SrcPassNumber = interlace ? 4 : 1; + int32_t pal_index = pCodec->m_GifBgIndex; + CFX_DIBitmap* pDevice = pCodec->m_pDeviceBitmap; + if (trans_index >= pal_num) { + trans_index = -1; + } + if (trans_index != -1) { + pCodec->m_pSrcPalette[trans_index] &= 0x00ffffff; + if (pDevice->HasAlpha()) { + pal_index = trans_index; + } + } + int startX = pCodec->m_startX; + int startY = pCodec->m_startY; + int sizeX = pCodec->m_sizeX; + int sizeY = pCodec->m_sizeY; + int Bpp = pDevice->GetBPP() / 8; + FX_ARGB argb = pCodec->m_pSrcPalette[pal_index]; + for (int row = 0; row < sizeY; row++) { + uint8_t* pScanline = + (uint8_t*)pDevice->GetScanline(row + startY) + startX * Bpp; + switch (pCodec->m_TransMethod) { + case 3: { + uint8_t gray = + FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); + FXSYS_memset(pScanline, gray, sizeX); + break; + } + case 8: { + for (int col = 0; col < sizeX; col++) { + *pScanline++ = FXARGB_B(argb); + *pScanline++ = FXARGB_G(argb); + *pScanline++ = FXARGB_R(argb); + pScanline += Bpp - 3; + } + break; + } + case 12: { + for (int col = 0; col < sizeX; col++) { + FXARGB_SETDIB(pScanline, argb); + pScanline += 4; + } + break; + } + } + } + return TRUE; +} +void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, + int32_t row_num, + uint8_t* row_buf) { + CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; + CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; + ASSERT(pDIBitmap != NULL); + int32_t img_width = pCodec->m_GifFrameRect.Width(); + if (!pDIBitmap->HasAlpha()) { + uint8_t* byte_ptr = row_buf; + for (int i = 0; i < img_width; i++) { + if (*byte_ptr == pCodec->m_GifTransIndex) { + *byte_ptr = pCodec->m_GifBgIndex; + } + byte_ptr++; + } + } + int32_t pal_index = pCodec->m_GifBgIndex; + if (pCodec->m_GifTransIndex != -1 && pCodec->m_pDeviceBitmap->HasAlpha()) { + pal_index = pCodec->m_GifTransIndex; + } + FXSYS_memset(pCodec->m_pDecodeBuf, pal_index, pCodec->m_SrcWidth); + FX_BOOL bLastPass = (row_num % 2) == 1; + int32_t line = row_num + pCodec->m_GifFrameRect.top; + int32_t left = pCodec->m_GifFrameRect.left; + FXSYS_memcpy(pCodec->m_pDecodeBuf + left, row_buf, img_width); + int src_top = pCodec->m_clipBox.top; + int src_bottom = pCodec->m_clipBox.bottom; + int des_top = pCodec->m_startY; + int src_hei = pCodec->m_clipBox.Height(); + int des_hei = pCodec->m_sizeY; + if (line >= src_top && line < src_bottom) { + double scale_y = (double)des_hei / (double)src_hei; + int src_row = line - src_top; + int des_row = (int)(src_row * scale_y) + des_top; + if (des_row >= des_top + des_hei) { + return; + } + pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, + pCodec->m_SrcFormat); + if (scale_y > 1.0 && + (!pCodec->m_bInterpol || pCodec->m_SrcPassNumber == 1)) { + pCodec->ResampleVert(pDIBitmap, scale_y, des_row); + return; + } + if (scale_y > 1.0) { + int des_bottom = des_top + pCodec->m_sizeY; + int des_Bpp = pDIBitmap->GetBPP() >> 3; + FX_DWORD des_ScanOffet = pCodec->m_startX * des_Bpp; + if (des_row + (int)scale_y >= des_bottom - 1) { + uint8_t* scan_src = + (uint8_t*)pDIBitmap->GetScanline(des_row) + des_ScanOffet; + int cur_row = des_row; + while (++cur_row < des_bottom) { + uint8_t* scan_des = + (uint8_t*)pDIBitmap->GetScanline(cur_row) + des_ScanOffet; + FX_DWORD size = pCodec->m_sizeX * des_Bpp; + FXSYS_memcpy(scan_des, scan_src, size); + } + } + if (bLastPass) { + pCodec->GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row); + } + } + } +} +void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert( + CFX_DIBitmap* pDeviceBitmap, + double scale_y, + int des_row) { + int des_Bpp = pDeviceBitmap->GetBPP() >> 3; + FX_DWORD des_ScanOffet = m_startX * des_Bpp; + int des_top = m_startY; + int des_row_1 = des_row - int(2 * scale_y); + if (des_row_1 < des_top) { + des_row_1 = des_top; + } + for (; des_row_1 < des_row; des_row_1++) { + uint8_t* scan_des = + (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; + PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); + const uint8_t* scan_src1 = + pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + + des_ScanOffet; + const uint8_t* scan_src2 = + pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; + for (int des_col = 0; des_col < m_sizeX; des_col++) { + switch (pDeviceBitmap->GetFormat()) { + case FXDIB_Invalid: + case FXDIB_1bppMask: + case FXDIB_1bppRgb: + return; + case FXDIB_8bppMask: + case FXDIB_8bppRgb: { + if (pDeviceBitmap->GetPalette() != NULL) { + return; + } + int des_g = 0; + des_g += pWeight->m_Weights[0] * (*scan_src1++); + des_g += pWeight->m_Weights[1] * (*scan_src2++); + *scan_des++ = (uint8_t)(des_g >> 16); + } break; + case FXDIB_Rgb: + case FXDIB_Rgb32: { + FX_DWORD des_b = 0, des_g = 0, des_r = 0; + des_b += pWeight->m_Weights[0] * (*scan_src1++); + des_g += pWeight->m_Weights[0] * (*scan_src1++); + des_r += pWeight->m_Weights[0] * (*scan_src1++); + scan_src1 += des_Bpp - 3; + des_b += pWeight->m_Weights[1] * (*scan_src2++); + des_g += pWeight->m_Weights[1] * (*scan_src2++); + des_r += pWeight->m_Weights[1] * (*scan_src2++); + scan_src2 += des_Bpp - 3; + *scan_des++ = (uint8_t)((des_b) >> 16); + *scan_des++ = (uint8_t)((des_g) >> 16); + *scan_des++ = (uint8_t)((des_r) >> 16); + scan_des += des_Bpp - 3; + } break; + case FXDIB_Argb: { + FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; + des_b += pWeight->m_Weights[0] * (*scan_src1++); + des_g += pWeight->m_Weights[0] * (*scan_src1++); + des_r += pWeight->m_Weights[0] * (*scan_src1++); + des_a += pWeight->m_Weights[0] * (*scan_src1++); + des_b += pWeight->m_Weights[1] * (*scan_src2++); + des_g += pWeight->m_Weights[1] * (*scan_src2++); + des_r += pWeight->m_Weights[1] * (*scan_src2++); + des_a += pWeight->m_Weights[1] * (*scan_src2++); + *scan_des++ = (uint8_t)((des_b) >> 16); + *scan_des++ = (uint8_t)((des_g) >> 16); + *scan_des++ = (uint8_t)((des_r) >> 16); + *scan_des++ = (uint8_t)((des_a) >> 16); + } break; + default: + return; + } + } + } + int des_bottom = des_top + m_sizeY - 1; + if (des_row + (int)(2 * scale_y) >= des_bottom && + des_row + (int)scale_y < des_bottom) { + GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y); + } +} +FX_BOOL CCodec_ProgressiveDecoder::BmpReadMoreData(ICodec_BmpModule* pBmpModule, + FXCODEC_STATUS& err_status) { + FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); + if (dwSize <= m_offSet) { + return FALSE; + } + dwSize = dwSize - m_offSet; + FX_DWORD dwAvail = pBmpModule->GetAvailInput(m_pBmpContext, NULL); + if (dwAvail == m_SrcSize) { + if (dwSize > FXCODEC_BLOCK_SIZE) { + dwSize = FXCODEC_BLOCK_SIZE; + } + m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / + FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; + m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); + if (!m_pSrcBuf) { + err_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + } else { + FX_DWORD dwConsume = m_SrcSize - dwAvail; + if (dwAvail) { + FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); + } + if (dwSize > dwConsume) { + dwSize = dwConsume; + } + } + if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { + err_status = FXCODEC_STATUS_ERR_READ; + return FALSE; + } + m_offSet += dwSize; + pBmpModule->Input(m_pBmpContext, m_pSrcBuf, dwSize + dwAvail); + return TRUE; +} +FX_BOOL CCodec_ProgressiveDecoder::BmpInputImagePositionBufCallback( + void* pModule, + FX_DWORD rcd_pos) { + CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; + pCodec->m_offSet = rcd_pos; + FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; + if (!pCodec->BmpReadMoreData(pCodec->m_pCodecMgr->GetBmpModule(), + error_status)) { + return FALSE; + } + return TRUE; +} +void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, + int32_t row_num, + uint8_t* row_buf) { + CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; + CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; + ASSERT(pDIBitmap != NULL); + FXSYS_memcpy(pCodec->m_pDecodeBuf, row_buf, pCodec->m_ScanlineSize); + int src_top = pCodec->m_clipBox.top; + int src_bottom = pCodec->m_clipBox.bottom; + int des_top = pCodec->m_startY; + int src_hei = pCodec->m_clipBox.Height(); + int des_hei = pCodec->m_sizeY; + if (row_num >= src_top && row_num < src_bottom) { + double scale_y = (double)des_hei / (double)src_hei; + int src_row = row_num - src_top; + int des_row = (int)(src_row * scale_y) + des_top; + if (des_row >= des_top + des_hei) { + return; + } + pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, + pCodec->m_SrcFormat); + if (scale_y > 1.0) { + if (pCodec->m_BmpIsTopBottom || !pCodec->m_bInterpol) { + pCodec->ResampleVert(pDIBitmap, scale_y, des_row); + return; + } else { + pCodec->ResampleVertBT(pDIBitmap, scale_y, des_row); + } + } + } +} +void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, + double scale_y, + int des_row) { + int des_Bpp = pDeviceBitmap->GetBPP() >> 3; + FX_DWORD des_ScanOffet = m_startX * des_Bpp; + int des_top = m_startY; + int des_bottom = m_startY + m_sizeY; + int des_row_1 = des_row + int(scale_y); + if (des_row_1 >= des_bottom - 1) { + uint8_t* scan_src = + (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; + while (++des_row < des_bottom) { + uint8_t* scan_des = + (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; + FX_DWORD size = m_sizeX * des_Bpp; + FXSYS_memcpy(scan_des, scan_src, size); + } + return; + } + for (; des_row_1 > des_row; des_row_1--) { + uint8_t* scan_des = + (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; + PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); + const uint8_t* scan_src1 = + pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + + des_ScanOffet; + const uint8_t* scan_src2 = + pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; + for (int des_col = 0; des_col < m_sizeX; des_col++) { + switch (pDeviceBitmap->GetFormat()) { + case FXDIB_Invalid: + case FXDIB_1bppMask: + case FXDIB_1bppRgb: + return; + case FXDIB_8bppMask: + case FXDIB_8bppRgb: { + if (pDeviceBitmap->GetPalette() != NULL) { + return; + } + int des_g = 0; + des_g += pWeight->m_Weights[0] * (*scan_src1++); + des_g += pWeight->m_Weights[1] * (*scan_src2++); + *scan_des++ = (uint8_t)(des_g >> 16); + } break; + case FXDIB_Rgb: + case FXDIB_Rgb32: { + FX_DWORD des_b = 0, des_g = 0, des_r = 0; + des_b += pWeight->m_Weights[0] * (*scan_src1++); + des_g += pWeight->m_Weights[0] * (*scan_src1++); + des_r += pWeight->m_Weights[0] * (*scan_src1++); + scan_src1 += des_Bpp - 3; + des_b += pWeight->m_Weights[1] * (*scan_src2++); + des_g += pWeight->m_Weights[1] * (*scan_src2++); + des_r += pWeight->m_Weights[1] * (*scan_src2++); + scan_src2 += des_Bpp - 3; + *scan_des++ = (uint8_t)((des_b) >> 16); + *scan_des++ = (uint8_t)((des_g) >> 16); + *scan_des++ = (uint8_t)((des_r) >> 16); + scan_des += des_Bpp - 3; + } break; + case FXDIB_Argb: { + FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; + des_b += pWeight->m_Weights[0] * (*scan_src1++); + des_g += pWeight->m_Weights[0] * (*scan_src1++); + des_r += pWeight->m_Weights[0] * (*scan_src1++); + des_a += pWeight->m_Weights[0] * (*scan_src1++); + des_b += pWeight->m_Weights[1] * (*scan_src2++); + des_g += pWeight->m_Weights[1] * (*scan_src2++); + des_r += pWeight->m_Weights[1] * (*scan_src2++); + des_a += pWeight->m_Weights[1] * (*scan_src2++); + *scan_des++ = (uint8_t)((des_b) >> 16); + *scan_des++ = (uint8_t)((des_g) >> 16); + *scan_des++ = (uint8_t)((des_r) >> 16); + *scan_des++ = (uint8_t)((des_a) >> 16); + } break; + default: + return; + } + } + } +} +FX_BOOL CCodec_ProgressiveDecoder::DetectImageType( + FXCODEC_IMAGE_TYPE imageType, + CFX_DIBAttribute* pAttribute) { + m_offSet = 0; + FX_DWORD size = (FX_DWORD)m_pFile->GetSize(); + if (size > FXCODEC_BLOCK_SIZE) { + size = FXCODEC_BLOCK_SIZE; + } + if (m_pSrcBuf != NULL) { + FX_Free(m_pSrcBuf); + m_pSrcBuf = NULL; + } + m_pSrcBuf = FX_Alloc(uint8_t, size); + if (m_pSrcBuf == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + FXSYS_memset(m_pSrcBuf, 0, size); + m_SrcSize = size; + switch (imageType) { + case FXCODEC_IMAGE_BMP: { + ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); + if (pBmpModule == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + pBmpModule->InputImagePositionBufCallback = + BmpInputImagePositionBufCallback; + pBmpModule->ReadScanlineCallback = BmpReadScanlineCallback; + m_pBmpContext = pBmpModule->Start((void*)this); + if (m_pBmpContext == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); + if (!bResult) { + m_status = FXCODEC_STATUS_ERR_READ; + return FALSE; + } + m_offSet += size; + pBmpModule->Input(m_pBmpContext, m_pSrcBuf, size); + FX_DWORD* pPalette = NULL; + int32_t readResult = pBmpModule->ReadHeader( + m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, + &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); + while (readResult == 2) { + FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; + if (!BmpReadMoreData(pBmpModule, error_status)) { + m_status = error_status; + return FALSE; + } + readResult = pBmpModule->ReadHeader( + m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, + &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); + } + if (readResult == 1) { + m_SrcBPC = 8; + m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); + if (m_pSrcPalette != NULL) { + FX_Free(m_pSrcPalette); + m_pSrcPalette = NULL; + } + if (m_SrcPaletteNumber) { + m_pSrcPalette = FX_Alloc(FX_ARGB, m_SrcPaletteNumber); + if (m_pSrcPalette == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + FXSYS_memcpy(m_pSrcPalette, pPalette, + m_SrcPaletteNumber * sizeof(FX_DWORD)); + } + return TRUE; + } + if (m_pBmpContext != NULL) { + pBmpModule->Finish(m_pBmpContext); + m_pBmpContext = NULL; + } + m_status = FXCODEC_STATUS_ERR_FORMAT; + return FALSE; + } break; + case FXCODEC_IMAGE_JPG: { + ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); + if (pJpegModule == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + m_pJpegContext = pJpegModule->Start(); + if (m_pJpegContext == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); + if (!bResult) { + m_status = FXCODEC_STATUS_ERR_READ; + return FALSE; + } + m_offSet += size; + pJpegModule->Input(m_pJpegContext, m_pSrcBuf, size); + int32_t readResult = + pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, + &m_SrcComponents, pAttribute); + while (readResult == 2) { + FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; + if (!JpegReadMoreData(pJpegModule, error_status)) { + m_status = error_status; + return FALSE; + } + readResult = + pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, + &m_SrcComponents, pAttribute); + } + if (!readResult) { + m_SrcBPC = 8; + m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); + return TRUE; + } + if (m_pJpegContext != NULL) { + pJpegModule->Finish(m_pJpegContext); + m_pJpegContext = NULL; + } + m_status = FXCODEC_STATUS_ERR_FORMAT; + return FALSE; + } break; + case FXCODEC_IMAGE_PNG: { + ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); + if (pPngModule == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + pPngModule->ReadHeaderCallback = + CCodec_ProgressiveDecoder::PngReadHeaderFunc; + pPngModule->AskScanlineBufCallback = + CCodec_ProgressiveDecoder::PngAskScanlineBufFunc; + pPngModule->FillScanlineBufCompletedCallback = + CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc; + m_pPngContext = pPngModule->Start((void*)this); + if (m_pPngContext == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); + if (!bResult) { + m_status = FXCODEC_STATUS_ERR_READ; + return FALSE; + } + m_offSet += size; + bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, size, pAttribute); + while (bResult) { + FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; + FX_DWORD input_size = + remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; + if (input_size == 0) { + if (m_pPngContext != NULL) { + pPngModule->Finish(m_pPngContext); + } + m_pPngContext = NULL; + m_status = FXCODEC_STATUS_ERR_FORMAT; + return FALSE; + } + if (m_pSrcBuf != NULL && input_size > m_SrcSize) { + FX_Free(m_pSrcBuf); + m_pSrcBuf = FX_Alloc(uint8_t, input_size); + if (m_pSrcBuf == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + FXSYS_memset(m_pSrcBuf, 0, input_size); + m_SrcSize = input_size; + } + bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); + if (!bResult) { + m_status = FXCODEC_STATUS_ERR_READ; + return FALSE; + } + m_offSet += input_size; + bResult = + pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, pAttribute); + } + ASSERT(!bResult); + if (m_pPngContext != NULL) { + pPngModule->Finish(m_pPngContext); + m_pPngContext = NULL; + } + if (m_SrcPassNumber == 0) { + m_status = FXCODEC_STATUS_ERR_FORMAT; + return FALSE; + } + } break; + case FXCODEC_IMAGE_GIF: { + ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); + if (pGifModule == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + pGifModule->RecordCurrentPositionCallback = + CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback; + pGifModule->AskLocalPaletteBufCallback = + CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback; + pGifModule->InputRecordPositionBufCallback = + CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback; + pGifModule->ReadScanlineCallback = + CCodec_ProgressiveDecoder::GifReadScanlineCallback; + m_pGifContext = pGifModule->Start((void*)this); + if (m_pGifContext == NULL) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return FALSE; + } + FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); + if (!bResult) { + m_status = FXCODEC_STATUS_ERR_READ; + return FALSE; + } + m_offSet += size; + pGifModule->Input(m_pGifContext, m_pSrcBuf, size); + m_SrcComponents = 1; + int32_t readResult = pGifModule->ReadHeader( + m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, + (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); + while (readResult == 2) { + FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; + if (!GifReadMoreData(pGifModule, error_status)) { + m_status = error_status; + return FALSE; + } + readResult = pGifModule->ReadHeader( + m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, + (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); + } + if (readResult == 1) { + m_SrcBPC = 8; + m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); + return TRUE; + } + if (m_pGifContext != NULL) { + pGifModule->Finish(m_pGifContext); + m_pGifContext = NULL; + } + m_status = FXCODEC_STATUS_ERR_FORMAT; + return FALSE; + } break; + case FXCODEC_IMAGE_TIF: { + ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); + if (pTiffModule == NULL) { + m_status = FXCODEC_STATUS_ERR_FORMAT; + return FALSE; + } + m_pTiffContext = pTiffModule->CreateDecoder(m_pFile); + if (m_pTiffContext == NULL) { + m_status = FXCODEC_STATUS_ERR_FORMAT; + return FALSE; + } + int32_t frames = 0; + pTiffModule->GetFrames(m_pTiffContext, frames); + FX_DWORD bpc; + FX_BOOL ret = pTiffModule->LoadFrameInfo( + m_pTiffContext, 0, (FX_DWORD&)m_SrcWidth, (FX_DWORD&)m_SrcHeight, + (FX_DWORD&)m_SrcComponents, bpc, pAttribute); + m_SrcComponents = 4; + m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); + if (!ret) { + pTiffModule->DestroyDecoder(m_pTiffContext); + (m_pTiffContext = NULL); + (m_status = FXCODEC_STATUS_ERR_FORMAT); + return FALSE; + } + } break; + default: + m_status = FXCODEC_STATUS_ERR_FORMAT; + return FALSE; + } + return TRUE; +} +FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo( + IFX_FileRead* pFile, + FXCODEC_IMAGE_TYPE imageType, + CFX_DIBAttribute* pAttribute) { + switch (m_status) { + case FXCODEC_STATUS_FRAME_READY: + case FXCODEC_STATUS_FRAME_TOBECONTINUE: + case FXCODEC_STATUS_DECODE_READY: + case FXCODEC_STATUS_DECODE_TOBECONTINUE: + return FXCODEC_STATUS_ERROR; + default:; + } + if (pFile == NULL) { + m_status = FXCODEC_STATUS_ERR_PARAMS; + m_pFile = NULL; + return m_status; + } + m_pFile = pFile; + m_offSet = 0; + m_SrcWidth = m_SrcHeight = 0; + m_SrcComponents = m_SrcBPC = 0; + m_clipBox = FX_RECT(0, 0, 0, 0); + m_startX = m_startY = 0; + m_sizeX = m_sizeY = 0; + m_SrcPassNumber = 0; + if (imageType != FXCODEC_IMAGE_UNKNOWN && + DetectImageType(imageType, pAttribute)) { + m_imagType = imageType; + m_status = FXCODEC_STATUS_FRAME_READY; + return m_status; + } + for (int type = FXCODEC_IMAGE_BMP; type < FXCODEC_IMAGE_MAX; type++) { + if (DetectImageType((FXCODEC_IMAGE_TYPE)type, pAttribute)) { + m_imagType = (FXCODEC_IMAGE_TYPE)type; + m_status = FXCODEC_STATUS_FRAME_READY; + return m_status; + } + } + m_status = FXCODEC_STATUS_ERR_FORMAT; + m_pFile = NULL; + return m_status; +} +void CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip) { + if (m_status != FXCODEC_STATUS_FRAME_READY) { + return; + } + if (clip->IsEmpty()) { + m_clipBox = FX_RECT(0, 0, 0, 0); + return; + } + if (clip->left < 0) { + clip->left = 0; + } + if (clip->right > m_SrcWidth) { + clip->right = m_SrcWidth; + } + if (clip->top < 0) { + clip->top = 0; + } + if (clip->bottom > m_SrcHeight) { + clip->bottom = m_SrcHeight; + } + if (clip->IsEmpty()) { + m_clipBox = FX_RECT(0, 0, 0, 0); + return; + } + m_clipBox = *clip; +} +void CCodec_ProgressiveDecoder::GetDownScale(int& down_scale) { + down_scale = 1; + int ratio_w = m_clipBox.Width() / m_sizeX; + int ratio_h = m_clipBox.Height() / m_sizeY; + int ratio = (ratio_w > ratio_h) ? ratio_h : ratio_w; + if (ratio >= 8) { + down_scale = 8; + } else if (ratio >= 4) { + down_scale = 4; + } else if (ratio >= 2) { + down_scale = 2; + } + m_clipBox.left /= down_scale; + m_clipBox.right /= down_scale; + m_clipBox.top /= down_scale; + m_clipBox.bottom /= down_scale; + if (m_clipBox.right == m_clipBox.left) { + m_clipBox.right = m_clipBox.left + 1; + } + if (m_clipBox.bottom == m_clipBox.top) { + m_clipBox.bottom = m_clipBox.top + 1; + } +} +void CCodec_ProgressiveDecoder::GetTransMethod(FXDIB_Format des_format, + FXCodec_Format src_format) { + switch (des_format) { + case FXDIB_1bppMask: + case FXDIB_1bppRgb: { + switch (src_format) { + case FXCodec_1bppGray: + m_TransMethod = 0; + break; + default: + m_TransMethod = -1; + } + } break; + case FXDIB_8bppMask: + case FXDIB_8bppRgb: { + switch (src_format) { + case FXCodec_1bppGray: + m_TransMethod = 1; + break; + case FXCodec_8bppGray: + m_TransMethod = 2; + break; + case FXCodec_1bppRgb: + case FXCodec_8bppRgb: + m_TransMethod = 3; + break; + case FXCodec_Rgb: + case FXCodec_Rgb32: + case FXCodec_Argb: + m_TransMethod = 4; + break; + case FXCodec_Cmyk: + m_TransMethod = 5; + break; + default: + m_TransMethod = -1; + } + } break; + case FXDIB_Rgb: { + switch (src_format) { + case FXCodec_1bppGray: + m_TransMethod = 6; + break; + case FXCodec_8bppGray: + m_TransMethod = 7; + break; + case FXCodec_1bppRgb: + case FXCodec_8bppRgb: + m_TransMethod = 8; + break; + case FXCodec_Rgb: + case FXCodec_Rgb32: + case FXCodec_Argb: + m_TransMethod = 9; + break; + case FXCodec_Cmyk: + m_TransMethod = 10; + break; + default: + m_TransMethod = -1; + } + } break; + case FXDIB_Rgb32: + case FXDIB_Argb: { + switch (src_format) { + case FXCodec_1bppGray: + m_TransMethod = 6; + break; + case FXCodec_8bppGray: + m_TransMethod = 7; + break; + case FXCodec_1bppRgb: + case FXCodec_8bppRgb: + if (des_format == FXDIB_Argb) { + m_TransMethod = 12; + } else { + m_TransMethod = 8; + } + break; + case FXCodec_Rgb: + case FXCodec_Rgb32: + m_TransMethod = 9; + break; + case FXCodec_Cmyk: + m_TransMethod = 10; + break; + case FXCodec_Argb: + m_TransMethod = 11; + break; + default: + m_TransMethod = -1; + } + } break; + default: + m_TransMethod = -1; + } +} +void _RGB2BGR(uint8_t* buffer, int width = 1) { + if (buffer && width > 0) { + uint8_t temp; + int i = 0; + int j = 0; + for (; i < width; i++, j += 3) { + temp = buffer[j]; + buffer[j] = buffer[j + 2]; + buffer[j + 2] = temp; + } + } +} +void CCodec_ProgressiveDecoder::ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, + int des_line, + uint8_t* src_scan, + FXCodec_Format src_format) { + int src_left = m_clipBox.left; + int des_left = m_startX; + uint8_t* des_scan = + pDeviceBitmap->GetBuffer() + des_line * pDeviceBitmap->GetPitch(); + int src_bpp = src_format & 0xff; + int des_bpp = pDeviceBitmap->GetBPP(); + int src_Bpp = src_bpp >> 3; + int des_Bpp = des_bpp >> 3; + src_scan += src_left * src_Bpp; + des_scan += des_left * des_Bpp; + for (int des_col = 0; des_col < m_sizeX; des_col++) { + PixelWeight* pPixelWeights = m_WeightHorz.GetPixelWeight(des_col); + switch (m_TransMethod) { + case -1: + return; + case 0: + return; + case 1: + return; + case 2: { + FX_DWORD des_g = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + des_g += pixel_weight * src_scan[j]; + } + *des_scan++ = (uint8_t)(des_g >> 16); + } break; + case 3: { + int des_r = 0, des_g = 0, des_b = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + unsigned long argb = m_pSrcPalette[src_scan[j]]; + des_r += pixel_weight * (uint8_t)(argb >> 16); + des_g += pixel_weight * (uint8_t)(argb >> 8); + des_b += pixel_weight * (uint8_t)argb; + } + *des_scan++ = + (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); + } break; + case 4: { + FX_DWORD des_b = 0, des_g = 0, des_r = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + const uint8_t* src_pixel = src_scan + j * src_Bpp; + des_b += pixel_weight * (*src_pixel++); + des_g += pixel_weight * (*src_pixel++); + des_r += pixel_weight * (*src_pixel); + } + *des_scan++ = + (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); + } break; + case 5: { + FX_DWORD des_b = 0, des_g = 0, des_r = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + const uint8_t* src_pixel = src_scan + j * src_Bpp; + uint8_t src_b = 0, src_g = 0, src_r = 0; + AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], + 255 - src_pixel[2], 255 - src_pixel[3], src_r, + src_g, src_b); + des_b += pixel_weight * src_b; + des_g += pixel_weight * src_g; + des_r += pixel_weight * src_r; + } + *des_scan++ = + (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); + } break; + case 6: + return; + case 7: { + FX_DWORD des_g = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + des_g += pixel_weight * src_scan[j]; + } + FXSYS_memset(des_scan, (uint8_t)(des_g >> 16), 3); + des_scan += des_Bpp; + } break; + case 8: { + int des_r = 0, des_g = 0, des_b = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + unsigned long argb = m_pSrcPalette[src_scan[j]]; + des_r += pixel_weight * (uint8_t)(argb >> 16); + des_g += pixel_weight * (uint8_t)(argb >> 8); + des_b += pixel_weight * (uint8_t)argb; + } + *des_scan++ = (uint8_t)((des_b) >> 16); + *des_scan++ = (uint8_t)((des_g) >> 16); + *des_scan++ = (uint8_t)((des_r) >> 16); + des_scan += des_Bpp - 3; + } break; + case 12: { + if (m_pBmpContext) { + int des_r = 0, des_g = 0, des_b = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + unsigned long argb = m_pSrcPalette[src_scan[j]]; + des_r += pixel_weight * (uint8_t)(argb >> 16); + des_g += pixel_weight * (uint8_t)(argb >> 8); + des_b += pixel_weight * (uint8_t)argb; + } + *des_scan++ = (uint8_t)((des_b) >> 16); + *des_scan++ = (uint8_t)((des_g) >> 16); + *des_scan++ = (uint8_t)((des_r) >> 16); + *des_scan++ = 0xFF; + } else { + int des_a = 0, des_r = 0, des_g = 0, des_b = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + unsigned long argb = m_pSrcPalette[src_scan[j]]; + des_a += pixel_weight * (uint8_t)(argb >> 24); + des_r += pixel_weight * (uint8_t)(argb >> 16); + des_g += pixel_weight * (uint8_t)(argb >> 8); + des_b += pixel_weight * (uint8_t)argb; + } + *des_scan++ = (uint8_t)((des_b) >> 16); + *des_scan++ = (uint8_t)((des_g) >> 16); + *des_scan++ = (uint8_t)((des_r) >> 16); + *des_scan++ = (uint8_t)((des_a) >> 16); + } + } break; + case 9: { + FX_DWORD des_b = 0, des_g = 0, des_r = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + const uint8_t* src_pixel = src_scan + j * src_Bpp; + des_b += pixel_weight * (*src_pixel++); + des_g += pixel_weight * (*src_pixel++); + des_r += pixel_weight * (*src_pixel); + } + *des_scan++ = (uint8_t)((des_b) >> 16); + *des_scan++ = (uint8_t)((des_g) >> 16); + *des_scan++ = (uint8_t)((des_r) >> 16); + des_scan += des_Bpp - 3; + } break; + case 10: { + FX_DWORD des_b = 0, des_g = 0, des_r = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + const uint8_t* src_pixel = src_scan + j * src_Bpp; + uint8_t src_b = 0, src_g = 0, src_r = 0; + AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], + 255 - src_pixel[2], 255 - src_pixel[3], src_r, + src_g, src_b); + des_b += pixel_weight * src_b; + des_g += pixel_weight * src_g; + des_r += pixel_weight * src_r; + } + *des_scan++ = (uint8_t)((des_b) >> 16); + *des_scan++ = (uint8_t)((des_g) >> 16); + *des_scan++ = (uint8_t)((des_r) >> 16); + des_scan += des_Bpp - 3; + } break; + case 11: { + FX_DWORD des_alpha = 0, des_r = 0, des_g = 0, des_b = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + const uint8_t* src_pixel = src_scan + j * src_Bpp; + pixel_weight = pixel_weight * src_pixel[3] / 255; + des_b += pixel_weight * (*src_pixel++); + des_g += pixel_weight * (*src_pixel++); + des_r += pixel_weight * (*src_pixel); + des_alpha += pixel_weight; + } + *des_scan++ = (uint8_t)((des_b) >> 16); + *des_scan++ = (uint8_t)((des_g) >> 16); + *des_scan++ = (uint8_t)((des_r) >> 16); + *des_scan++ = (uint8_t)((des_alpha * 255) >> 16); + } break; + default: + return; + } + } +} +void CCodec_ProgressiveDecoder::ResampleVert(CFX_DIBitmap* pDeviceBitmap, + double scale_y, + int des_row) { + int des_Bpp = pDeviceBitmap->GetBPP() >> 3; + FX_DWORD des_ScanOffet = m_startX * des_Bpp; + if (m_bInterpol) { + int des_top = m_startY; + int des_row_1 = des_row - int(scale_y); + if (des_row_1 < des_top) { + int des_bottom = des_top + m_sizeY; + if (des_row + (int)scale_y >= des_bottom - 1) { + uint8_t* scan_src = + (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; + while (++des_row < des_bottom) { + uint8_t* scan_des = + (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; + FX_DWORD size = m_sizeX * des_Bpp; + FXSYS_memcpy(scan_des, scan_src, size); + } + } + return; + } + for (; des_row_1 < des_row; des_row_1++) { + uint8_t* scan_des = + (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; + PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); + const uint8_t* scan_src1 = + pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + + des_ScanOffet; + const uint8_t* scan_src2 = + pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + + des_ScanOffet; + for (int des_col = 0; des_col < m_sizeX; des_col++) { + switch (pDeviceBitmap->GetFormat()) { + case FXDIB_Invalid: + case FXDIB_1bppMask: + case FXDIB_1bppRgb: + return; + case FXDIB_8bppMask: + case FXDIB_8bppRgb: { + if (pDeviceBitmap->GetPalette() != NULL) { + return; + } + int des_g = 0; + des_g += pWeight->m_Weights[0] * (*scan_src1++); + des_g += pWeight->m_Weights[1] * (*scan_src2++); + *scan_des++ = (uint8_t)(des_g >> 16); + } break; + case FXDIB_Rgb: + case FXDIB_Rgb32: { + FX_DWORD des_b = 0, des_g = 0, des_r = 0; + des_b += pWeight->m_Weights[0] * (*scan_src1++); + des_g += pWeight->m_Weights[0] * (*scan_src1++); + des_r += pWeight->m_Weights[0] * (*scan_src1++); + scan_src1 += des_Bpp - 3; + des_b += pWeight->m_Weights[1] * (*scan_src2++); + des_g += pWeight->m_Weights[1] * (*scan_src2++); + des_r += pWeight->m_Weights[1] * (*scan_src2++); + scan_src2 += des_Bpp - 3; + *scan_des++ = (uint8_t)((des_b) >> 16); + *scan_des++ = (uint8_t)((des_g) >> 16); + *scan_des++ = (uint8_t)((des_r) >> 16); + scan_des += des_Bpp - 3; + } break; + case FXDIB_Argb: { + FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; + des_b += pWeight->m_Weights[0] * (*scan_src1++); + des_g += pWeight->m_Weights[0] * (*scan_src1++); + des_r += pWeight->m_Weights[0] * (*scan_src1++); + des_a += pWeight->m_Weights[0] * (*scan_src1++); + des_b += pWeight->m_Weights[1] * (*scan_src2++); + des_g += pWeight->m_Weights[1] * (*scan_src2++); + des_r += pWeight->m_Weights[1] * (*scan_src2++); + des_a += pWeight->m_Weights[1] * (*scan_src2++); + *scan_des++ = (uint8_t)((des_b) >> 16); + *scan_des++ = (uint8_t)((des_g) >> 16); + *scan_des++ = (uint8_t)((des_r) >> 16); + *scan_des++ = (uint8_t)((des_a) >> 16); + } break; + default: + return; + } + } + } + int des_bottom = des_top + m_sizeY; + if (des_row + (int)scale_y >= des_bottom - 1) { + uint8_t* scan_src = + (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; + while (++des_row < des_bottom) { + uint8_t* scan_des = + (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; + FX_DWORD size = m_sizeX * des_Bpp; + FXSYS_memcpy(scan_des, scan_src, size); + } + } + return; + } + int multiple = (int)FXSYS_ceil((FX_FLOAT)scale_y - 1); + if (multiple > 0) { + uint8_t* scan_src = + (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; + for (int i = 1; i <= multiple; i++) { + if (des_row + i >= m_startY + m_sizeY) { + return; + } + uint8_t* scan_des = + (uint8_t*)pDeviceBitmap->GetScanline(des_row + i) + des_ScanOffet; + FX_DWORD size = m_sizeX * des_Bpp; + FXSYS_memcpy(scan_des, scan_src, size); + } + } +} +void CCodec_ProgressiveDecoder::Resample(CFX_DIBitmap* pDeviceBitmap, + int32_t src_line, + uint8_t* src_scan, + FXCodec_Format src_format) { + int src_top = m_clipBox.top; + int des_top = m_startY; + int src_hei = m_clipBox.Height(); + int des_hei = m_sizeY; + if (src_line >= src_top) { + double scale_y = (double)des_hei / (double)src_hei; + int src_row = src_line - src_top; + int des_row = (int)(src_row * scale_y) + des_top; + if (des_row >= des_top + des_hei) { + return; + } + ReSampleScanline(pDeviceBitmap, des_row, m_pDecodeBuf, src_format); + if (scale_y > 1.0) { + ResampleVert(pDeviceBitmap, scale_y, des_row); + } + } +} +FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames, + IFX_Pause* pPause) { + if (!(m_status == FXCODEC_STATUS_FRAME_READY || + m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) { + return FXCODEC_STATUS_ERROR; + } + switch (m_imagType) { + case FXCODEC_IMAGE_BMP: + case FXCODEC_IMAGE_JPG: + case FXCODEC_IMAGE_PNG: + case FXCODEC_IMAGE_TIF: + frames = m_FrameNumber = 1; + return m_status = FXCODEC_STATUS_DECODE_READY; + case FXCODEC_IMAGE_GIF: { + ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); + while (TRUE) { + int32_t readResult = + pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); + while (readResult == 2) { + FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ; + if (!GifReadMoreData(pGifModule, error_status)) { + return error_status; + } + if (pPause && pPause->NeedToPauseNow()) { + return m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE; + } + readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); + } + if (readResult == 1) { + frames = m_FrameNumber; + return m_status = FXCODEC_STATUS_DECODE_READY; + } + if (m_pGifContext != NULL) { + pGifModule->Finish(m_pGifContext); + m_pGifContext = NULL; + } + return m_status = FXCODEC_STATUS_ERROR; + } + } break; + default:; + } + return FXCODEC_STATUS_ERROR; +} +FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, + int start_x, + int start_y, + int size_x, + int size_y, + int32_t frames, + FX_BOOL bInterpol) { + if (m_status != FXCODEC_STATUS_DECODE_READY) { + return FXCODEC_STATUS_ERROR; + } + if (pDIBitmap == NULL || pDIBitmap->GetBPP() < 8 || frames < 0 || + frames >= m_FrameNumber) { + return FXCODEC_STATUS_ERR_PARAMS; + } + m_pDeviceBitmap = pDIBitmap; + if (m_clipBox.IsEmpty()) { + return FXCODEC_STATUS_ERR_PARAMS; + } + if (size_x <= 0 || size_x > 65535 || size_y <= 0 || size_y > 65535) { + return FXCODEC_STATUS_ERR_PARAMS; + } + FX_RECT device_rc = + FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y); + int32_t out_range_x = device_rc.right - pDIBitmap->GetWidth(); + int32_t out_range_y = device_rc.bottom - pDIBitmap->GetHeight(); + device_rc.Intersect( + FX_RECT(0, 0, pDIBitmap->GetWidth(), pDIBitmap->GetHeight())); + if (device_rc.IsEmpty()) { + return FXCODEC_STATUS_ERR_PARAMS; + } + m_startX = device_rc.left; + m_startY = device_rc.top; + m_sizeX = device_rc.Width(); + m_sizeY = device_rc.Height(); + m_bInterpol = bInterpol; + m_FrameCur = 0; + if (start_x < 0 || out_range_x > 0) { + FX_FLOAT scaleX = (FX_FLOAT)m_clipBox.Width() / (FX_FLOAT)size_x; + if (start_x < 0) { + m_clipBox.left -= (int32_t)FXSYS_ceil((FX_FLOAT)start_x * scaleX); + } + if (out_range_x > 0) { + m_clipBox.right -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_x * scaleX); + } + } + if (start_y < 0 || out_range_y > 0) { + FX_FLOAT scaleY = (FX_FLOAT)m_clipBox.Height() / (FX_FLOAT)size_y; + if (start_y < 0) { + m_clipBox.top -= (int32_t)FXSYS_ceil((FX_FLOAT)start_y * scaleY); + } + if (out_range_y > 0) { + m_clipBox.bottom -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_y * scaleY); + } + } + if (m_clipBox.IsEmpty()) { + return FXCODEC_STATUS_ERR_PARAMS; + } + switch (m_imagType) { + case FXCODEC_IMAGE_JPG: { + ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); + int down_scale = 1; + GetDownScale(down_scale); + FX_BOOL bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); + while (!bStart) { + FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; + if (!JpegReadMoreData(pJpegModule, error_status)) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = error_status; + } + bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); + } + int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale; + scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4; + if (m_pDecodeBuf != NULL) { + FX_Free(m_pDecodeBuf); + m_pDecodeBuf = NULL; + } + m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); + if (m_pDecodeBuf == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + FXSYS_memset(m_pDecodeBuf, 0, scanline_size); + m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, + m_clipBox.Width(), m_bInterpol); + m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); + switch (m_SrcComponents) { + case 1: + m_SrcFormat = FXCodec_8bppGray; + break; + case 3: + m_SrcFormat = FXCodec_Rgb; + break; + case 4: + m_SrcFormat = FXCodec_Cmyk; + break; + } + GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat); + return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; + } break; + case FXCODEC_IMAGE_PNG: { + ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); + if (pPngModule == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + if (m_pPngContext != NULL) { + pPngModule->Finish(m_pPngContext); + m_pPngContext = NULL; + } + m_pPngContext = pPngModule->Start((void*)this); + if (m_pPngContext == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + m_offSet = 0; + switch (m_pDeviceBitmap->GetFormat()) { + case FXDIB_8bppMask: + case FXDIB_8bppRgb: + m_SrcComponents = 1; + m_SrcFormat = FXCodec_8bppGray; + break; + case FXDIB_Rgb: + m_SrcComponents = 3; + m_SrcFormat = FXCodec_Rgb; + break; + case FXDIB_Rgb32: + case FXDIB_Argb: + m_SrcComponents = 4; + m_SrcFormat = FXCodec_Argb; + break; + default: { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_PARAMS; + } + } + GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); + int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; + if (m_pDecodeBuf != NULL) { + FX_Free(m_pDecodeBuf); + m_pDecodeBuf = NULL; + } + m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); + if (m_pDecodeBuf == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + FXSYS_memset(m_pDecodeBuf, 0, scanline_size); + m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width(), m_bInterpol); + m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); + return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; + } break; + case FXCODEC_IMAGE_GIF: { + ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); + if (pGifModule == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + m_SrcFormat = FXCodec_8bppRgb; + GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); + int scanline_size = (m_SrcWidth + 3) / 4 * 4; + if (m_pDecodeBuf != NULL) { + FX_Free(m_pDecodeBuf); + m_pDecodeBuf = NULL; + } + m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); + if (m_pDecodeBuf == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + FXSYS_memset(m_pDecodeBuf, 0, scanline_size); + m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, + m_clipBox.Width(), m_bInterpol); + m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); + m_FrameCur = frames; + return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; + } break; + case FXCODEC_IMAGE_BMP: { + ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); + if (pBmpModule == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + switch (m_SrcComponents) { + case 1: + m_SrcFormat = FXCodec_8bppRgb; + break; + case 3: + m_SrcFormat = FXCodec_Rgb; + break; + case 4: + m_SrcFormat = FXCodec_Rgb32; + break; + } + GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); + m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; + if (m_pDecodeBuf != NULL) { + FX_Free(m_pDecodeBuf); + m_pDecodeBuf = NULL; + } + m_pDecodeBuf = FX_Alloc(uint8_t, m_ScanlineSize); + if (m_pDecodeBuf == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + FXSYS_memset(m_pDecodeBuf, 0, m_ScanlineSize); + m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, + m_clipBox.Width(), m_bInterpol); + m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); + return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; + } break; + case FXCODEC_IMAGE_TIF: + return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; + default: + break; + } + return FXCODEC_STATUS_ERROR; +} +FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { + if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE) { + return FXCODEC_STATUS_ERROR; + } + switch (m_imagType) { + case FXCODEC_IMAGE_JPG: { + ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); + while (TRUE) { + FX_BOOL readRes = + pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); + while (!readRes) { + FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; + if (!JpegReadMoreData(pJpegModule, error_status)) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = error_status; + } + readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); + } + if (m_SrcFormat == FXCodec_Rgb) { + int src_Bpp = (m_SrcFormat & 0xff) >> 3; + _RGB2BGR(m_pDecodeBuf + m_clipBox.left * src_Bpp, m_clipBox.Width()); + } + if (m_SrcRow >= m_clipBox.bottom) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_DECODE_FINISH; + } + Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat); + m_SrcRow++; + if (pPause && pPause->NeedToPauseNow()) { + return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; + } + } + } break; + case FXCODEC_IMAGE_PNG: { + ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); + while (TRUE) { + FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; + FX_DWORD input_size = + remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; + if (input_size == 0) { + if (m_pPngContext != NULL) { + pPngModule->Finish(m_pPngContext); + } + m_pPngContext = NULL; + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_DECODE_FINISH; + } + if (m_pSrcBuf != NULL && input_size > m_SrcSize) { + FX_Free(m_pSrcBuf); + m_pSrcBuf = FX_Alloc(uint8_t, input_size); + if (m_pSrcBuf == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + FXSYS_memset(m_pSrcBuf, 0, input_size); + m_SrcSize = input_size; + } + FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); + if (!bResult) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_READ; + } + m_offSet += input_size; + bResult = + pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, nullptr); + if (!bResult) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERROR; + } + if (pPause && pPause->NeedToPauseNow()) { + return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; + } + } + } break; + case FXCODEC_IMAGE_GIF: { + ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); + while (TRUE) { + int32_t readRes = + pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); + while (readRes == 2) { + FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; + if (!GifReadMoreData(pGifModule, error_status)) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = error_status; + } + if (pPause && pPause->NeedToPauseNow()) { + return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; + } + readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); + } + if (readRes == 1) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_DECODE_FINISH; + } + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERROR; + } + } break; + case FXCODEC_IMAGE_BMP: { + ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); + while (TRUE) { + int32_t readRes = pBmpModule->LoadImage(m_pBmpContext); + while (readRes == 2) { + FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; + if (!BmpReadMoreData(pBmpModule, error_status)) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = error_status; + } + if (pPause && pPause->NeedToPauseNow()) { + return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; + } + readRes = pBmpModule->LoadImage(m_pBmpContext); + } + if (readRes == 1) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_DECODE_FINISH; + } + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERROR; + } + } break; + case FXCODEC_IMAGE_TIF: { + ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); + FX_BOOL ret = FALSE; + if (m_pDeviceBitmap->GetBPP() == 32 && + m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX && + m_pDeviceBitmap->GetHeight() == m_SrcHeight && + m_SrcHeight == m_sizeY && m_startX == 0 && m_startY == 0 && + m_clipBox.left == 0 && m_clipBox.top == 0 && + m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) { + ret = pTiffModule->Decode(m_pTiffContext, m_pDeviceBitmap); + m_pDeviceBitmap = NULL; + m_pFile = NULL; + if (!ret) { + return m_status = FXCODEC_STATUS_ERROR; + } + return m_status = FXCODEC_STATUS_DECODE_FINISH; + } else { + CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; + pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb); + if (pDIBitmap->GetBuffer() == NULL) { + delete pDIBitmap; + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap); + if (!ret) { + delete pDIBitmap; + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERROR; + } + CFX_DIBitmap* pClipBitmap = + (m_clipBox.left == 0 && m_clipBox.top == 0 && + m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) + ? pDIBitmap + : pDIBitmap->Clone(&m_clipBox); + if (pDIBitmap != pClipBitmap) { + delete pDIBitmap; + } + if (pClipBitmap == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + CFX_DIBitmap* pFormatBitmap = NULL; + switch (m_pDeviceBitmap->GetFormat()) { + case FXDIB_8bppRgb: + pFormatBitmap = new CFX_DIBitmap; + pFormatBitmap->Create(pClipBitmap->GetWidth(), + pClipBitmap->GetHeight(), FXDIB_8bppRgb); + break; + case FXDIB_8bppMask: + pFormatBitmap = new CFX_DIBitmap; + pFormatBitmap->Create(pClipBitmap->GetWidth(), + pClipBitmap->GetHeight(), FXDIB_8bppMask); + break; + case FXDIB_Rgb: + pFormatBitmap = new CFX_DIBitmap; + pFormatBitmap->Create(pClipBitmap->GetWidth(), + pClipBitmap->GetHeight(), FXDIB_Rgb); + break; + case FXDIB_Rgb32: + pFormatBitmap = new CFX_DIBitmap; + pFormatBitmap->Create(pClipBitmap->GetWidth(), + pClipBitmap->GetHeight(), FXDIB_Rgb32); + break; + case FXDIB_Argb: + pFormatBitmap = pClipBitmap; + break; + default:; + } + switch (m_pDeviceBitmap->GetFormat()) { + case FXDIB_8bppRgb: + case FXDIB_8bppMask: { + for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { + uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); + uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); + for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { + uint8_t _a = 255 - src_line[3]; + uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; + uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; + uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; + *des_line++ = FXRGB2GRAY(r, g, b); + src_line += 4; + } + } + } break; + case FXDIB_Rgb: + case FXDIB_Rgb32: { + int32_t desBpp = + (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4; + for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { + uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); + uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); + for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { + uint8_t _a = 255 - src_line[3]; + uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; + uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; + uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; + *des_line++ = b; + *des_line++ = g; + *des_line++ = r; + des_line += desBpp - 3; + src_line += 4; + } + } + } break; + default:; + } + if (pClipBitmap != pFormatBitmap) { + delete pClipBitmap; + } + if (pFormatBitmap == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + CFX_DIBitmap* pStrechBitmap = pFormatBitmap->StretchTo( + m_sizeX, m_sizeY, m_bInterpol ? FXDIB_INTERPOL : FXDIB_DOWNSAMPLE); + delete pFormatBitmap; + pFormatBitmap = NULL; + if (pStrechBitmap == NULL) { + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_ERR_MEMORY; + } + m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY, + pStrechBitmap, 0, 0); + delete pStrechBitmap; + pStrechBitmap = NULL; + m_pDeviceBitmap = NULL; + m_pFile = NULL; + return m_status = FXCODEC_STATUS_DECODE_FINISH; + } + } break; + default: + break; + } + return FXCODEC_STATUS_ERROR; +} +ICodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder() { + return new CCodec_ProgressiveDecoder(this); +} diff --git a/core/src/fxcodec/codec/fx_codec_progress.h b/core/src/fxcodec/codec/fx_codec_progress.h index cee8b39c50..2da92c9b01 100644 --- a/core/src/fxcodec/codec/fx_codec_progress.h +++ b/core/src/fxcodec/codec/fx_codec_progress.h @@ -1,223 +1,223 @@ -// 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 - -#ifndef _FX_CODEC_PROGRESS_H_ -#define _FX_CODEC_PROGRESS_H_ -#define FXCODEC_BLOCK_SIZE 4096 -#define FXCODEC_PNG_GAMMA 2.2 -#if _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_ -#undef FXCODEC_PNG_GAMMA -#define FXCODEC_PNG_GAMMA 1.7 -#endif -struct PixelWeight { - int m_SrcStart; - int m_SrcEnd; - int m_Weights[1]; -}; -class CFXCODEC_WeightTable { - public: - CFXCODEC_WeightTable() { m_pWeightTables = NULL; } - ~CFXCODEC_WeightTable() { - if (m_pWeightTables != NULL) { - FX_Free(m_pWeightTables); - } - } - - void Calc(int dest_len, - int dest_min, - int dest_max, - int src_len, - int src_min, - int src_max, - FX_BOOL bInterpol); - PixelWeight* GetPixelWeight(int pixel) { - return (PixelWeight*)(m_pWeightTables + (pixel - m_DestMin) * m_ItemSize); - } - - int m_DestMin, m_ItemSize; - uint8_t* m_pWeightTables; -}; -class CFXCODEC_HorzTable { - public: - CFXCODEC_HorzTable() { m_pWeightTables = NULL; } - ~CFXCODEC_HorzTable() { - if (m_pWeightTables != NULL) { - FX_Free(m_pWeightTables); - } - } - - void Calc(int dest_len, int src_len, FX_BOOL bInterpol); - PixelWeight* GetPixelWeight(int pixel) { - return (PixelWeight*)(m_pWeightTables + pixel * m_ItemSize); - } - - int m_ItemSize; - uint8_t* m_pWeightTables; -}; -class CFXCODEC_VertTable { - public: - CFXCODEC_VertTable() { m_pWeightTables = NULL; } - ~CFXCODEC_VertTable() { - if (m_pWeightTables != NULL) { - FX_Free(m_pWeightTables); - } - } - void Calc(int dest_len, int src_len); - PixelWeight* GetPixelWeight(int pixel) { - return (PixelWeight*)(m_pWeightTables + pixel * m_ItemSize); - } - int m_ItemSize; - uint8_t* m_pWeightTables; -}; -enum FXCodec_Format { - FXCodec_Invalid = 0, - FXCodec_1bppGray = 0x101, - FXCodec_1bppRgb = 0x001, - FXCodec_8bppGray = 0x108, - FXCodec_8bppRgb = 0x008, - FXCodec_Rgb = 0x018, - FXCodec_Rgb32 = 0x020, - FXCodec_Argb = 0x220, - FXCodec_Cmyk = 0x120 -}; -class CCodec_ProgressiveDecoder : public ICodec_ProgressiveDecoder { - public: - CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr); - ~CCodec_ProgressiveDecoder() override; - - FXCODEC_STATUS LoadImageInfo(IFX_FileRead* pFile, - FXCODEC_IMAGE_TYPE imageType, - CFX_DIBAttribute* pAttribute) override; - - FXCODEC_IMAGE_TYPE GetType() const override { return m_imagType; } - int32_t GetWidth() const override { return m_SrcWidth; } - int32_t GetHeight() const override { return m_SrcHeight; } - int32_t GetNumComponents() const override { return m_SrcComponents; } - int32_t GetBPC() const override { return m_SrcBPC; } - void SetClipBox(FX_RECT* clip) override; - - FXCODEC_STATUS GetFrames(int32_t& frames, IFX_Pause* pPause) override; - FXCODEC_STATUS StartDecode(CFX_DIBitmap* pDIBitmap, - int start_x, - int start_y, - int size_x, - int size_y, - int32_t frames, - FX_BOOL bInterpol) override; - - FXCODEC_STATUS ContinueDecode(IFX_Pause* pPause) override; - - protected: - static FX_BOOL PngReadHeaderFunc(void* pModule, - int width, - int height, - int bpc, - int pass, - int* color_type, - double* gamma); - static FX_BOOL PngAskScanlineBufFunc(void* pModule, - int line, - uint8_t*& src_buf); - static void PngFillScanlineBufCompletedFunc(void* pModule, - int pass, - int line); - static void GifRecordCurrentPositionCallback(void* pModule, - FX_DWORD& cur_pos); - static uint8_t* GifAskLocalPaletteBufCallback(void* pModule, - int32_t frame_num, - int32_t pal_size); - static FX_BOOL GifInputRecordPositionBufCallback(void* pModule, - FX_DWORD rcd_pos, - const FX_RECT& img_rc, - int32_t pal_num, - void* pal_ptr, - int32_t delay_time, - FX_BOOL user_input, - int32_t trans_index, - int32_t disposal_method, - FX_BOOL interlace); - static void GifReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf); - static FX_BOOL BmpInputImagePositionBufCallback(void* pModule, - FX_DWORD rcd_pos); - static void BmpReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf); - - FX_BOOL DetectImageType(FXCODEC_IMAGE_TYPE imageType, - CFX_DIBAttribute* pAttribute); - void GetDownScale(int& down_scale); - void GetTransMethod(FXDIB_Format des_format, FXCodec_Format src_format); - void ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, - int32_t des_line, - uint8_t* src_scan, - FXCodec_Format src_format); - void Resample(CFX_DIBitmap* pDeviceBitmap, - int32_t src_line, - uint8_t* src_scan, - FXCodec_Format src_format); - void ResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); - FX_BOOL JpegReadMoreData(ICodec_JpegModule* pJpegModule, - FXCODEC_STATUS& err_status); - void PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, - int32_t des_line, - uint8_t* src_scan, - FXCodec_Format src_format); - FX_BOOL GifReadMoreData(ICodec_GifModule* pGifModule, - FXCODEC_STATUS& err_status); - void GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, - double scale_y, - int des_row); - FX_BOOL BmpReadMoreData(ICodec_BmpModule* pBmpModule, - FXCODEC_STATUS& err_status); - void ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); - - public: - IFX_FileRead* m_pFile; - CCodec_ModuleMgr* m_pCodecMgr; - void* m_pJpegContext; - void* m_pPngContext; - void* m_pGifContext; - void* m_pBmpContext; - void* m_pTiffContext; - FXCODEC_IMAGE_TYPE m_imagType; - FX_DWORD m_offSet; - uint8_t* m_pSrcBuf; - FX_DWORD m_SrcSize; - uint8_t* m_pDecodeBuf; - int m_ScanlineSize; - CFX_DIBitmap* m_pDeviceBitmap; - FX_BOOL m_bInterpol; - CFXCODEC_WeightTable m_WeightHorz; - CFXCODEC_VertTable m_WeightVert; - CFXCODEC_HorzTable m_WeightHorzOO; - int m_SrcWidth; - int m_SrcHeight; - int m_SrcComponents; - int m_SrcBPC; - FX_RECT m_clipBox; - int m_startX; - int m_startY; - int m_sizeX; - int m_sizeY; - int m_TransMethod; - FX_ARGB* m_pSrcPalette; - int m_SrcPaletteNumber; - int m_SrcRow; - FXCodec_Format m_SrcFormat; - int m_SrcPassNumber; - int m_FrameNumber; - int m_FrameCur; - int m_GifBgIndex; - uint8_t* m_pGifPalette; - int32_t m_GifPltNumber; - int m_GifTransIndex; - FX_RECT m_GifFrameRect; - FX_BOOL m_BmpIsTopBottom; - FXCODEC_STATUS m_status; -}; -#endif +// 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 + +#ifndef _FX_CODEC_PROGRESS_H_ +#define _FX_CODEC_PROGRESS_H_ +#define FXCODEC_BLOCK_SIZE 4096 +#define FXCODEC_PNG_GAMMA 2.2 +#if _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_ +#undef FXCODEC_PNG_GAMMA +#define FXCODEC_PNG_GAMMA 1.7 +#endif +struct PixelWeight { + int m_SrcStart; + int m_SrcEnd; + int m_Weights[1]; +}; +class CFXCODEC_WeightTable { + public: + CFXCODEC_WeightTable() { m_pWeightTables = NULL; } + ~CFXCODEC_WeightTable() { + if (m_pWeightTables != NULL) { + FX_Free(m_pWeightTables); + } + } + + void Calc(int dest_len, + int dest_min, + int dest_max, + int src_len, + int src_min, + int src_max, + FX_BOOL bInterpol); + PixelWeight* GetPixelWeight(int pixel) { + return (PixelWeight*)(m_pWeightTables + (pixel - m_DestMin) * m_ItemSize); + } + + int m_DestMin, m_ItemSize; + uint8_t* m_pWeightTables; +}; +class CFXCODEC_HorzTable { + public: + CFXCODEC_HorzTable() { m_pWeightTables = NULL; } + ~CFXCODEC_HorzTable() { + if (m_pWeightTables != NULL) { + FX_Free(m_pWeightTables); + } + } + + void Calc(int dest_len, int src_len, FX_BOOL bInterpol); + PixelWeight* GetPixelWeight(int pixel) { + return (PixelWeight*)(m_pWeightTables + pixel * m_ItemSize); + } + + int m_ItemSize; + uint8_t* m_pWeightTables; +}; +class CFXCODEC_VertTable { + public: + CFXCODEC_VertTable() { m_pWeightTables = NULL; } + ~CFXCODEC_VertTable() { + if (m_pWeightTables != NULL) { + FX_Free(m_pWeightTables); + } + } + void Calc(int dest_len, int src_len); + PixelWeight* GetPixelWeight(int pixel) { + return (PixelWeight*)(m_pWeightTables + pixel * m_ItemSize); + } + int m_ItemSize; + uint8_t* m_pWeightTables; +}; +enum FXCodec_Format { + FXCodec_Invalid = 0, + FXCodec_1bppGray = 0x101, + FXCodec_1bppRgb = 0x001, + FXCodec_8bppGray = 0x108, + FXCodec_8bppRgb = 0x008, + FXCodec_Rgb = 0x018, + FXCodec_Rgb32 = 0x020, + FXCodec_Argb = 0x220, + FXCodec_Cmyk = 0x120 +}; +class CCodec_ProgressiveDecoder : public ICodec_ProgressiveDecoder { + public: + CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr); + ~CCodec_ProgressiveDecoder() override; + + FXCODEC_STATUS LoadImageInfo(IFX_FileRead* pFile, + FXCODEC_IMAGE_TYPE imageType, + CFX_DIBAttribute* pAttribute) override; + + FXCODEC_IMAGE_TYPE GetType() const override { return m_imagType; } + int32_t GetWidth() const override { return m_SrcWidth; } + int32_t GetHeight() const override { return m_SrcHeight; } + int32_t GetNumComponents() const override { return m_SrcComponents; } + int32_t GetBPC() const override { return m_SrcBPC; } + void SetClipBox(FX_RECT* clip) override; + + FXCODEC_STATUS GetFrames(int32_t& frames, IFX_Pause* pPause) override; + FXCODEC_STATUS StartDecode(CFX_DIBitmap* pDIBitmap, + int start_x, + int start_y, + int size_x, + int size_y, + int32_t frames, + FX_BOOL bInterpol) override; + + FXCODEC_STATUS ContinueDecode(IFX_Pause* pPause) override; + + protected: + static FX_BOOL PngReadHeaderFunc(void* pModule, + int width, + int height, + int bpc, + int pass, + int* color_type, + double* gamma); + static FX_BOOL PngAskScanlineBufFunc(void* pModule, + int line, + uint8_t*& src_buf); + static void PngFillScanlineBufCompletedFunc(void* pModule, + int pass, + int line); + static void GifRecordCurrentPositionCallback(void* pModule, + FX_DWORD& cur_pos); + static uint8_t* GifAskLocalPaletteBufCallback(void* pModule, + int32_t frame_num, + int32_t pal_size); + static FX_BOOL GifInputRecordPositionBufCallback(void* pModule, + FX_DWORD rcd_pos, + const FX_RECT& img_rc, + int32_t pal_num, + void* pal_ptr, + int32_t delay_time, + FX_BOOL user_input, + int32_t trans_index, + int32_t disposal_method, + FX_BOOL interlace); + static void GifReadScanlineCallback(void* pModule, + int32_t row_num, + uint8_t* row_buf); + static FX_BOOL BmpInputImagePositionBufCallback(void* pModule, + FX_DWORD rcd_pos); + static void BmpReadScanlineCallback(void* pModule, + int32_t row_num, + uint8_t* row_buf); + + FX_BOOL DetectImageType(FXCODEC_IMAGE_TYPE imageType, + CFX_DIBAttribute* pAttribute); + void GetDownScale(int& down_scale); + void GetTransMethod(FXDIB_Format des_format, FXCodec_Format src_format); + void ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, + int32_t des_line, + uint8_t* src_scan, + FXCodec_Format src_format); + void Resample(CFX_DIBitmap* pDeviceBitmap, + int32_t src_line, + uint8_t* src_scan, + FXCodec_Format src_format); + void ResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); + FX_BOOL JpegReadMoreData(ICodec_JpegModule* pJpegModule, + FXCODEC_STATUS& err_status); + void PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, + int32_t des_line, + uint8_t* src_scan, + FXCodec_Format src_format); + FX_BOOL GifReadMoreData(ICodec_GifModule* pGifModule, + FXCODEC_STATUS& err_status); + void GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, + double scale_y, + int des_row); + FX_BOOL BmpReadMoreData(ICodec_BmpModule* pBmpModule, + FXCODEC_STATUS& err_status); + void ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); + + public: + IFX_FileRead* m_pFile; + CCodec_ModuleMgr* m_pCodecMgr; + void* m_pJpegContext; + void* m_pPngContext; + void* m_pGifContext; + void* m_pBmpContext; + void* m_pTiffContext; + FXCODEC_IMAGE_TYPE m_imagType; + FX_DWORD m_offSet; + uint8_t* m_pSrcBuf; + FX_DWORD m_SrcSize; + uint8_t* m_pDecodeBuf; + int m_ScanlineSize; + CFX_DIBitmap* m_pDeviceBitmap; + FX_BOOL m_bInterpol; + CFXCODEC_WeightTable m_WeightHorz; + CFXCODEC_VertTable m_WeightVert; + CFXCODEC_HorzTable m_WeightHorzOO; + int m_SrcWidth; + int m_SrcHeight; + int m_SrcComponents; + int m_SrcBPC; + FX_RECT m_clipBox; + int m_startX; + int m_startY; + int m_sizeX; + int m_sizeY; + int m_TransMethod; + FX_ARGB* m_pSrcPalette; + int m_SrcPaletteNumber; + int m_SrcRow; + FXCodec_Format m_SrcFormat; + int m_SrcPassNumber; + int m_FrameNumber; + int m_FrameCur; + int m_GifBgIndex; + uint8_t* m_pGifPalette; + int32_t m_GifPltNumber; + int m_GifTransIndex; + FX_RECT m_GifFrameRect; + FX_BOOL m_BmpIsTopBottom; + FXCODEC_STATUS m_status; +}; +#endif diff --git a/core/src/fxcodec/codec/fx_codec_tiff.cpp b/core/src/fxcodec/codec/fx_codec_tiff.cpp index d158c0009a..cfdc5feb97 100644 --- a/core/src/fxcodec/codec/fx_codec_tiff.cpp +++ b/core/src/fxcodec/codec/fx_codec_tiff.cpp @@ -1,544 +1,544 @@ -// 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/include/fxcodec/fx_codec.h" -#include "core/include/fxge/fx_dib.h" -#include "codec_int.h" - -extern "C" { -#include "third_party/libtiff/tiffiop.h" -} - -void* IccLib_CreateTransform_sRGB(const unsigned char* pProfileData, - unsigned int dwProfileSize, - int nComponents, - int intent, - FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT); -void IccLib_TranslateImage(void* pTransform, - unsigned char* pDest, - const unsigned char* pSrc, - int pixels); -void IccLib_DestroyTransform(void* pTransform); -class CCodec_TiffContext { - public: - CCodec_TiffContext(); - ~CCodec_TiffContext(); - - FX_BOOL InitDecoder(IFX_FileRead* file_ptr); - void GetFrames(int32_t& frames); - FX_BOOL LoadFrameInfo(int32_t frame, - FX_DWORD& width, - FX_DWORD& height, - FX_DWORD& comps, - FX_DWORD& bpc, - CFX_DIBAttribute* pAttribute); - FX_BOOL Decode(CFX_DIBitmap* pDIBitmap); - - union { - IFX_FileRead* in; - IFX_FileStream* out; - } io; - - FX_DWORD offset; - - TIFF* tif_ctx; - void* icc_ctx; - int32_t frame_num; - int32_t frame_cur; - FX_BOOL isDecoder; - - private: - FX_BOOL isSupport(CFX_DIBitmap* pDIBitmap); - void SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps); - FX_BOOL Decode1bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp); - FX_BOOL Decode8bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp); - FX_BOOL Decode24bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp); -}; -CCodec_TiffContext::CCodec_TiffContext() { - offset = 0; - frame_num = 0; - frame_cur = 0; - io.in = NULL; - tif_ctx = NULL; - icc_ctx = NULL; - isDecoder = TRUE; -} -CCodec_TiffContext::~CCodec_TiffContext() { - if (icc_ctx) { - IccLib_DestroyTransform(icc_ctx); - icc_ctx = NULL; - } - if (tif_ctx) { - TIFFClose(tif_ctx); - } -} -static tsize_t _tiff_read(thandle_t context, tdata_t buf, tsize_t length) { - CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; - FX_BOOL ret = FALSE; - if (pTiffContext->isDecoder) { - ret = pTiffContext->io.in->ReadBlock(buf, pTiffContext->offset, length); - } else { - ret = pTiffContext->io.out->ReadBlock(buf, pTiffContext->offset, length); - } - if (!ret) { - return 0; - } - pTiffContext->offset += (FX_DWORD)length; - return length; -} -static tsize_t _tiff_write(thandle_t context, tdata_t buf, tsize_t length) { - CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; - ASSERT(!pTiffContext->isDecoder); - if (!pTiffContext->io.out->WriteBlock(buf, pTiffContext->offset, length)) { - return 0; - } - pTiffContext->offset += (FX_DWORD)length; - return length; -} -static toff_t _tiff_seek(thandle_t context, toff_t offset, int whence) { - CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; - switch (whence) { - case 0: - pTiffContext->offset = (FX_DWORD)offset; - break; - case 1: - pTiffContext->offset += (FX_DWORD)offset; - break; - case 2: - if (pTiffContext->isDecoder) { - if (pTiffContext->io.in->GetSize() < (FX_FILESIZE)offset) { - return -1; - } - pTiffContext->offset = - (FX_DWORD)(pTiffContext->io.in->GetSize() - offset); - } else { - if (pTiffContext->io.out->GetSize() < (FX_FILESIZE)offset) { - return -1; - } - pTiffContext->offset = - (FX_DWORD)(pTiffContext->io.out->GetSize() - offset); - } - break; - default: - return -1; - } - ASSERT(pTiffContext->isDecoder ? (pTiffContext->offset <= - (FX_DWORD)pTiffContext->io.in->GetSize()) - : TRUE); - return pTiffContext->offset; -} -static int _tiff_close(thandle_t context) { - return 0; -} -static toff_t _tiff_get_size(thandle_t context) { - CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; - return pTiffContext->isDecoder ? (toff_t)pTiffContext->io.in->GetSize() - : (toff_t)pTiffContext->io.out->GetSize(); -} -static int _tiff_map(thandle_t context, tdata_t*, toff_t*) { - return 0; -} -static 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; -} -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); -} - -TIFFErrorHandler _TIFFwarningHandler = nullptr; -TIFFErrorHandler _TIFFerrorHandler = nullptr; - -int TIFFCmyk2Rgb(thandle_t context, - uint8 c, - uint8 m, - uint8 y, - uint8 k, - uint8* r, - uint8* g, - uint8* b) { - if (context == NULL) { - return 0; - } - CCodec_TiffContext* p = (CCodec_TiffContext*)context; - if (p->icc_ctx) { - unsigned char cmyk[4], bgr[3]; - cmyk[0] = c, cmyk[1] = m, cmyk[2] = y, cmyk[3] = k; - IccLib_TranslateImage(p->icc_ctx, bgr, cmyk, 1); - *r = bgr[2], *g = bgr[1], *b = bgr[0]; - } else { - AdobeCMYK_to_sRGB1(c, m, y, k, *r, *g, *b); - } - return 1; -} -FX_BOOL CCodec_TiffContext::InitDecoder(IFX_FileRead* file_ptr) { - io.in = file_ptr; - tif_ctx = _tiff_open(this, "r"); - if (tif_ctx == NULL) { - return FALSE; - } - return TRUE; -} -void CCodec_TiffContext::GetFrames(int32_t& frames) { - frames = frame_num = TIFFNumberOfDirectories(tif_ctx); -} -#define TIFF_EXIF_GETINFO(key, T, tag) \ - { \ - T val = (T)0; \ - TIFFGetField(tif_ctx, tag, &val); \ - if (val) { \ - (key) = FX_Alloc(uint8_t, sizeof(T)); \ - if ((key)) { \ - T* ptr = (T*)(key); \ - *ptr = val; \ - pExif->m_TagVal.SetAt(tag, (key)); \ - } \ - } \ - } \ - (key) = NULL; -#define TIFF_EXIF_GETSTRINGINFO(key, tag) \ - { \ - FX_DWORD size = 0; \ - uint8_t* buf = NULL; \ - TIFFGetField(tif_ctx, tag, &size, &buf); \ - if (size && buf) { \ - (key) = FX_Alloc(uint8_t, size); \ - if ((key)) { \ - FXSYS_memcpy((key), buf, size); \ - pExif->m_TagVal.SetAt(tag, (key)); \ - } \ - } \ - } \ - (key) = NULL; - -namespace { - -template -FX_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; -} - -} // namespace - -FX_BOOL CCodec_TiffContext::LoadFrameInfo(int32_t frame, - FX_DWORD& width, - FX_DWORD& height, - FX_DWORD& comps, - FX_DWORD& bpc, - CFX_DIBAttribute* pAttribute) { - if (!TIFFSetDirectory(tif_ctx, (uint16)frame)) { - return FALSE; - } - FX_WORD tif_cs; - FX_DWORD tif_icc_size = 0; - uint8_t* tif_icc_buf = NULL; - FX_WORD tif_bpc = 0; - FX_WORD tif_cps; - FX_DWORD tif_rps; - width = height = comps = 0; - TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height); - TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &comps); - TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc); - TIFFGetField(tif_ctx, TIFFTAG_PHOTOMETRIC, &tif_cs); - TIFFGetField(tif_ctx, TIFFTAG_COMPRESSION, &tif_cps); - TIFFGetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps); - TIFFGetField(tif_ctx, TIFFTAG_ICCPROFILE, &tif_icc_size, &tif_icc_buf); - if (pAttribute) { - pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH; - if (TIFFGetField(tif_ctx, TIFFTAG_RESOLUTIONUNIT, - &pAttribute->m_wDPIUnit)) { - pAttribute->m_wDPIUnit -= 1; - } - Tiff_Exif_GetInfo(tif_ctx, TIFFTAG_ORIENTATION, pAttribute); - if (Tiff_Exif_GetInfo(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(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(tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pAttribute); - Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MAKE, pAttribute); - Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MODEL, pAttribute); - } - bpc = tif_bpc; - if (tif_rps > height) { - TIFFSetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps = height); - } - return TRUE; -} -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; - } -} -FX_BOOL CCodec_TiffContext::isSupport(CFX_DIBitmap* pDIBitmap) { - if (TIFFIsTiled(tif_ctx)) { - return FALSE; - } - uint16_t photometric; - if (!TIFFGetField(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; - if (!TIFFGetFieldDefaulted(tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig)) { - return FALSE; - } - if (planarconfig == PLANARCONFIG_SEPARATE) { - return FALSE; - } - return TRUE; -} -void CCodec_TiffContext::SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps) { - uint16_t *red_orig, *green_orig, *blue_orig; - TIFFGetField(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++) { - FX_DWORD r = red_orig[index] & 0xFF; - FX_DWORD g = green_orig[index] & 0xFF; - FX_DWORD b = blue_orig[index] & 0xFF; - FX_DWORD color = (uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16) | - (((uint32)0xffL) << 24); - pDIBitmap->SetPaletteEntry(index, color); - } -} -FX_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(tif_ctx); - uint8_t* buf = (uint8_t*)_TIFFmalloc(size); - if (buf == NULL) { - TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); - return FALSE; - } - uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); - FX_DWORD pitch = pDIBitmap->GetPitch(); - for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(tif_ctx, buf, row, 0); - for (int32_t j = 0; j < size; j++) { - bitMapbuffer[row * pitch + j] = buf[j]; - } - } - _TIFFfree(buf); - return TRUE; -} -FX_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(tif_ctx); - uint8_t* buf = (uint8_t*)_TIFFmalloc(size); - if (buf == NULL) { - TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); - return FALSE; - } - uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); - FX_DWORD pitch = pDIBitmap->GetPitch(); - for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(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; -} -FX_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(tif_ctx); - uint8_t* buf = (uint8_t*)_TIFFmalloc(size); - if (buf == NULL) { - TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); - return FALSE; - } - uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); - FX_DWORD pitch = pDIBitmap->GetPitch(); - for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(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; -} -FX_BOOL CCodec_TiffContext::Decode(CFX_DIBitmap* pDIBitmap) { - FX_DWORD img_wid = pDIBitmap->GetWidth(); - FX_DWORD img_hei = pDIBitmap->GetHeight(); - FX_DWORD width = 0; - FX_DWORD height = 0; - TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height); - if (img_wid != width || img_hei != height) { - return FALSE; - } - if (pDIBitmap->GetBPP() == 32) { - FX_WORD rotation = ORIENTATION_TOPLEFT; - TIFFGetField(tif_ctx, TIFFTAG_ORIENTATION, &rotation); - if (TIFFReadRGBAImageOriented(tif_ctx, img_wid, img_hei, - (uint32*)pDIBitmap->GetBuffer(), rotation, - 1)) { - for (FX_DWORD 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, bps; - TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp); - TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps); - FX_DWORD bpp = bps * spp; - if (bpp == 1) { - return Decode1bppRGB(pDIBitmap, height, width, bps, spp); - } else if (bpp <= 8) { - return Decode8bppRGB(pDIBitmap, height, width, bps, spp); - } else if (bpp <= 24) { - return Decode24bppRGB(pDIBitmap, height, width, bps, spp); - } - return FALSE; -} -void* CCodec_TiffModule::CreateDecoder(IFX_FileRead* file_ptr) { - CCodec_TiffContext* pDecoder = new CCodec_TiffContext; - if (!pDecoder->InitDecoder(file_ptr)) { - delete pDecoder; - return NULL; - } - return pDecoder; -} -void CCodec_TiffModule::GetFrames(void* ctx, int32_t& frames) { - CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; - pDecoder->GetFrames(frames); -} -FX_BOOL CCodec_TiffModule::LoadFrameInfo(void* ctx, - int32_t frame, - FX_DWORD& width, - FX_DWORD& height, - FX_DWORD& comps, - FX_DWORD& bpc, - CFX_DIBAttribute* pAttribute) { - CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; - return pDecoder->LoadFrameInfo(frame, width, height, comps, bpc, pAttribute); -} -FX_BOOL CCodec_TiffModule::Decode(void* ctx, class CFX_DIBitmap* pDIBitmap) { - CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; - return pDecoder->Decode(pDIBitmap); -} -void CCodec_TiffModule::DestroyDecoder(void* ctx) { - CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; - delete pDecoder; -} +// 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/include/fxcodec/fx_codec.h" +#include "core/include/fxge/fx_dib.h" +#include "codec_int.h" + +extern "C" { +#include "third_party/libtiff/tiffiop.h" +} + +void* IccLib_CreateTransform_sRGB(const unsigned char* pProfileData, + unsigned int dwProfileSize, + int nComponents, + int intent, + FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT); +void IccLib_TranslateImage(void* pTransform, + unsigned char* pDest, + const unsigned char* pSrc, + int pixels); +void IccLib_DestroyTransform(void* pTransform); +class CCodec_TiffContext { + public: + CCodec_TiffContext(); + ~CCodec_TiffContext(); + + FX_BOOL InitDecoder(IFX_FileRead* file_ptr); + void GetFrames(int32_t& frames); + FX_BOOL LoadFrameInfo(int32_t frame, + FX_DWORD& width, + FX_DWORD& height, + FX_DWORD& comps, + FX_DWORD& bpc, + CFX_DIBAttribute* pAttribute); + FX_BOOL Decode(CFX_DIBitmap* pDIBitmap); + + union { + IFX_FileRead* in; + IFX_FileStream* out; + } io; + + FX_DWORD offset; + + TIFF* tif_ctx; + void* icc_ctx; + int32_t frame_num; + int32_t frame_cur; + FX_BOOL isDecoder; + + private: + FX_BOOL isSupport(CFX_DIBitmap* pDIBitmap); + void SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps); + FX_BOOL Decode1bppRGB(CFX_DIBitmap* pDIBitmap, + int32_t height, + int32_t width, + uint16_t bps, + uint16_t spp); + FX_BOOL Decode8bppRGB(CFX_DIBitmap* pDIBitmap, + int32_t height, + int32_t width, + uint16_t bps, + uint16_t spp); + FX_BOOL Decode24bppRGB(CFX_DIBitmap* pDIBitmap, + int32_t height, + int32_t width, + uint16_t bps, + uint16_t spp); +}; +CCodec_TiffContext::CCodec_TiffContext() { + offset = 0; + frame_num = 0; + frame_cur = 0; + io.in = NULL; + tif_ctx = NULL; + icc_ctx = NULL; + isDecoder = TRUE; +} +CCodec_TiffContext::~CCodec_TiffContext() { + if (icc_ctx) { + IccLib_DestroyTransform(icc_ctx); + icc_ctx = NULL; + } + if (tif_ctx) { + TIFFClose(tif_ctx); + } +} +static tsize_t _tiff_read(thandle_t context, tdata_t buf, tsize_t length) { + CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; + FX_BOOL ret = FALSE; + if (pTiffContext->isDecoder) { + ret = pTiffContext->io.in->ReadBlock(buf, pTiffContext->offset, length); + } else { + ret = pTiffContext->io.out->ReadBlock(buf, pTiffContext->offset, length); + } + if (!ret) { + return 0; + } + pTiffContext->offset += (FX_DWORD)length; + return length; +} +static tsize_t _tiff_write(thandle_t context, tdata_t buf, tsize_t length) { + CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; + ASSERT(!pTiffContext->isDecoder); + if (!pTiffContext->io.out->WriteBlock(buf, pTiffContext->offset, length)) { + return 0; + } + pTiffContext->offset += (FX_DWORD)length; + return length; +} +static toff_t _tiff_seek(thandle_t context, toff_t offset, int whence) { + CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; + switch (whence) { + case 0: + pTiffContext->offset = (FX_DWORD)offset; + break; + case 1: + pTiffContext->offset += (FX_DWORD)offset; + break; + case 2: + if (pTiffContext->isDecoder) { + if (pTiffContext->io.in->GetSize() < (FX_FILESIZE)offset) { + return -1; + } + pTiffContext->offset = + (FX_DWORD)(pTiffContext->io.in->GetSize() - offset); + } else { + if (pTiffContext->io.out->GetSize() < (FX_FILESIZE)offset) { + return -1; + } + pTiffContext->offset = + (FX_DWORD)(pTiffContext->io.out->GetSize() - offset); + } + break; + default: + return -1; + } + ASSERT(pTiffContext->isDecoder ? (pTiffContext->offset <= + (FX_DWORD)pTiffContext->io.in->GetSize()) + : TRUE); + return pTiffContext->offset; +} +static int _tiff_close(thandle_t context) { + return 0; +} +static toff_t _tiff_get_size(thandle_t context) { + CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; + return pTiffContext->isDecoder ? (toff_t)pTiffContext->io.in->GetSize() + : (toff_t)pTiffContext->io.out->GetSize(); +} +static int _tiff_map(thandle_t context, tdata_t*, toff_t*) { + return 0; +} +static 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; +} +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); +} + +TIFFErrorHandler _TIFFwarningHandler = nullptr; +TIFFErrorHandler _TIFFerrorHandler = nullptr; + +int TIFFCmyk2Rgb(thandle_t context, + uint8 c, + uint8 m, + uint8 y, + uint8 k, + uint8* r, + uint8* g, + uint8* b) { + if (context == NULL) { + return 0; + } + CCodec_TiffContext* p = (CCodec_TiffContext*)context; + if (p->icc_ctx) { + unsigned char cmyk[4], bgr[3]; + cmyk[0] = c, cmyk[1] = m, cmyk[2] = y, cmyk[3] = k; + IccLib_TranslateImage(p->icc_ctx, bgr, cmyk, 1); + *r = bgr[2], *g = bgr[1], *b = bgr[0]; + } else { + AdobeCMYK_to_sRGB1(c, m, y, k, *r, *g, *b); + } + return 1; +} +FX_BOOL CCodec_TiffContext::InitDecoder(IFX_FileRead* file_ptr) { + io.in = file_ptr; + tif_ctx = _tiff_open(this, "r"); + if (tif_ctx == NULL) { + return FALSE; + } + return TRUE; +} +void CCodec_TiffContext::GetFrames(int32_t& frames) { + frames = frame_num = TIFFNumberOfDirectories(tif_ctx); +} +#define TIFF_EXIF_GETINFO(key, T, tag) \ + { \ + T val = (T)0; \ + TIFFGetField(tif_ctx, tag, &val); \ + if (val) { \ + (key) = FX_Alloc(uint8_t, sizeof(T)); \ + if ((key)) { \ + T* ptr = (T*)(key); \ + *ptr = val; \ + pExif->m_TagVal.SetAt(tag, (key)); \ + } \ + } \ + } \ + (key) = NULL; +#define TIFF_EXIF_GETSTRINGINFO(key, tag) \ + { \ + FX_DWORD size = 0; \ + uint8_t* buf = NULL; \ + TIFFGetField(tif_ctx, tag, &size, &buf); \ + if (size && buf) { \ + (key) = FX_Alloc(uint8_t, size); \ + if ((key)) { \ + FXSYS_memcpy((key), buf, size); \ + pExif->m_TagVal.SetAt(tag, (key)); \ + } \ + } \ + } \ + (key) = NULL; + +namespace { + +template +FX_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; +} + +} // namespace + +FX_BOOL CCodec_TiffContext::LoadFrameInfo(int32_t frame, + FX_DWORD& width, + FX_DWORD& height, + FX_DWORD& comps, + FX_DWORD& bpc, + CFX_DIBAttribute* pAttribute) { + if (!TIFFSetDirectory(tif_ctx, (uint16)frame)) { + return FALSE; + } + FX_WORD tif_cs; + FX_DWORD tif_icc_size = 0; + uint8_t* tif_icc_buf = NULL; + FX_WORD tif_bpc = 0; + FX_WORD tif_cps; + FX_DWORD tif_rps; + width = height = comps = 0; + TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height); + TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &comps); + TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc); + TIFFGetField(tif_ctx, TIFFTAG_PHOTOMETRIC, &tif_cs); + TIFFGetField(tif_ctx, TIFFTAG_COMPRESSION, &tif_cps); + TIFFGetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps); + TIFFGetField(tif_ctx, TIFFTAG_ICCPROFILE, &tif_icc_size, &tif_icc_buf); + if (pAttribute) { + pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH; + if (TIFFGetField(tif_ctx, TIFFTAG_RESOLUTIONUNIT, + &pAttribute->m_wDPIUnit)) { + pAttribute->m_wDPIUnit -= 1; + } + Tiff_Exif_GetInfo(tif_ctx, TIFFTAG_ORIENTATION, pAttribute); + if (Tiff_Exif_GetInfo(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(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(tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pAttribute); + Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MAKE, pAttribute); + Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MODEL, pAttribute); + } + bpc = tif_bpc; + if (tif_rps > height) { + TIFFSetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps = height); + } + return TRUE; +} +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; + } +} +FX_BOOL CCodec_TiffContext::isSupport(CFX_DIBitmap* pDIBitmap) { + if (TIFFIsTiled(tif_ctx)) { + return FALSE; + } + uint16_t photometric; + if (!TIFFGetField(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; + if (!TIFFGetFieldDefaulted(tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig)) { + return FALSE; + } + if (planarconfig == PLANARCONFIG_SEPARATE) { + return FALSE; + } + return TRUE; +} +void CCodec_TiffContext::SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps) { + uint16_t *red_orig, *green_orig, *blue_orig; + TIFFGetField(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++) { + FX_DWORD r = red_orig[index] & 0xFF; + FX_DWORD g = green_orig[index] & 0xFF; + FX_DWORD b = blue_orig[index] & 0xFF; + FX_DWORD color = (uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16) | + (((uint32)0xffL) << 24); + pDIBitmap->SetPaletteEntry(index, color); + } +} +FX_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(tif_ctx); + uint8_t* buf = (uint8_t*)_TIFFmalloc(size); + if (buf == NULL) { + TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); + return FALSE; + } + uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); + FX_DWORD pitch = pDIBitmap->GetPitch(); + for (int32_t row = 0; row < height; row++) { + TIFFReadScanline(tif_ctx, buf, row, 0); + for (int32_t j = 0; j < size; j++) { + bitMapbuffer[row * pitch + j] = buf[j]; + } + } + _TIFFfree(buf); + return TRUE; +} +FX_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(tif_ctx); + uint8_t* buf = (uint8_t*)_TIFFmalloc(size); + if (buf == NULL) { + TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); + return FALSE; + } + uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); + FX_DWORD pitch = pDIBitmap->GetPitch(); + for (int32_t row = 0; row < height; row++) { + TIFFReadScanline(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; +} +FX_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(tif_ctx); + uint8_t* buf = (uint8_t*)_TIFFmalloc(size); + if (buf == NULL) { + TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); + return FALSE; + } + uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); + FX_DWORD pitch = pDIBitmap->GetPitch(); + for (int32_t row = 0; row < height; row++) { + TIFFReadScanline(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; +} +FX_BOOL CCodec_TiffContext::Decode(CFX_DIBitmap* pDIBitmap) { + FX_DWORD img_wid = pDIBitmap->GetWidth(); + FX_DWORD img_hei = pDIBitmap->GetHeight(); + FX_DWORD width = 0; + FX_DWORD height = 0; + TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height); + if (img_wid != width || img_hei != height) { + return FALSE; + } + if (pDIBitmap->GetBPP() == 32) { + FX_WORD rotation = ORIENTATION_TOPLEFT; + TIFFGetField(tif_ctx, TIFFTAG_ORIENTATION, &rotation); + if (TIFFReadRGBAImageOriented(tif_ctx, img_wid, img_hei, + (uint32*)pDIBitmap->GetBuffer(), rotation, + 1)) { + for (FX_DWORD 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, bps; + TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp); + TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps); + FX_DWORD bpp = bps * spp; + if (bpp == 1) { + return Decode1bppRGB(pDIBitmap, height, width, bps, spp); + } else if (bpp <= 8) { + return Decode8bppRGB(pDIBitmap, height, width, bps, spp); + } else if (bpp <= 24) { + return Decode24bppRGB(pDIBitmap, height, width, bps, spp); + } + return FALSE; +} +void* CCodec_TiffModule::CreateDecoder(IFX_FileRead* file_ptr) { + CCodec_TiffContext* pDecoder = new CCodec_TiffContext; + if (!pDecoder->InitDecoder(file_ptr)) { + delete pDecoder; + return NULL; + } + return pDecoder; +} +void CCodec_TiffModule::GetFrames(void* ctx, int32_t& frames) { + CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; + pDecoder->GetFrames(frames); +} +FX_BOOL CCodec_TiffModule::LoadFrameInfo(void* ctx, + int32_t frame, + FX_DWORD& width, + FX_DWORD& height, + FX_DWORD& comps, + FX_DWORD& bpc, + CFX_DIBAttribute* pAttribute) { + CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; + return pDecoder->LoadFrameInfo(frame, width, height, comps, bpc, pAttribute); +} +FX_BOOL CCodec_TiffModule::Decode(void* ctx, class CFX_DIBitmap* pDIBitmap) { + CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; + return pDecoder->Decode(pDIBitmap); +} +void CCodec_TiffModule::DestroyDecoder(void* ctx) { + CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; + delete pDecoder; +} diff --git a/core/src/fxcodec/lbmp/fx_bmp.cpp b/core/src/fxcodec/lbmp/fx_bmp.cpp index 00477581a1..388daa434f 100644 --- a/core/src/fxcodec/lbmp/fx_bmp.cpp +++ b/core/src/fxcodec/lbmp/fx_bmp.cpp @@ -1,975 +1,975 @@ -// 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 "fx_bmp.h" - -#include - -namespace { - -const size_t kBmpCoreHeaderSize = 12; -const size_t kBmpInfoHeaderSize = 40; - -} // namespace - -FX_DWORD _GetDWord_LSBFirst(uint8_t* p) { - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); -} -FX_WORD _GetWord_LSBFirst(uint8_t* p) { - return p[0] | (p[1] << 8); -} -void _SetDWord_LSBFirst(uint8_t* p, FX_DWORD v) { - p[0] = (uint8_t)v; - p[1] = (uint8_t)(v >> 8); - p[2] = (uint8_t)(v >> 16); - p[3] = (uint8_t)(v >> 24); -} -void _SetWord_LSBFirst(uint8_t* p, FX_WORD v) { - p[0] = (uint8_t)v; - p[1] = (uint8_t)(v >> 8); -} -void _bmp_error(bmp_decompress_struct_p bmp_ptr, const FX_CHAR* err_msg) { - if (bmp_ptr != NULL && bmp_ptr->_bmp_error_fn != NULL) { - bmp_ptr->_bmp_error_fn(bmp_ptr, err_msg); - } -} -bmp_decompress_struct_p _bmp_create_decompress() { - bmp_decompress_struct_p bmp_ptr = FX_Alloc(bmp_decompress_struct, 1); - if (bmp_ptr == NULL) { - return NULL; - } - FXSYS_memset(bmp_ptr, 0, sizeof(bmp_decompress_struct)); - bmp_ptr->decode_status = BMP_D_STATUS_HEADER; - bmp_ptr->bmp_header_ptr = FX_Alloc(BmpFileHeader, 1); - return bmp_ptr; -} -void _bmp_destroy_decompress(bmp_decompress_struct_pp bmp_ptr_ptr) { - if (bmp_ptr_ptr == NULL || *bmp_ptr_ptr == NULL) { - return; - } - bmp_decompress_struct_p bmp_ptr = *bmp_ptr_ptr; - *bmp_ptr_ptr = NULL; - if (bmp_ptr->out_row_buffer != NULL) { - FX_Free(bmp_ptr->out_row_buffer); - } - if (bmp_ptr->pal_ptr != NULL) { - FX_Free(bmp_ptr->pal_ptr); - } - if (bmp_ptr->bmp_header_ptr != NULL) { - FX_Free(bmp_ptr->bmp_header_ptr); - } - FX_Free(bmp_ptr); -} -int32_t _bmp_read_header(bmp_decompress_struct_p bmp_ptr) { - if (bmp_ptr == NULL) { - return 0; - } - FX_DWORD skip_size_org = bmp_ptr->skip_size; - if (bmp_ptr->decode_status == BMP_D_STATUS_HEADER) { - ASSERT(sizeof(BmpFileHeader) == 14); - BmpFileHeader* bmp_header_ptr = NULL; - if (_bmp_read_data(bmp_ptr, (uint8_t**)&bmp_header_ptr, 14) == NULL) { - return 2; - } - bmp_ptr->bmp_header_ptr->bfType = - _GetWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfType); - bmp_ptr->bmp_header_ptr->bfOffBits = - _GetDWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfOffBits); - bmp_ptr->data_size = _GetDWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfSize); - if (bmp_ptr->bmp_header_ptr->bfType != BMP_SIGNATURE) { - _bmp_error(bmp_ptr, "Not A Bmp Image"); - return 0; - } - if (bmp_ptr->avail_in < sizeof(FX_DWORD)) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - bmp_ptr->img_ifh_size = - _GetDWord_LSBFirst(bmp_ptr->next_in + bmp_ptr->skip_size); - bmp_ptr->pal_type = 0; - static_assert(sizeof(BmpCoreHeader) == kBmpCoreHeaderSize, - "BmpCoreHeader has wrong size"); - static_assert(sizeof(BmpInfoHeader) == kBmpInfoHeaderSize, - "BmpInfoHeader has wrong size"); - switch (bmp_ptr->img_ifh_size) { - case kBmpCoreHeaderSize: { - bmp_ptr->pal_type = 1; - BmpCoreHeaderPtr bmp_core_header_ptr = NULL; - if (_bmp_read_data(bmp_ptr, (uint8_t**)&bmp_core_header_ptr, - bmp_ptr->img_ifh_size) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - bmp_ptr->width = (FX_DWORD)_GetWord_LSBFirst( - (uint8_t*)&bmp_core_header_ptr->bcWidth); - bmp_ptr->height = (FX_DWORD)_GetWord_LSBFirst( - (uint8_t*)&bmp_core_header_ptr->bcHeight); - bmp_ptr->bitCounts = - _GetWord_LSBFirst((uint8_t*)&bmp_core_header_ptr->bcBitCount); - bmp_ptr->compress_flag = BMP_RGB; - bmp_ptr->imgTB_flag = FALSE; - } break; - case kBmpInfoHeaderSize: { - BmpInfoHeaderPtr bmp_info_header_ptr = NULL; - if (_bmp_read_data(bmp_ptr, (uint8_t**)&bmp_info_header_ptr, - bmp_ptr->img_ifh_size) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - bmp_ptr->width = - _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biWidth); - bmp_ptr->height = - _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biHeight); - bmp_ptr->bitCounts = - _GetWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biBitCount); - bmp_ptr->compress_flag = - _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biCompression); - bmp_ptr->color_used = - _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biClrUsed); - bmp_ptr->dpi_x = (int32_t)_GetDWord_LSBFirst( - (uint8_t*)&bmp_info_header_ptr->biXPelsPerMeter); - bmp_ptr->dpi_y = (int32_t)_GetDWord_LSBFirst( - (uint8_t*)&bmp_info_header_ptr->biYPelsPerMeter); - if (bmp_ptr->height < 0) { - bmp_ptr->height = -bmp_ptr->height; - bmp_ptr->imgTB_flag = TRUE; - } - } break; - default: { - if (bmp_ptr->img_ifh_size > - std::min(kBmpInfoHeaderSize, sizeof(BmpInfoHeader))) { - BmpInfoHeaderPtr bmp_info_header_ptr = NULL; - if (_bmp_read_data(bmp_ptr, (uint8_t**)&bmp_info_header_ptr, - bmp_ptr->img_ifh_size) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - FX_WORD biPlanes; - bmp_ptr->width = - _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biWidth); - bmp_ptr->height = - _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biHeight); - bmp_ptr->bitCounts = - _GetWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biBitCount); - bmp_ptr->compress_flag = - _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biCompression); - bmp_ptr->color_used = - _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biClrUsed); - biPlanes = - _GetWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biPlanes); - bmp_ptr->dpi_x = _GetDWord_LSBFirst( - (uint8_t*)&bmp_info_header_ptr->biXPelsPerMeter); - bmp_ptr->dpi_y = _GetDWord_LSBFirst( - (uint8_t*)&bmp_info_header_ptr->biYPelsPerMeter); - if (bmp_ptr->height < 0) { - bmp_ptr->height = -bmp_ptr->height; - bmp_ptr->imgTB_flag = TRUE; - } - if (bmp_ptr->compress_flag == BMP_RGB && biPlanes == 1 && - bmp_ptr->color_used == 0) { - break; - } - } - _bmp_error(bmp_ptr, "Unsupported Bmp File"); - return 0; - } - } - ASSERT(bmp_ptr->width > 0); - ASSERT(bmp_ptr->compress_flag <= BMP_BITFIELDS); - switch (bmp_ptr->bitCounts) { - case 1: - case 4: - case 8: - case 16: - case 24: { - if (bmp_ptr->color_used > ((FX_DWORD)1) << bmp_ptr->bitCounts) { - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); - return 0; - } - } - case 32: { - if (bmp_ptr->width <= 0 || bmp_ptr->compress_flag > BMP_BITFIELDS) { - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); - return 0; - } - } break; - default: - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); - return 0; - } - bmp_ptr->src_row_bytes = BMP_WIDTHBYTES(bmp_ptr->width, bmp_ptr->bitCounts); - switch (bmp_ptr->bitCounts) { - case 1: - case 4: - case 8: - bmp_ptr->out_row_bytes = BMP_WIDTHBYTES(bmp_ptr->width, 8); - bmp_ptr->components = 1; - break; - case 16: - case 24: - bmp_ptr->out_row_bytes = BMP_WIDTHBYTES(bmp_ptr->width, 24); - bmp_ptr->components = 3; - break; - case 32: - bmp_ptr->out_row_bytes = bmp_ptr->src_row_bytes; - bmp_ptr->components = 4; - break; - } - if (bmp_ptr->out_row_buffer != NULL) { - FX_Free(bmp_ptr->out_row_buffer); - bmp_ptr->out_row_buffer = NULL; - } - bmp_ptr->out_row_buffer = FX_Alloc(uint8_t, bmp_ptr->out_row_bytes); - BMP_PTR_NOT_NULL(bmp_ptr->out_row_buffer, bmp_ptr); - FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_PAL); - } - if (bmp_ptr->decode_status == BMP_D_STATUS_PAL) { - skip_size_org = bmp_ptr->skip_size; -#ifdef BMP_SUPPORT_BITFIELD - if (bmp_ptr->compress_flag == BMP_BITFIELDS) { - if (bmp_ptr->bitCounts != 16 && bmp_ptr->bitCounts != 32) { - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); - return 0; - } - FX_DWORD* mask; - if (_bmp_read_data(bmp_ptr, (uint8_t**)&mask, 3 * sizeof(FX_DWORD)) == - NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - bmp_ptr->mask_red = _GetDWord_LSBFirst((uint8_t*)&mask[0]); - bmp_ptr->mask_green = _GetDWord_LSBFirst((uint8_t*)&mask[1]); - bmp_ptr->mask_blue = _GetDWord_LSBFirst((uint8_t*)&mask[2]); - if (bmp_ptr->mask_red & bmp_ptr->mask_green || - bmp_ptr->mask_red & bmp_ptr->mask_blue || - bmp_ptr->mask_green & bmp_ptr->mask_blue) { - _bmp_error(bmp_ptr, "The Bitfield Bmp File Is Corrupt"); - return 0; - } - if (bmp_ptr->bmp_header_ptr->bfOffBits < 26 + bmp_ptr->img_ifh_size) { - bmp_ptr->bmp_header_ptr->bfOffBits = 26 + bmp_ptr->img_ifh_size; - } - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA_PRE); - return 1; - } else if (bmp_ptr->bitCounts == 16) { - bmp_ptr->mask_red = 0x7C00; - bmp_ptr->mask_green = 0x03E0; - bmp_ptr->mask_blue = 0x001F; - } -#else - if (bmp_ptr->compress_flag == BMP_BITFIELDS || bmp_ptr->bitCounts == 16) { - _bmp_error(bmp_ptr, "Unsupported Bitfield Bmp File"); - return 0; - } -#endif - bmp_ptr->pal_num = 0; - if (bmp_ptr->bitCounts < 16) { - bmp_ptr->pal_num = 1 << bmp_ptr->bitCounts; - if (bmp_ptr->color_used != 0) { - bmp_ptr->pal_num = bmp_ptr->color_used; - } - uint8_t* src_pal_ptr = NULL; - FX_DWORD src_pal_size = bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4); - if (_bmp_read_data(bmp_ptr, (uint8_t**)&src_pal_ptr, src_pal_size) == - NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - if (bmp_ptr->pal_ptr != NULL) { - FX_Free(bmp_ptr->pal_ptr); - bmp_ptr->pal_ptr = NULL; - } - bmp_ptr->pal_ptr = FX_Alloc(FX_DWORD, bmp_ptr->pal_num); - BMP_PTR_NOT_NULL(bmp_ptr->pal_ptr, bmp_ptr); - int32_t src_pal_index = 0; - if (bmp_ptr->pal_type == BMP_PAL_OLD) { - while (src_pal_index < bmp_ptr->pal_num) { - bmp_ptr->pal_ptr[src_pal_index++] = BMP_PAL_ENCODE( - 0x00, src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]); - src_pal_ptr += 3; - } - } else { - while (src_pal_index < bmp_ptr->pal_num) { - bmp_ptr->pal_ptr[src_pal_index++] = BMP_PAL_ENCODE( - src_pal_ptr[3], src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]); - src_pal_ptr += 4; - } - } - } - if (bmp_ptr->bmp_header_ptr->bfOffBits < - 14 + bmp_ptr->img_ifh_size + - bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4)) { - bmp_ptr->bmp_header_ptr->bfOffBits = - 14 + bmp_ptr->img_ifh_size + - bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4); - } - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA_PRE); - } - return 1; -} -int32_t _bmp_decode_image(bmp_decompress_struct_p bmp_ptr) { - if (bmp_ptr->decode_status == BMP_D_STATUS_DATA_PRE) { - bmp_ptr->avail_in = 0; - if (!bmp_ptr->_bmp_get_data_position_fn( - bmp_ptr, bmp_ptr->bmp_header_ptr->bfOffBits)) { - bmp_ptr->decode_status = BMP_D_STATUS_TAIL; - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt, Unexpected Stream Offset"); - return 0; - } - bmp_ptr->row_num = 0; - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA); - } - if (bmp_ptr->decode_status == BMP_D_STATUS_DATA) { - switch (bmp_ptr->compress_flag) { - case BMP_RGB: - case BMP_BITFIELDS: - return _bmp_decode_rgb(bmp_ptr); - case BMP_RLE8: - return _bmp_decode_rle8(bmp_ptr); - case BMP_RLE4: - return _bmp_decode_rle4(bmp_ptr); - } - } - _bmp_error(bmp_ptr, "Any Uncontrol Error"); - return 0; -} -int32_t _bmp_decode_rgb(bmp_decompress_struct_p bmp_ptr) { - uint8_t* row_buf = bmp_ptr->out_row_buffer; - uint8_t* des_buf = NULL; - while (bmp_ptr->row_num < bmp_ptr->height) { - if (_bmp_read_data(bmp_ptr, &des_buf, bmp_ptr->src_row_bytes) == NULL) { - return 2; - } - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA); - switch (bmp_ptr->bitCounts) { - case 1: { - for (int32_t col = 0; col < bmp_ptr->width; col++) { - *row_buf++ = des_buf[col >> 3] & (0x80 >> (col % 8)) ? 0x01 : 0x00; - } - } break; - case 4: { - for (int32_t col = 0; col < bmp_ptr->width; col++) { - *row_buf++ = (col & 0x01) ? (des_buf[col >> 1] & 0x0F) - : ((des_buf[col >> 1] & 0xF0) >> 4); - } - } break; -#ifdef BMP_SUPPORT_BITFIELD - case 16: { - FX_WORD* buf = (FX_WORD*)des_buf; - uint8_t blue_bits = 0; - uint8_t green_bits = 0; - uint8_t red_bits = 0; - for (int32_t i = 0; i < 16; i++) { - if ((bmp_ptr->mask_blue >> i) & 0x01) { - blue_bits++; - } - if ((bmp_ptr->mask_green >> i) & 0x01) { - green_bits++; - } - if ((bmp_ptr->mask_red >> i) & 0x01) { - red_bits++; - } - } - green_bits += blue_bits; - red_bits += green_bits; - blue_bits = 8 - blue_bits; - green_bits -= 8; - red_bits -= 8; - for (int32_t col = 0; col < bmp_ptr->width; col++) { - *buf = _GetWord_LSBFirst((uint8_t*)buf); - *row_buf++ = (uint8_t)((*buf & bmp_ptr->mask_blue) << blue_bits); - *row_buf++ = (uint8_t)((*buf & bmp_ptr->mask_green) >> green_bits); - *row_buf++ = (uint8_t)((*buf++ & bmp_ptr->mask_red) >> red_bits); - } - } break; -#endif - case 8: - case 24: - case 32: - FXSYS_memcpy(bmp_ptr->out_row_buffer, des_buf, bmp_ptr->src_row_bytes); - break; - } - row_buf = bmp_ptr->out_row_buffer; - bmp_ptr->_bmp_get_row_fn(bmp_ptr, - bmp_ptr->imgTB_flag - ? bmp_ptr->row_num++ - : (bmp_ptr->height - 1 - bmp_ptr->row_num++), - bmp_ptr->out_row_buffer); - } - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); - return 1; -} -int32_t _bmp_decode_rle8(bmp_decompress_struct_p bmp_ptr) { - uint8_t* first_byte_ptr = NULL; - uint8_t* second_byte_ptr = NULL; - bmp_ptr->col_num = 0; - while (TRUE) { - FX_DWORD skip_size_org = bmp_ptr->skip_size; - if (_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { - return 2; - } - switch (*first_byte_ptr) { - case RLE_MARKER: { - if (_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - switch (*first_byte_ptr) { - case RLE_EOL: { - if (bmp_ptr->row_num >= bmp_ptr->height) { - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); - return 0; - } - bmp_ptr->_bmp_get_row_fn( - bmp_ptr, bmp_ptr->imgTB_flag - ? bmp_ptr->row_num++ - : (bmp_ptr->height - 1 - bmp_ptr->row_num++), - bmp_ptr->out_row_buffer); - bmp_ptr->col_num = 0; - FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA); - continue; - } - case RLE_EOI: { - if (bmp_ptr->row_num < bmp_ptr->height) { - bmp_ptr->_bmp_get_row_fn( - bmp_ptr, bmp_ptr->imgTB_flag - ? bmp_ptr->row_num++ - : (bmp_ptr->height - 1 - bmp_ptr->row_num++), - bmp_ptr->out_row_buffer); - } - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); - return 1; - } - case RLE_DELTA: { - uint8_t* delta_ptr; - if (_bmp_read_data(bmp_ptr, &delta_ptr, 2) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - bmp_ptr->col_num += (int32_t)delta_ptr[0]; - int32_t bmp_row_num_next = bmp_ptr->row_num + (int32_t)delta_ptr[1]; - if (bmp_ptr->col_num >= bmp_ptr->out_row_bytes || - bmp_row_num_next >= bmp_ptr->height) { - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt Or Not Supported"); - return 0; - } - while (bmp_ptr->row_num < bmp_row_num_next) { - FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); - bmp_ptr->_bmp_get_row_fn( - bmp_ptr, bmp_ptr->imgTB_flag - ? bmp_ptr->row_num++ - : (bmp_ptr->height - 1 - bmp_ptr->row_num++), - bmp_ptr->out_row_buffer); - } - } break; - default: { - if ((int32_t)(*first_byte_ptr) > - bmp_ptr->src_row_bytes - bmp_ptr->col_num) { - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); - return 0; - } - if (_bmp_read_data(bmp_ptr, &second_byte_ptr, - *first_byte_ptr & 1 ? *first_byte_ptr + 1 - : *first_byte_ptr) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - FXSYS_memcpy(bmp_ptr->out_row_buffer + bmp_ptr->col_num, - second_byte_ptr, *first_byte_ptr); - bmp_ptr->col_num += (int32_t)(*first_byte_ptr); - } - } - } break; - default: { - if (_bmp_read_data(bmp_ptr, &second_byte_ptr, 1) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - if ((int32_t)(*first_byte_ptr) > - bmp_ptr->src_row_bytes - bmp_ptr->col_num) { - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); - return 0; - } - FXSYS_memset(bmp_ptr->out_row_buffer + bmp_ptr->col_num, - *second_byte_ptr, *first_byte_ptr); - bmp_ptr->col_num += (int32_t)(*first_byte_ptr); - } - } - } - _bmp_error(bmp_ptr, "Any Uncontrol Error"); - return 0; -} -int32_t _bmp_decode_rle4(bmp_decompress_struct_p bmp_ptr) { - uint8_t* first_byte_ptr = NULL; - uint8_t* second_byte_ptr = NULL; - bmp_ptr->col_num = 0; - while (TRUE) { - FX_DWORD skip_size_org = bmp_ptr->skip_size; - if (_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { - return 2; - } - switch (*first_byte_ptr) { - case RLE_MARKER: { - if (_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - switch (*first_byte_ptr) { - case RLE_EOL: { - if (bmp_ptr->row_num >= bmp_ptr->height) { - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); - return 0; - } - bmp_ptr->_bmp_get_row_fn( - bmp_ptr, bmp_ptr->imgTB_flag - ? bmp_ptr->row_num++ - : (bmp_ptr->height - 1 - bmp_ptr->row_num++), - bmp_ptr->out_row_buffer); - bmp_ptr->col_num = 0; - FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA); - continue; - } - case RLE_EOI: { - if (bmp_ptr->row_num < bmp_ptr->height) { - bmp_ptr->_bmp_get_row_fn( - bmp_ptr, bmp_ptr->imgTB_flag - ? bmp_ptr->row_num++ - : (bmp_ptr->height - 1 - bmp_ptr->row_num++), - bmp_ptr->out_row_buffer); - } - _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); - return 1; - } - case RLE_DELTA: { - uint8_t* delta_ptr; - if (_bmp_read_data(bmp_ptr, &delta_ptr, 2) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - bmp_ptr->col_num += (int32_t)delta_ptr[0]; - int32_t bmp_row_num_next = bmp_ptr->row_num + (int32_t)delta_ptr[1]; - if (bmp_ptr->col_num >= bmp_ptr->out_row_bytes || - bmp_row_num_next >= bmp_ptr->height) { - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt Or Not Supported"); - return 0; - } - while (bmp_ptr->row_num < bmp_row_num_next) { - FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); - bmp_ptr->_bmp_get_row_fn( - bmp_ptr, bmp_ptr->imgTB_flag - ? bmp_ptr->row_num++ - : (bmp_ptr->height - 1 - bmp_ptr->row_num++), - bmp_ptr->out_row_buffer); - } - } break; - default: { - uint8_t size = (uint8_t)(((FX_WORD)(*first_byte_ptr) + 1) >> 1); - if ((int32_t)*first_byte_ptr >= - bmp_ptr->out_row_bytes - bmp_ptr->col_num) { - if (size + (bmp_ptr->col_num >> 1) > bmp_ptr->src_row_bytes) { - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); - return 0; - } - *first_byte_ptr = bmp_ptr->out_row_bytes - bmp_ptr->col_num - 1; - } - if (_bmp_read_data(bmp_ptr, &second_byte_ptr, - size & 1 ? size + 1 : size) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - for (uint8_t i = 0; i < *first_byte_ptr; i++) { - if (i & 0x01) { - *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = - (*second_byte_ptr++ & 0x0F); - } else { - *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = - ((*second_byte_ptr & 0xF0) >> 4); - } - } - } - } - } break; - default: { - if (_bmp_read_data(bmp_ptr, &second_byte_ptr, 1) == NULL) { - bmp_ptr->skip_size = skip_size_org; - return 2; - } - if ((int32_t)*first_byte_ptr > - bmp_ptr->out_row_bytes - bmp_ptr->col_num) { - uint8_t size = (uint8_t)(((FX_WORD)(*first_byte_ptr) + 1) >> 1); - if (size + (bmp_ptr->col_num >> 1) > bmp_ptr->src_row_bytes) { - _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); - return 0; - } - *first_byte_ptr = bmp_ptr->out_row_bytes - bmp_ptr->col_num - 1; - } - for (uint8_t i = 0; i < *first_byte_ptr; i++) { - if (i & 0x01) { - *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = - (*second_byte_ptr & 0x0F); - } else { - *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = - ((*second_byte_ptr & 0xF0) >> 4); - } - } - } - } - } - _bmp_error(bmp_ptr, "Any Uncontrol Error"); - return 0; -} -uint8_t* _bmp_read_data(bmp_decompress_struct_p bmp_ptr, - uint8_t** des_buf_pp, - FX_DWORD data_size) { - if (bmp_ptr == NULL || bmp_ptr->avail_in < bmp_ptr->skip_size + data_size) { - return NULL; - } - *des_buf_pp = bmp_ptr->next_in + bmp_ptr->skip_size; - bmp_ptr->skip_size += data_size; - return *des_buf_pp; -} -void _bmp_save_decoding_status(bmp_decompress_struct_p bmp_ptr, - int32_t status) { - bmp_ptr->decode_status = status; - bmp_ptr->next_in += bmp_ptr->skip_size; - bmp_ptr->avail_in -= bmp_ptr->skip_size; - bmp_ptr->skip_size = 0; -} -void _bmp_input_buffer(bmp_decompress_struct_p bmp_ptr, - uint8_t* src_buf, - FX_DWORD src_size) { - bmp_ptr->next_in = src_buf; - bmp_ptr->avail_in = src_size; - bmp_ptr->skip_size = 0; -} -FX_DWORD _bmp_get_avail_input(bmp_decompress_struct_p bmp_ptr, - uint8_t** avial_buf_ptr) { - if (avial_buf_ptr != NULL) { - *avial_buf_ptr = NULL; - if (bmp_ptr->avail_in > 0) { - *avial_buf_ptr = bmp_ptr->next_in; - } - } - return bmp_ptr->avail_in; -} -bmp_compress_struct_p _bmp_create_compress() { - bmp_compress_struct_p bmp_ptr; - bmp_ptr = FX_Alloc(bmp_compress_struct, 1); - if (bmp_ptr) { - FXSYS_memset(bmp_ptr, 0, sizeof(bmp_compress_struct)); - } - return bmp_ptr; -} -void _bmp_destroy_compress(bmp_compress_struct_p bmp_ptr) { - if (bmp_ptr) { - if (bmp_ptr->src_free && bmp_ptr->src_buf) { - FX_Free(bmp_ptr->src_buf); - } - FX_Free(bmp_ptr); - } -} -static void WriteFileHeader(BmpFileHeaderPtr head_ptr, uint8_t* dst_buf) { - FX_DWORD offset; - offset = 0; - _SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfType); - offset += 2; - _SetDWord_LSBFirst(&dst_buf[offset], head_ptr->bfSize); - offset += 4; - _SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfReserved1); - offset += 2; - _SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfReserved2); - offset += 2; - _SetDWord_LSBFirst(&dst_buf[offset], head_ptr->bfOffBits); - offset += 4; -} -static void WriteInfoHeader(BmpInfoHeaderPtr info_head_ptr, uint8_t* dst_buf) { - FX_DWORD offset; - offset = sizeof(BmpFileHeader); - _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biSize); - offset += 4; - _SetDWord_LSBFirst(&dst_buf[offset], (FX_DWORD)info_head_ptr->biWidth); - offset += 4; - _SetDWord_LSBFirst(&dst_buf[offset], (FX_DWORD)info_head_ptr->biHeight); - offset += 4; - _SetWord_LSBFirst(&dst_buf[offset], info_head_ptr->biPlanes); - offset += 2; - _SetWord_LSBFirst(&dst_buf[offset], info_head_ptr->biBitCount); - offset += 2; - _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biCompression); - offset += 4; - _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biSizeImage); - offset += 4; - _SetDWord_LSBFirst(&dst_buf[offset], - (FX_DWORD)info_head_ptr->biXPelsPerMeter); - offset += 4; - _SetDWord_LSBFirst(&dst_buf[offset], - (FX_DWORD)info_head_ptr->biYPelsPerMeter); - offset += 4; - _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biClrUsed); - offset += 4; - _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biClrImportant); - offset += 4; -} -#ifdef BMP_SUPPORT_BITFIELD -static void _bmp_encode_bitfields(bmp_compress_struct_p bmp_ptr, - uint8_t*& dst_buf, - FX_DWORD& dst_size) { - if (bmp_ptr->info_header.biBitCount != 16 && - bmp_ptr->info_header.biBitCount != 32) { - return; - } - FX_DWORD size, dst_pos, i; - size = bmp_ptr->src_pitch * bmp_ptr->src_row * - bmp_ptr->info_header.biBitCount / 16; - dst_pos = bmp_ptr->file_header.bfOffBits; - dst_size += size; - dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); - if (dst_buf == NULL) { - return; - } - FXSYS_memset(&dst_buf[dst_pos], 0, size); - FX_DWORD mask_red; - FX_DWORD mask_green; - FX_DWORD mask_blue; - mask_red = 0x7C00; - mask_green = 0x03E0; - mask_blue = 0x001F; - if (bmp_ptr->info_header.biCompression == BMP_BITFIELDS) { - if (bmp_ptr->bit_type == BMP_BIT_565) { - mask_red = 0xF800; - mask_green = 0x07E0; - mask_blue = 0x001F; - } - if (bmp_ptr->info_header.biBitCount == 32) { - mask_red = 0xFF0000; - mask_green = 0x00FF00; - mask_blue = 0x0000FF; - } - _SetDWord_LSBFirst(&dst_buf[dst_pos], mask_red); - dst_pos += 4; - _SetDWord_LSBFirst(&dst_buf[dst_pos], mask_green); - dst_pos += 4; - _SetDWord_LSBFirst(&dst_buf[dst_pos], mask_blue); - dst_pos += 4; - bmp_ptr->file_header.bfOffBits = dst_pos; - } - uint8_t blue_bits = 0; - uint8_t green_bits = 0; - uint8_t red_bits = 0; - for (i = 0; i < bmp_ptr->info_header.biBitCount; i++) { - if ((mask_blue >> i) & 0x01) { - blue_bits++; - } - if ((mask_green >> i) & 0x01) { - green_bits++; - } - if ((mask_red >> i) & 0x01) { - red_bits++; - } - } - green_bits += blue_bits; - red_bits += green_bits; - blue_bits = 8 - blue_bits; - green_bits -= 8; - red_bits -= 8; - i = 0; - for (int32_t row_num = bmp_ptr->src_row - 1; row_num > -1; row_num--, i = 0) { - while (i < bmp_ptr->src_width * bmp_ptr->src_bpp / 8) { - uint8_t b = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; - uint8_t g = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; - uint8_t r = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; - if (bmp_ptr->src_bpp == 32) { - i++; - } - FX_DWORD pix_val = 0; - pix_val |= (b >> blue_bits) & mask_blue; - pix_val |= (g << green_bits) & mask_green; - pix_val |= (r << red_bits) & mask_red; - if (bmp_ptr->info_header.biBitCount == 16) { - _SetWord_LSBFirst(&dst_buf[dst_pos], (FX_WORD)pix_val); - dst_pos += 2; - } else { - _SetDWord_LSBFirst(&dst_buf[dst_pos], pix_val); - dst_pos += 4; - } - } - } - dst_size = dst_pos; -} -#endif -static void _bmp_encode_rgb(bmp_compress_struct_p bmp_ptr, - uint8_t*& dst_buf, - FX_DWORD& dst_size) { - if (bmp_ptr->info_header.biBitCount == 16) { -#ifdef BMP_SUPPORT_BITFIELD - _bmp_encode_bitfields(bmp_ptr, dst_buf, dst_size); -#endif - return; - } - FX_DWORD size, dst_pos; - FX_DWORD dst_pitch = - (bmp_ptr->src_width * bmp_ptr->info_header.biBitCount + 31) / 32 * 4; - size = dst_pitch * bmp_ptr->src_row; - dst_pos = bmp_ptr->file_header.bfOffBits; - dst_size += size; - dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); - if (dst_buf == NULL) { - return; - } - FXSYS_memset(&dst_buf[dst_pos], 0, size); - for (int32_t row_num = bmp_ptr->src_row - 1; row_num > -1; row_num--) { - FXSYS_memcpy(&dst_buf[dst_pos], - &bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch], - bmp_ptr->src_pitch); - dst_pos += dst_pitch; - } - dst_size = dst_pos; -} -static uint8_t _bmp_rle8_search(const uint8_t* buf, int32_t len) { - uint8_t num; - num = 1; - while (num < len) { - if (buf[num - 1] != buf[num] || num == 0xFF) { - break; - } - num++; - } - return num; -} -static void _bmp_encode_rle8(bmp_compress_struct_p bmp_ptr, - uint8_t*& dst_buf, - FX_DWORD& dst_size) { - FX_DWORD size, dst_pos, index; - uint8_t rle[2] = {0}; - size = bmp_ptr->src_pitch * bmp_ptr->src_row * 2; - dst_pos = bmp_ptr->file_header.bfOffBits; - dst_size += size; - dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); - if (dst_buf == NULL) { - return; - } - FXSYS_memset(&dst_buf[dst_pos], 0, size); - for (int32_t row_num = bmp_ptr->src_row - 1, i = 0; row_num > -1;) { - index = row_num * bmp_ptr->src_pitch; - rle[0] = _bmp_rle8_search(&bmp_ptr->src_buf[index + i], size - index - i); - rle[1] = bmp_ptr->src_buf[index + i]; - if (i + rle[0] >= (int32_t)bmp_ptr->src_pitch) { - rle[0] = uint8_t(bmp_ptr->src_pitch - i); - if (rle[0]) { - dst_buf[dst_pos++] = rle[0]; - dst_buf[dst_pos++] = rle[1]; - } - dst_buf[dst_pos++] = RLE_MARKER; - dst_buf[dst_pos++] = RLE_EOL; - i = 0; - row_num--; - } else { - i += rle[0]; - dst_buf[dst_pos++] = rle[0]; - dst_buf[dst_pos++] = rle[1]; - } - } - dst_buf[dst_pos++] = RLE_MARKER; - dst_buf[dst_pos++] = RLE_EOI; - dst_size = dst_pos; -} -static uint8_t _bmp_rle4_search(const uint8_t* buf, int32_t len) { - uint8_t num; - num = 2; - while (num < len) { - if (buf[num - 2] != buf[num] || num == 0xFF) { - break; - } - num++; - } - return num; -} -static void _bmp_encode_rle4(bmp_compress_struct_p bmp_ptr, - uint8_t*& dst_buf, - FX_DWORD& dst_size) { - FX_DWORD size, dst_pos, index; - uint8_t rle[2] = {0}; - size = bmp_ptr->src_pitch * bmp_ptr->src_row; - dst_pos = bmp_ptr->file_header.bfOffBits; - dst_size += size; - dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); - if (dst_buf == NULL) { - return; - } - FXSYS_memset(&dst_buf[dst_pos], 0, size); - for (int32_t row_num = bmp_ptr->src_row - 1, i = 0; row_num > -1; - rle[1] = 0) { - index = row_num * bmp_ptr->src_pitch; - rle[0] = _bmp_rle4_search(&bmp_ptr->src_buf[index + i], size - index - i); - rle[1] |= (bmp_ptr->src_buf[index + i] & 0x0f) << 4; - rle[1] |= bmp_ptr->src_buf[index + i + 1] & 0x0f; - if (i + rle[0] >= (int32_t)bmp_ptr->src_pitch) { - rle[0] = uint8_t(bmp_ptr->src_pitch - i); - if (rle[0]) { - dst_buf[dst_pos++] = rle[0]; - dst_buf[dst_pos++] = rle[1]; - } - dst_buf[dst_pos++] = RLE_MARKER; - dst_buf[dst_pos++] = RLE_EOL; - i = 0; - row_num--; - } else { - i += rle[0]; - dst_buf[dst_pos++] = rle[0]; - dst_buf[dst_pos++] = rle[1]; - } - } - dst_buf[dst_pos++] = RLE_MARKER; - dst_buf[dst_pos++] = RLE_EOI; - dst_size = dst_pos; -} -FX_BOOL _bmp_encode_image(bmp_compress_struct_p bmp_ptr, - uint8_t*& dst_buf, - FX_DWORD& dst_size) { - FX_DWORD head_size = sizeof(BmpFileHeader) + sizeof(BmpInfoHeader); - FX_DWORD pal_size = sizeof(FX_DWORD) * bmp_ptr->pal_num; - if (bmp_ptr->info_header.biClrUsed > 0 && - bmp_ptr->info_header.biClrUsed < bmp_ptr->pal_num) { - pal_size = sizeof(FX_DWORD) * bmp_ptr->info_header.biClrUsed; - } - dst_size = head_size + sizeof(FX_DWORD) * bmp_ptr->pal_num; - dst_buf = FX_TryAlloc(uint8_t, dst_size); - if (dst_buf == NULL) { - return FALSE; - } - FXSYS_memset(dst_buf, 0, dst_size); - bmp_ptr->file_header.bfOffBits = head_size; - if (bmp_ptr->pal_ptr && pal_size) { - FXSYS_memcpy(&dst_buf[head_size], bmp_ptr->pal_ptr, pal_size); - bmp_ptr->file_header.bfOffBits += pal_size; - } - WriteInfoHeader(&bmp_ptr->info_header, dst_buf); - switch (bmp_ptr->info_header.biCompression) { - case BMP_RGB: - _bmp_encode_rgb(bmp_ptr, dst_buf, dst_size); - break; - case BMP_BITFIELDS: -#ifdef BMP_SUPPORT_BITFIELD - _bmp_encode_bitfields(bmp_ptr, dst_buf, dst_size); -#endif - break; - case BMP_RLE8: - _bmp_encode_rle8(bmp_ptr, dst_buf, dst_size); - break; - case BMP_RLE4: - _bmp_encode_rle4(bmp_ptr, dst_buf, dst_size); - break; - default:; - } - bmp_ptr->file_header.bfSize = dst_size; - WriteFileHeader(&bmp_ptr->file_header, dst_buf); - return TRUE; -} +// 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 "fx_bmp.h" + +#include + +namespace { + +const size_t kBmpCoreHeaderSize = 12; +const size_t kBmpInfoHeaderSize = 40; + +} // namespace + +FX_DWORD _GetDWord_LSBFirst(uint8_t* p) { + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} +FX_WORD _GetWord_LSBFirst(uint8_t* p) { + return p[0] | (p[1] << 8); +} +void _SetDWord_LSBFirst(uint8_t* p, FX_DWORD v) { + p[0] = (uint8_t)v; + p[1] = (uint8_t)(v >> 8); + p[2] = (uint8_t)(v >> 16); + p[3] = (uint8_t)(v >> 24); +} +void _SetWord_LSBFirst(uint8_t* p, FX_WORD v) { + p[0] = (uint8_t)v; + p[1] = (uint8_t)(v >> 8); +} +void _bmp_error(bmp_decompress_struct_p bmp_ptr, const FX_CHAR* err_msg) { + if (bmp_ptr != NULL && bmp_ptr->_bmp_error_fn != NULL) { + bmp_ptr->_bmp_error_fn(bmp_ptr, err_msg); + } +} +bmp_decompress_struct_p _bmp_create_decompress() { + bmp_decompress_struct_p bmp_ptr = FX_Alloc(bmp_decompress_struct, 1); + if (bmp_ptr == NULL) { + return NULL; + } + FXSYS_memset(bmp_ptr, 0, sizeof(bmp_decompress_struct)); + bmp_ptr->decode_status = BMP_D_STATUS_HEADER; + bmp_ptr->bmp_header_ptr = FX_Alloc(BmpFileHeader, 1); + return bmp_ptr; +} +void _bmp_destroy_decompress(bmp_decompress_struct_pp bmp_ptr_ptr) { + if (bmp_ptr_ptr == NULL || *bmp_ptr_ptr == NULL) { + return; + } + bmp_decompress_struct_p bmp_ptr = *bmp_ptr_ptr; + *bmp_ptr_ptr = NULL; + if (bmp_ptr->out_row_buffer != NULL) { + FX_Free(bmp_ptr->out_row_buffer); + } + if (bmp_ptr->pal_ptr != NULL) { + FX_Free(bmp_ptr->pal_ptr); + } + if (bmp_ptr->bmp_header_ptr != NULL) { + FX_Free(bmp_ptr->bmp_header_ptr); + } + FX_Free(bmp_ptr); +} +int32_t _bmp_read_header(bmp_decompress_struct_p bmp_ptr) { + if (bmp_ptr == NULL) { + return 0; + } + FX_DWORD skip_size_org = bmp_ptr->skip_size; + if (bmp_ptr->decode_status == BMP_D_STATUS_HEADER) { + ASSERT(sizeof(BmpFileHeader) == 14); + BmpFileHeader* bmp_header_ptr = NULL; + if (_bmp_read_data(bmp_ptr, (uint8_t**)&bmp_header_ptr, 14) == NULL) { + return 2; + } + bmp_ptr->bmp_header_ptr->bfType = + _GetWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfType); + bmp_ptr->bmp_header_ptr->bfOffBits = + _GetDWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfOffBits); + bmp_ptr->data_size = _GetDWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfSize); + if (bmp_ptr->bmp_header_ptr->bfType != BMP_SIGNATURE) { + _bmp_error(bmp_ptr, "Not A Bmp Image"); + return 0; + } + if (bmp_ptr->avail_in < sizeof(FX_DWORD)) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + bmp_ptr->img_ifh_size = + _GetDWord_LSBFirst(bmp_ptr->next_in + bmp_ptr->skip_size); + bmp_ptr->pal_type = 0; + static_assert(sizeof(BmpCoreHeader) == kBmpCoreHeaderSize, + "BmpCoreHeader has wrong size"); + static_assert(sizeof(BmpInfoHeader) == kBmpInfoHeaderSize, + "BmpInfoHeader has wrong size"); + switch (bmp_ptr->img_ifh_size) { + case kBmpCoreHeaderSize: { + bmp_ptr->pal_type = 1; + BmpCoreHeaderPtr bmp_core_header_ptr = NULL; + if (_bmp_read_data(bmp_ptr, (uint8_t**)&bmp_core_header_ptr, + bmp_ptr->img_ifh_size) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + bmp_ptr->width = (FX_DWORD)_GetWord_LSBFirst( + (uint8_t*)&bmp_core_header_ptr->bcWidth); + bmp_ptr->height = (FX_DWORD)_GetWord_LSBFirst( + (uint8_t*)&bmp_core_header_ptr->bcHeight); + bmp_ptr->bitCounts = + _GetWord_LSBFirst((uint8_t*)&bmp_core_header_ptr->bcBitCount); + bmp_ptr->compress_flag = BMP_RGB; + bmp_ptr->imgTB_flag = FALSE; + } break; + case kBmpInfoHeaderSize: { + BmpInfoHeaderPtr bmp_info_header_ptr = NULL; + if (_bmp_read_data(bmp_ptr, (uint8_t**)&bmp_info_header_ptr, + bmp_ptr->img_ifh_size) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + bmp_ptr->width = + _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biWidth); + bmp_ptr->height = + _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biHeight); + bmp_ptr->bitCounts = + _GetWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biBitCount); + bmp_ptr->compress_flag = + _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biCompression); + bmp_ptr->color_used = + _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biClrUsed); + bmp_ptr->dpi_x = (int32_t)_GetDWord_LSBFirst( + (uint8_t*)&bmp_info_header_ptr->biXPelsPerMeter); + bmp_ptr->dpi_y = (int32_t)_GetDWord_LSBFirst( + (uint8_t*)&bmp_info_header_ptr->biYPelsPerMeter); + if (bmp_ptr->height < 0) { + bmp_ptr->height = -bmp_ptr->height; + bmp_ptr->imgTB_flag = TRUE; + } + } break; + default: { + if (bmp_ptr->img_ifh_size > + std::min(kBmpInfoHeaderSize, sizeof(BmpInfoHeader))) { + BmpInfoHeaderPtr bmp_info_header_ptr = NULL; + if (_bmp_read_data(bmp_ptr, (uint8_t**)&bmp_info_header_ptr, + bmp_ptr->img_ifh_size) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + FX_WORD biPlanes; + bmp_ptr->width = + _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biWidth); + bmp_ptr->height = + _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biHeight); + bmp_ptr->bitCounts = + _GetWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biBitCount); + bmp_ptr->compress_flag = + _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biCompression); + bmp_ptr->color_used = + _GetDWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biClrUsed); + biPlanes = + _GetWord_LSBFirst((uint8_t*)&bmp_info_header_ptr->biPlanes); + bmp_ptr->dpi_x = _GetDWord_LSBFirst( + (uint8_t*)&bmp_info_header_ptr->biXPelsPerMeter); + bmp_ptr->dpi_y = _GetDWord_LSBFirst( + (uint8_t*)&bmp_info_header_ptr->biYPelsPerMeter); + if (bmp_ptr->height < 0) { + bmp_ptr->height = -bmp_ptr->height; + bmp_ptr->imgTB_flag = TRUE; + } + if (bmp_ptr->compress_flag == BMP_RGB && biPlanes == 1 && + bmp_ptr->color_used == 0) { + break; + } + } + _bmp_error(bmp_ptr, "Unsupported Bmp File"); + return 0; + } + } + ASSERT(bmp_ptr->width > 0); + ASSERT(bmp_ptr->compress_flag <= BMP_BITFIELDS); + switch (bmp_ptr->bitCounts) { + case 1: + case 4: + case 8: + case 16: + case 24: { + if (bmp_ptr->color_used > ((FX_DWORD)1) << bmp_ptr->bitCounts) { + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); + return 0; + } + } + case 32: { + if (bmp_ptr->width <= 0 || bmp_ptr->compress_flag > BMP_BITFIELDS) { + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); + return 0; + } + } break; + default: + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); + return 0; + } + bmp_ptr->src_row_bytes = BMP_WIDTHBYTES(bmp_ptr->width, bmp_ptr->bitCounts); + switch (bmp_ptr->bitCounts) { + case 1: + case 4: + case 8: + bmp_ptr->out_row_bytes = BMP_WIDTHBYTES(bmp_ptr->width, 8); + bmp_ptr->components = 1; + break; + case 16: + case 24: + bmp_ptr->out_row_bytes = BMP_WIDTHBYTES(bmp_ptr->width, 24); + bmp_ptr->components = 3; + break; + case 32: + bmp_ptr->out_row_bytes = bmp_ptr->src_row_bytes; + bmp_ptr->components = 4; + break; + } + if (bmp_ptr->out_row_buffer != NULL) { + FX_Free(bmp_ptr->out_row_buffer); + bmp_ptr->out_row_buffer = NULL; + } + bmp_ptr->out_row_buffer = FX_Alloc(uint8_t, bmp_ptr->out_row_bytes); + BMP_PTR_NOT_NULL(bmp_ptr->out_row_buffer, bmp_ptr); + FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_PAL); + } + if (bmp_ptr->decode_status == BMP_D_STATUS_PAL) { + skip_size_org = bmp_ptr->skip_size; +#ifdef BMP_SUPPORT_BITFIELD + if (bmp_ptr->compress_flag == BMP_BITFIELDS) { + if (bmp_ptr->bitCounts != 16 && bmp_ptr->bitCounts != 32) { + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); + return 0; + } + FX_DWORD* mask; + if (_bmp_read_data(bmp_ptr, (uint8_t**)&mask, 3 * sizeof(FX_DWORD)) == + NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + bmp_ptr->mask_red = _GetDWord_LSBFirst((uint8_t*)&mask[0]); + bmp_ptr->mask_green = _GetDWord_LSBFirst((uint8_t*)&mask[1]); + bmp_ptr->mask_blue = _GetDWord_LSBFirst((uint8_t*)&mask[2]); + if (bmp_ptr->mask_red & bmp_ptr->mask_green || + bmp_ptr->mask_red & bmp_ptr->mask_blue || + bmp_ptr->mask_green & bmp_ptr->mask_blue) { + _bmp_error(bmp_ptr, "The Bitfield Bmp File Is Corrupt"); + return 0; + } + if (bmp_ptr->bmp_header_ptr->bfOffBits < 26 + bmp_ptr->img_ifh_size) { + bmp_ptr->bmp_header_ptr->bfOffBits = 26 + bmp_ptr->img_ifh_size; + } + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA_PRE); + return 1; + } else if (bmp_ptr->bitCounts == 16) { + bmp_ptr->mask_red = 0x7C00; + bmp_ptr->mask_green = 0x03E0; + bmp_ptr->mask_blue = 0x001F; + } +#else + if (bmp_ptr->compress_flag == BMP_BITFIELDS || bmp_ptr->bitCounts == 16) { + _bmp_error(bmp_ptr, "Unsupported Bitfield Bmp File"); + return 0; + } +#endif + bmp_ptr->pal_num = 0; + if (bmp_ptr->bitCounts < 16) { + bmp_ptr->pal_num = 1 << bmp_ptr->bitCounts; + if (bmp_ptr->color_used != 0) { + bmp_ptr->pal_num = bmp_ptr->color_used; + } + uint8_t* src_pal_ptr = NULL; + FX_DWORD src_pal_size = bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4); + if (_bmp_read_data(bmp_ptr, (uint8_t**)&src_pal_ptr, src_pal_size) == + NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + if (bmp_ptr->pal_ptr != NULL) { + FX_Free(bmp_ptr->pal_ptr); + bmp_ptr->pal_ptr = NULL; + } + bmp_ptr->pal_ptr = FX_Alloc(FX_DWORD, bmp_ptr->pal_num); + BMP_PTR_NOT_NULL(bmp_ptr->pal_ptr, bmp_ptr); + int32_t src_pal_index = 0; + if (bmp_ptr->pal_type == BMP_PAL_OLD) { + while (src_pal_index < bmp_ptr->pal_num) { + bmp_ptr->pal_ptr[src_pal_index++] = BMP_PAL_ENCODE( + 0x00, src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]); + src_pal_ptr += 3; + } + } else { + while (src_pal_index < bmp_ptr->pal_num) { + bmp_ptr->pal_ptr[src_pal_index++] = BMP_PAL_ENCODE( + src_pal_ptr[3], src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]); + src_pal_ptr += 4; + } + } + } + if (bmp_ptr->bmp_header_ptr->bfOffBits < + 14 + bmp_ptr->img_ifh_size + + bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4)) { + bmp_ptr->bmp_header_ptr->bfOffBits = + 14 + bmp_ptr->img_ifh_size + + bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4); + } + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA_PRE); + } + return 1; +} +int32_t _bmp_decode_image(bmp_decompress_struct_p bmp_ptr) { + if (bmp_ptr->decode_status == BMP_D_STATUS_DATA_PRE) { + bmp_ptr->avail_in = 0; + if (!bmp_ptr->_bmp_get_data_position_fn( + bmp_ptr, bmp_ptr->bmp_header_ptr->bfOffBits)) { + bmp_ptr->decode_status = BMP_D_STATUS_TAIL; + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt, Unexpected Stream Offset"); + return 0; + } + bmp_ptr->row_num = 0; + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA); + } + if (bmp_ptr->decode_status == BMP_D_STATUS_DATA) { + switch (bmp_ptr->compress_flag) { + case BMP_RGB: + case BMP_BITFIELDS: + return _bmp_decode_rgb(bmp_ptr); + case BMP_RLE8: + return _bmp_decode_rle8(bmp_ptr); + case BMP_RLE4: + return _bmp_decode_rle4(bmp_ptr); + } + } + _bmp_error(bmp_ptr, "Any Uncontrol Error"); + return 0; +} +int32_t _bmp_decode_rgb(bmp_decompress_struct_p bmp_ptr) { + uint8_t* row_buf = bmp_ptr->out_row_buffer; + uint8_t* des_buf = NULL; + while (bmp_ptr->row_num < bmp_ptr->height) { + if (_bmp_read_data(bmp_ptr, &des_buf, bmp_ptr->src_row_bytes) == NULL) { + return 2; + } + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA); + switch (bmp_ptr->bitCounts) { + case 1: { + for (int32_t col = 0; col < bmp_ptr->width; col++) { + *row_buf++ = des_buf[col >> 3] & (0x80 >> (col % 8)) ? 0x01 : 0x00; + } + } break; + case 4: { + for (int32_t col = 0; col < bmp_ptr->width; col++) { + *row_buf++ = (col & 0x01) ? (des_buf[col >> 1] & 0x0F) + : ((des_buf[col >> 1] & 0xF0) >> 4); + } + } break; +#ifdef BMP_SUPPORT_BITFIELD + case 16: { + FX_WORD* buf = (FX_WORD*)des_buf; + uint8_t blue_bits = 0; + uint8_t green_bits = 0; + uint8_t red_bits = 0; + for (int32_t i = 0; i < 16; i++) { + if ((bmp_ptr->mask_blue >> i) & 0x01) { + blue_bits++; + } + if ((bmp_ptr->mask_green >> i) & 0x01) { + green_bits++; + } + if ((bmp_ptr->mask_red >> i) & 0x01) { + red_bits++; + } + } + green_bits += blue_bits; + red_bits += green_bits; + blue_bits = 8 - blue_bits; + green_bits -= 8; + red_bits -= 8; + for (int32_t col = 0; col < bmp_ptr->width; col++) { + *buf = _GetWord_LSBFirst((uint8_t*)buf); + *row_buf++ = (uint8_t)((*buf & bmp_ptr->mask_blue) << blue_bits); + *row_buf++ = (uint8_t)((*buf & bmp_ptr->mask_green) >> green_bits); + *row_buf++ = (uint8_t)((*buf++ & bmp_ptr->mask_red) >> red_bits); + } + } break; +#endif + case 8: + case 24: + case 32: + FXSYS_memcpy(bmp_ptr->out_row_buffer, des_buf, bmp_ptr->src_row_bytes); + break; + } + row_buf = bmp_ptr->out_row_buffer; + bmp_ptr->_bmp_get_row_fn(bmp_ptr, + bmp_ptr->imgTB_flag + ? bmp_ptr->row_num++ + : (bmp_ptr->height - 1 - bmp_ptr->row_num++), + bmp_ptr->out_row_buffer); + } + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); + return 1; +} +int32_t _bmp_decode_rle8(bmp_decompress_struct_p bmp_ptr) { + uint8_t* first_byte_ptr = NULL; + uint8_t* second_byte_ptr = NULL; + bmp_ptr->col_num = 0; + while (TRUE) { + FX_DWORD skip_size_org = bmp_ptr->skip_size; + if (_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { + return 2; + } + switch (*first_byte_ptr) { + case RLE_MARKER: { + if (_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + switch (*first_byte_ptr) { + case RLE_EOL: { + if (bmp_ptr->row_num >= bmp_ptr->height) { + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); + return 0; + } + bmp_ptr->_bmp_get_row_fn( + bmp_ptr, bmp_ptr->imgTB_flag + ? bmp_ptr->row_num++ + : (bmp_ptr->height - 1 - bmp_ptr->row_num++), + bmp_ptr->out_row_buffer); + bmp_ptr->col_num = 0; + FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA); + continue; + } + case RLE_EOI: { + if (bmp_ptr->row_num < bmp_ptr->height) { + bmp_ptr->_bmp_get_row_fn( + bmp_ptr, bmp_ptr->imgTB_flag + ? bmp_ptr->row_num++ + : (bmp_ptr->height - 1 - bmp_ptr->row_num++), + bmp_ptr->out_row_buffer); + } + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); + return 1; + } + case RLE_DELTA: { + uint8_t* delta_ptr; + if (_bmp_read_data(bmp_ptr, &delta_ptr, 2) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + bmp_ptr->col_num += (int32_t)delta_ptr[0]; + int32_t bmp_row_num_next = bmp_ptr->row_num + (int32_t)delta_ptr[1]; + if (bmp_ptr->col_num >= bmp_ptr->out_row_bytes || + bmp_row_num_next >= bmp_ptr->height) { + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt Or Not Supported"); + return 0; + } + while (bmp_ptr->row_num < bmp_row_num_next) { + FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); + bmp_ptr->_bmp_get_row_fn( + bmp_ptr, bmp_ptr->imgTB_flag + ? bmp_ptr->row_num++ + : (bmp_ptr->height - 1 - bmp_ptr->row_num++), + bmp_ptr->out_row_buffer); + } + } break; + default: { + if ((int32_t)(*first_byte_ptr) > + bmp_ptr->src_row_bytes - bmp_ptr->col_num) { + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); + return 0; + } + if (_bmp_read_data(bmp_ptr, &second_byte_ptr, + *first_byte_ptr & 1 ? *first_byte_ptr + 1 + : *first_byte_ptr) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + FXSYS_memcpy(bmp_ptr->out_row_buffer + bmp_ptr->col_num, + second_byte_ptr, *first_byte_ptr); + bmp_ptr->col_num += (int32_t)(*first_byte_ptr); + } + } + } break; + default: { + if (_bmp_read_data(bmp_ptr, &second_byte_ptr, 1) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + if ((int32_t)(*first_byte_ptr) > + bmp_ptr->src_row_bytes - bmp_ptr->col_num) { + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); + return 0; + } + FXSYS_memset(bmp_ptr->out_row_buffer + bmp_ptr->col_num, + *second_byte_ptr, *first_byte_ptr); + bmp_ptr->col_num += (int32_t)(*first_byte_ptr); + } + } + } + _bmp_error(bmp_ptr, "Any Uncontrol Error"); + return 0; +} +int32_t _bmp_decode_rle4(bmp_decompress_struct_p bmp_ptr) { + uint8_t* first_byte_ptr = NULL; + uint8_t* second_byte_ptr = NULL; + bmp_ptr->col_num = 0; + while (TRUE) { + FX_DWORD skip_size_org = bmp_ptr->skip_size; + if (_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { + return 2; + } + switch (*first_byte_ptr) { + case RLE_MARKER: { + if (_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + switch (*first_byte_ptr) { + case RLE_EOL: { + if (bmp_ptr->row_num >= bmp_ptr->height) { + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); + return 0; + } + bmp_ptr->_bmp_get_row_fn( + bmp_ptr, bmp_ptr->imgTB_flag + ? bmp_ptr->row_num++ + : (bmp_ptr->height - 1 - bmp_ptr->row_num++), + bmp_ptr->out_row_buffer); + bmp_ptr->col_num = 0; + FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA); + continue; + } + case RLE_EOI: { + if (bmp_ptr->row_num < bmp_ptr->height) { + bmp_ptr->_bmp_get_row_fn( + bmp_ptr, bmp_ptr->imgTB_flag + ? bmp_ptr->row_num++ + : (bmp_ptr->height - 1 - bmp_ptr->row_num++), + bmp_ptr->out_row_buffer); + } + _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); + return 1; + } + case RLE_DELTA: { + uint8_t* delta_ptr; + if (_bmp_read_data(bmp_ptr, &delta_ptr, 2) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + bmp_ptr->col_num += (int32_t)delta_ptr[0]; + int32_t bmp_row_num_next = bmp_ptr->row_num + (int32_t)delta_ptr[1]; + if (bmp_ptr->col_num >= bmp_ptr->out_row_bytes || + bmp_row_num_next >= bmp_ptr->height) { + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt Or Not Supported"); + return 0; + } + while (bmp_ptr->row_num < bmp_row_num_next) { + FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); + bmp_ptr->_bmp_get_row_fn( + bmp_ptr, bmp_ptr->imgTB_flag + ? bmp_ptr->row_num++ + : (bmp_ptr->height - 1 - bmp_ptr->row_num++), + bmp_ptr->out_row_buffer); + } + } break; + default: { + uint8_t size = (uint8_t)(((FX_WORD)(*first_byte_ptr) + 1) >> 1); + if ((int32_t)*first_byte_ptr >= + bmp_ptr->out_row_bytes - bmp_ptr->col_num) { + if (size + (bmp_ptr->col_num >> 1) > bmp_ptr->src_row_bytes) { + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); + return 0; + } + *first_byte_ptr = bmp_ptr->out_row_bytes - bmp_ptr->col_num - 1; + } + if (_bmp_read_data(bmp_ptr, &second_byte_ptr, + size & 1 ? size + 1 : size) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + for (uint8_t i = 0; i < *first_byte_ptr; i++) { + if (i & 0x01) { + *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = + (*second_byte_ptr++ & 0x0F); + } else { + *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = + ((*second_byte_ptr & 0xF0) >> 4); + } + } + } + } + } break; + default: { + if (_bmp_read_data(bmp_ptr, &second_byte_ptr, 1) == NULL) { + bmp_ptr->skip_size = skip_size_org; + return 2; + } + if ((int32_t)*first_byte_ptr > + bmp_ptr->out_row_bytes - bmp_ptr->col_num) { + uint8_t size = (uint8_t)(((FX_WORD)(*first_byte_ptr) + 1) >> 1); + if (size + (bmp_ptr->col_num >> 1) > bmp_ptr->src_row_bytes) { + _bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); + return 0; + } + *first_byte_ptr = bmp_ptr->out_row_bytes - bmp_ptr->col_num - 1; + } + for (uint8_t i = 0; i < *first_byte_ptr; i++) { + if (i & 0x01) { + *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = + (*second_byte_ptr & 0x0F); + } else { + *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = + ((*second_byte_ptr & 0xF0) >> 4); + } + } + } + } + } + _bmp_error(bmp_ptr, "Any Uncontrol Error"); + return 0; +} +uint8_t* _bmp_read_data(bmp_decompress_struct_p bmp_ptr, + uint8_t** des_buf_pp, + FX_DWORD data_size) { + if (bmp_ptr == NULL || bmp_ptr->avail_in < bmp_ptr->skip_size + data_size) { + return NULL; + } + *des_buf_pp = bmp_ptr->next_in + bmp_ptr->skip_size; + bmp_ptr->skip_size += data_size; + return *des_buf_pp; +} +void _bmp_save_decoding_status(bmp_decompress_struct_p bmp_ptr, + int32_t status) { + bmp_ptr->decode_status = status; + bmp_ptr->next_in += bmp_ptr->skip_size; + bmp_ptr->avail_in -= bmp_ptr->skip_size; + bmp_ptr->skip_size = 0; +} +void _bmp_input_buffer(bmp_decompress_struct_p bmp_ptr, + uint8_t* src_buf, + FX_DWORD src_size) { + bmp_ptr->next_in = src_buf; + bmp_ptr->avail_in = src_size; + bmp_ptr->skip_size = 0; +} +FX_DWORD _bmp_get_avail_input(bmp_decompress_struct_p bmp_ptr, + uint8_t** avial_buf_ptr) { + if (avial_buf_ptr != NULL) { + *avial_buf_ptr = NULL; + if (bmp_ptr->avail_in > 0) { + *avial_buf_ptr = bmp_ptr->next_in; + } + } + return bmp_ptr->avail_in; +} +bmp_compress_struct_p _bmp_create_compress() { + bmp_compress_struct_p bmp_ptr; + bmp_ptr = FX_Alloc(bmp_compress_struct, 1); + if (bmp_ptr) { + FXSYS_memset(bmp_ptr, 0, sizeof(bmp_compress_struct)); + } + return bmp_ptr; +} +void _bmp_destroy_compress(bmp_compress_struct_p bmp_ptr) { + if (bmp_ptr) { + if (bmp_ptr->src_free && bmp_ptr->src_buf) { + FX_Free(bmp_ptr->src_buf); + } + FX_Free(bmp_ptr); + } +} +static void WriteFileHeader(BmpFileHeaderPtr head_ptr, uint8_t* dst_buf) { + FX_DWORD offset; + offset = 0; + _SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfType); + offset += 2; + _SetDWord_LSBFirst(&dst_buf[offset], head_ptr->bfSize); + offset += 4; + _SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfReserved1); + offset += 2; + _SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfReserved2); + offset += 2; + _SetDWord_LSBFirst(&dst_buf[offset], head_ptr->bfOffBits); + offset += 4; +} +static void WriteInfoHeader(BmpInfoHeaderPtr info_head_ptr, uint8_t* dst_buf) { + FX_DWORD offset; + offset = sizeof(BmpFileHeader); + _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biSize); + offset += 4; + _SetDWord_LSBFirst(&dst_buf[offset], (FX_DWORD)info_head_ptr->biWidth); + offset += 4; + _SetDWord_LSBFirst(&dst_buf[offset], (FX_DWORD)info_head_ptr->biHeight); + offset += 4; + _SetWord_LSBFirst(&dst_buf[offset], info_head_ptr->biPlanes); + offset += 2; + _SetWord_LSBFirst(&dst_buf[offset], info_head_ptr->biBitCount); + offset += 2; + _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biCompression); + offset += 4; + _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biSizeImage); + offset += 4; + _SetDWord_LSBFirst(&dst_buf[offset], + (FX_DWORD)info_head_ptr->biXPelsPerMeter); + offset += 4; + _SetDWord_LSBFirst(&dst_buf[offset], + (FX_DWORD)info_head_ptr->biYPelsPerMeter); + offset += 4; + _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biClrUsed); + offset += 4; + _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biClrImportant); + offset += 4; +} +#ifdef BMP_SUPPORT_BITFIELD +static void _bmp_encode_bitfields(bmp_compress_struct_p bmp_ptr, + uint8_t*& dst_buf, + FX_DWORD& dst_size) { + if (bmp_ptr->info_header.biBitCount != 16 && + bmp_ptr->info_header.biBitCount != 32) { + return; + } + FX_DWORD size, dst_pos, i; + size = bmp_ptr->src_pitch * bmp_ptr->src_row * + bmp_ptr->info_header.biBitCount / 16; + dst_pos = bmp_ptr->file_header.bfOffBits; + dst_size += size; + dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); + if (dst_buf == NULL) { + return; + } + FXSYS_memset(&dst_buf[dst_pos], 0, size); + FX_DWORD mask_red; + FX_DWORD mask_green; + FX_DWORD mask_blue; + mask_red = 0x7C00; + mask_green = 0x03E0; + mask_blue = 0x001F; + if (bmp_ptr->info_header.biCompression == BMP_BITFIELDS) { + if (bmp_ptr->bit_type == BMP_BIT_565) { + mask_red = 0xF800; + mask_green = 0x07E0; + mask_blue = 0x001F; + } + if (bmp_ptr->info_header.biBitCount == 32) { + mask_red = 0xFF0000; + mask_green = 0x00FF00; + mask_blue = 0x0000FF; + } + _SetDWord_LSBFirst(&dst_buf[dst_pos], mask_red); + dst_pos += 4; + _SetDWord_LSBFirst(&dst_buf[dst_pos], mask_green); + dst_pos += 4; + _SetDWord_LSBFirst(&dst_buf[dst_pos], mask_blue); + dst_pos += 4; + bmp_ptr->file_header.bfOffBits = dst_pos; + } + uint8_t blue_bits = 0; + uint8_t green_bits = 0; + uint8_t red_bits = 0; + for (i = 0; i < bmp_ptr->info_header.biBitCount; i++) { + if ((mask_blue >> i) & 0x01) { + blue_bits++; + } + if ((mask_green >> i) & 0x01) { + green_bits++; + } + if ((mask_red >> i) & 0x01) { + red_bits++; + } + } + green_bits += blue_bits; + red_bits += green_bits; + blue_bits = 8 - blue_bits; + green_bits -= 8; + red_bits -= 8; + i = 0; + for (int32_t row_num = bmp_ptr->src_row - 1; row_num > -1; row_num--, i = 0) { + while (i < bmp_ptr->src_width * bmp_ptr->src_bpp / 8) { + uint8_t b = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; + uint8_t g = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; + uint8_t r = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; + if (bmp_ptr->src_bpp == 32) { + i++; + } + FX_DWORD pix_val = 0; + pix_val |= (b >> blue_bits) & mask_blue; + pix_val |= (g << green_bits) & mask_green; + pix_val |= (r << red_bits) & mask_red; + if (bmp_ptr->info_header.biBitCount == 16) { + _SetWord_LSBFirst(&dst_buf[dst_pos], (FX_WORD)pix_val); + dst_pos += 2; + } else { + _SetDWord_LSBFirst(&dst_buf[dst_pos], pix_val); + dst_pos += 4; + } + } + } + dst_size = dst_pos; +} +#endif +static void _bmp_encode_rgb(bmp_compress_struct_p bmp_ptr, + uint8_t*& dst_buf, + FX_DWORD& dst_size) { + if (bmp_ptr->info_header.biBitCount == 16) { +#ifdef BMP_SUPPORT_BITFIELD + _bmp_encode_bitfields(bmp_ptr, dst_buf, dst_size); +#endif + return; + } + FX_DWORD size, dst_pos; + FX_DWORD dst_pitch = + (bmp_ptr->src_width * bmp_ptr->info_header.biBitCount + 31) / 32 * 4; + size = dst_pitch * bmp_ptr->src_row; + dst_pos = bmp_ptr->file_header.bfOffBits; + dst_size += size; + dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); + if (dst_buf == NULL) { + return; + } + FXSYS_memset(&dst_buf[dst_pos], 0, size); + for (int32_t row_num = bmp_ptr->src_row - 1; row_num > -1; row_num--) { + FXSYS_memcpy(&dst_buf[dst_pos], + &bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch], + bmp_ptr->src_pitch); + dst_pos += dst_pitch; + } + dst_size = dst_pos; +} +static uint8_t _bmp_rle8_search(const uint8_t* buf, int32_t len) { + uint8_t num; + num = 1; + while (num < len) { + if (buf[num - 1] != buf[num] || num == 0xFF) { + break; + } + num++; + } + return num; +} +static void _bmp_encode_rle8(bmp_compress_struct_p bmp_ptr, + uint8_t*& dst_buf, + FX_DWORD& dst_size) { + FX_DWORD size, dst_pos, index; + uint8_t rle[2] = {0}; + size = bmp_ptr->src_pitch * bmp_ptr->src_row * 2; + dst_pos = bmp_ptr->file_header.bfOffBits; + dst_size += size; + dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); + if (dst_buf == NULL) { + return; + } + FXSYS_memset(&dst_buf[dst_pos], 0, size); + for (int32_t row_num = bmp_ptr->src_row - 1, i = 0; row_num > -1;) { + index = row_num * bmp_ptr->src_pitch; + rle[0] = _bmp_rle8_search(&bmp_ptr->src_buf[index + i], size - index - i); + rle[1] = bmp_ptr->src_buf[index + i]; + if (i + rle[0] >= (int32_t)bmp_ptr->src_pitch) { + rle[0] = uint8_t(bmp_ptr->src_pitch - i); + if (rle[0]) { + dst_buf[dst_pos++] = rle[0]; + dst_buf[dst_pos++] = rle[1]; + } + dst_buf[dst_pos++] = RLE_MARKER; + dst_buf[dst_pos++] = RLE_EOL; + i = 0; + row_num--; + } else { + i += rle[0]; + dst_buf[dst_pos++] = rle[0]; + dst_buf[dst_pos++] = rle[1]; + } + } + dst_buf[dst_pos++] = RLE_MARKER; + dst_buf[dst_pos++] = RLE_EOI; + dst_size = dst_pos; +} +static uint8_t _bmp_rle4_search(const uint8_t* buf, int32_t len) { + uint8_t num; + num = 2; + while (num < len) { + if (buf[num - 2] != buf[num] || num == 0xFF) { + break; + } + num++; + } + return num; +} +static void _bmp_encode_rle4(bmp_compress_struct_p bmp_ptr, + uint8_t*& dst_buf, + FX_DWORD& dst_size) { + FX_DWORD size, dst_pos, index; + uint8_t rle[2] = {0}; + size = bmp_ptr->src_pitch * bmp_ptr->src_row; + dst_pos = bmp_ptr->file_header.bfOffBits; + dst_size += size; + dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); + if (dst_buf == NULL) { + return; + } + FXSYS_memset(&dst_buf[dst_pos], 0, size); + for (int32_t row_num = bmp_ptr->src_row - 1, i = 0; row_num > -1; + rle[1] = 0) { + index = row_num * bmp_ptr->src_pitch; + rle[0] = _bmp_rle4_search(&bmp_ptr->src_buf[index + i], size - index - i); + rle[1] |= (bmp_ptr->src_buf[index + i] & 0x0f) << 4; + rle[1] |= bmp_ptr->src_buf[index + i + 1] & 0x0f; + if (i + rle[0] >= (int32_t)bmp_ptr->src_pitch) { + rle[0] = uint8_t(bmp_ptr->src_pitch - i); + if (rle[0]) { + dst_buf[dst_pos++] = rle[0]; + dst_buf[dst_pos++] = rle[1]; + } + dst_buf[dst_pos++] = RLE_MARKER; + dst_buf[dst_pos++] = RLE_EOL; + i = 0; + row_num--; + } else { + i += rle[0]; + dst_buf[dst_pos++] = rle[0]; + dst_buf[dst_pos++] = rle[1]; + } + } + dst_buf[dst_pos++] = RLE_MARKER; + dst_buf[dst_pos++] = RLE_EOI; + dst_size = dst_pos; +} +FX_BOOL _bmp_encode_image(bmp_compress_struct_p bmp_ptr, + uint8_t*& dst_buf, + FX_DWORD& dst_size) { + FX_DWORD head_size = sizeof(BmpFileHeader) + sizeof(BmpInfoHeader); + FX_DWORD pal_size = sizeof(FX_DWORD) * bmp_ptr->pal_num; + if (bmp_ptr->info_header.biClrUsed > 0 && + bmp_ptr->info_header.biClrUsed < bmp_ptr->pal_num) { + pal_size = sizeof(FX_DWORD) * bmp_ptr->info_header.biClrUsed; + } + dst_size = head_size + sizeof(FX_DWORD) * bmp_ptr->pal_num; + dst_buf = FX_TryAlloc(uint8_t, dst_size); + if (dst_buf == NULL) { + return FALSE; + } + FXSYS_memset(dst_buf, 0, dst_size); + bmp_ptr->file_header.bfOffBits = head_size; + if (bmp_ptr->pal_ptr && pal_size) { + FXSYS_memcpy(&dst_buf[head_size], bmp_ptr->pal_ptr, pal_size); + bmp_ptr->file_header.bfOffBits += pal_size; + } + WriteInfoHeader(&bmp_ptr->info_header, dst_buf); + switch (bmp_ptr->info_header.biCompression) { + case BMP_RGB: + _bmp_encode_rgb(bmp_ptr, dst_buf, dst_size); + break; + case BMP_BITFIELDS: +#ifdef BMP_SUPPORT_BITFIELD + _bmp_encode_bitfields(bmp_ptr, dst_buf, dst_size); +#endif + break; + case BMP_RLE8: + _bmp_encode_rle8(bmp_ptr, dst_buf, dst_size); + break; + case BMP_RLE4: + _bmp_encode_rle4(bmp_ptr, dst_buf, dst_size); + break; + default:; + } + bmp_ptr->file_header.bfSize = dst_size; + WriteFileHeader(&bmp_ptr->file_header, dst_buf); + return TRUE; +} diff --git a/core/src/fxcodec/lbmp/fx_bmp.h b/core/src/fxcodec/lbmp/fx_bmp.h index d1232f1f11..06bfe1e99d 100644 --- a/core/src/fxcodec/lbmp/fx_bmp.h +++ b/core/src/fxcodec/lbmp/fx_bmp.h @@ -1,155 +1,155 @@ -// 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/include/fxcrt/fx_basic.h" - -#define BMP_SUPPORT_BITFIELD -#define BMP_WIDTHBYTES(width, bitCount) ((width * bitCount) + 31) / 32 * 4 -#define BMP_PAL_ENCODE(a, r, g, b) \ - (((FX_DWORD)(a) << 24) | ((r) << 16) | ((g) << 8) | (b)) -#define BMP_D_STATUS_HEADER 0x01 -#define BMP_D_STATUS_PAL 0x02 -#define BMP_D_STATUS_DATA_PRE 0x03 -#define BMP_D_STATUS_DATA 0x04 -#define BMP_D_STATUS_TAIL 0x00 -#define BMP_SIGNATURE 0x4D42 -#define BMP_PAL_NEW 0 -#define BMP_PAL_OLD 1 -#define RLE_MARKER 0 -#define RLE_EOL 0 -#define RLE_EOI 1 -#define RLE_DELTA 2 -#define BMP_RGB 0L -#define BMP_RLE8 1L -#define BMP_RLE4 2L -#define BMP_BITFIELDS 3L -#define BMP_BIT_555 0 -#define BMP_BIT_565 1 -#define BMP_MAX_ERROR_SIZE 256 -#pragma pack(1) -typedef struct tagBmpFileHeader { - FX_WORD bfType; - FX_DWORD bfSize; - FX_WORD bfReserved1; - FX_WORD bfReserved2; - FX_DWORD bfOffBits; -} BmpFileHeader, *BmpFileHeaderPtr; -typedef struct tagBmpCoreHeader { - FX_DWORD bcSize; - FX_WORD bcWidth; - FX_WORD bcHeight; - FX_WORD bcPlanes; - FX_WORD bcBitCount; -} BmpCoreHeader, *BmpCoreHeaderPtr; -typedef struct tagBmpInfoHeader { - FX_DWORD biSize; - int32_t biWidth; - int32_t biHeight; - FX_WORD biPlanes; - FX_WORD biBitCount; - FX_DWORD biCompression; - FX_DWORD biSizeImage; - int32_t biXPelsPerMeter; - int32_t biYPelsPerMeter; - FX_DWORD biClrUsed; - FX_DWORD biClrImportant; -} BmpInfoHeader, *BmpInfoHeaderPtr; -#pragma pack() -typedef struct tag_bmp_decompress_struct bmp_decompress_struct; -typedef bmp_decompress_struct* bmp_decompress_struct_p; -typedef bmp_decompress_struct_p* bmp_decompress_struct_pp; -struct tag_bmp_decompress_struct { - jmp_buf jmpbuf; - FX_CHAR* err_ptr; - void (*_bmp_error_fn)(bmp_decompress_struct_p gif_ptr, - const FX_CHAR* err_msg); - - void* context_ptr; - - BmpFileHeaderPtr bmp_header_ptr; - BmpInfoHeaderPtr bmp_infoheader_ptr; - int32_t width; - int32_t height; - FX_DWORD compress_flag; - int32_t components; - int32_t src_row_bytes; - int32_t out_row_bytes; - uint8_t* out_row_buffer; - FX_WORD bitCounts; - FX_DWORD color_used; - FX_BOOL imgTB_flag; - int32_t pal_num; - int32_t pal_type; - FX_DWORD* pal_ptr; - FX_DWORD data_size; - FX_DWORD img_data_offset; - FX_DWORD img_ifh_size; - int32_t row_num; - int32_t col_num; - int32_t dpi_x; - int32_t dpi_y; -#ifdef BMP_SUPPORT_BITFIELD - FX_DWORD mask_red; - FX_DWORD mask_green; - FX_DWORD mask_blue; -#endif - - FX_BOOL (*_bmp_get_data_position_fn)(bmp_decompress_struct_p bmp_ptr, FX_DWORD cur_pos); - void (*_bmp_get_row_fn)(bmp_decompress_struct_p bmp_ptr, - int32_t row_num, - uint8_t* row_buf); - uint8_t* next_in; - FX_DWORD avail_in; - FX_DWORD skip_size; - int32_t decode_status; -}; -void _bmp_error(bmp_decompress_struct_p bmp_ptr, const FX_CHAR* err_msg); -bmp_decompress_struct_p _bmp_create_decompress(); -void _bmp_destroy_decompress(bmp_decompress_struct_pp bmp_ptr_ptr); -int32_t _bmp_read_header(bmp_decompress_struct_p bmp_ptr); -int32_t _bmp_decode_image(bmp_decompress_struct_p bmp_ptr); -int32_t _bmp_decode_rgb(bmp_decompress_struct_p bmp_ptr); -int32_t _bmp_decode_rle8(bmp_decompress_struct_p bmp_ptr); -int32_t _bmp_decode_rle4(bmp_decompress_struct_p bmp_ptr); -uint8_t* _bmp_read_data(bmp_decompress_struct_p bmp_ptr, - uint8_t** des_buf_pp, - FX_DWORD data_size); -void _bmp_save_decoding_status(bmp_decompress_struct_p bmp_ptr, int32_t status); -void _bmp_input_buffer(bmp_decompress_struct_p bmp_ptr, - uint8_t* src_buf, - FX_DWORD src_size); -FX_DWORD _bmp_get_avail_input(bmp_decompress_struct_p bmp_ptr, - uint8_t** avial_buf_ptr); -#define BMP_PTR_NOT_NULL(ptr, bmp_ptr) \ - if (ptr == NULL) { \ - _bmp_error(bmp_ptr, "Out Of Memory"); \ - return 0; \ - } -typedef struct tag_bmp_compress_struct bmp_compress_struct; -typedef bmp_compress_struct* bmp_compress_struct_p; -typedef bmp_compress_struct_p* bmp_compress_struct_pp; -struct tag_bmp_compress_struct { - BmpFileHeader file_header; - BmpInfoHeader info_header; - uint8_t* src_buf; - FX_DWORD src_pitch; - FX_DWORD src_row; - uint8_t src_bpp; - FX_DWORD src_width; - FX_BOOL src_free; - FX_DWORD* pal_ptr; - FX_WORD pal_num; -#ifdef BMP_SUPPORT_BITFIELD - uint8_t bit_type; -#endif -}; -bmp_compress_struct_p _bmp_create_compress(); -void _bmp_destroy_compress(bmp_compress_struct_p bmp_ptr); -FX_BOOL _bmp_encode_image(bmp_compress_struct_p bmp_ptr, - uint8_t*& dst_buf, - FX_DWORD& dst_size); +// 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/include/fxcrt/fx_basic.h" + +#define BMP_SUPPORT_BITFIELD +#define BMP_WIDTHBYTES(width, bitCount) ((width * bitCount) + 31) / 32 * 4 +#define BMP_PAL_ENCODE(a, r, g, b) \ + (((FX_DWORD)(a) << 24) | ((r) << 16) | ((g) << 8) | (b)) +#define BMP_D_STATUS_HEADER 0x01 +#define BMP_D_STATUS_PAL 0x02 +#define BMP_D_STATUS_DATA_PRE 0x03 +#define BMP_D_STATUS_DATA 0x04 +#define BMP_D_STATUS_TAIL 0x00 +#define BMP_SIGNATURE 0x4D42 +#define BMP_PAL_NEW 0 +#define BMP_PAL_OLD 1 +#define RLE_MARKER 0 +#define RLE_EOL 0 +#define RLE_EOI 1 +#define RLE_DELTA 2 +#define BMP_RGB 0L +#define BMP_RLE8 1L +#define BMP_RLE4 2L +#define BMP_BITFIELDS 3L +#define BMP_BIT_555 0 +#define BMP_BIT_565 1 +#define BMP_MAX_ERROR_SIZE 256 +#pragma pack(1) +typedef struct tagBmpFileHeader { + FX_WORD bfType; + FX_DWORD bfSize; + FX_WORD bfReserved1; + FX_WORD bfReserved2; + FX_DWORD bfOffBits; +} BmpFileHeader, *BmpFileHeaderPtr; +typedef struct tagBmpCoreHeader { + FX_DWORD bcSize; + FX_WORD bcWidth; + FX_WORD bcHeight; + FX_WORD bcPlanes; + FX_WORD bcBitCount; +} BmpCoreHeader, *BmpCoreHeaderPtr; +typedef struct tagBmpInfoHeader { + FX_DWORD biSize; + int32_t biWidth; + int32_t biHeight; + FX_WORD biPlanes; + FX_WORD biBitCount; + FX_DWORD biCompression; + FX_DWORD biSizeImage; + int32_t biXPelsPerMeter; + int32_t biYPelsPerMeter; + FX_DWORD biClrUsed; + FX_DWORD biClrImportant; +} BmpInfoHeader, *BmpInfoHeaderPtr; +#pragma pack() +typedef struct tag_bmp_decompress_struct bmp_decompress_struct; +typedef bmp_decompress_struct* bmp_decompress_struct_p; +typedef bmp_decompress_struct_p* bmp_decompress_struct_pp; +struct tag_bmp_decompress_struct { + jmp_buf jmpbuf; + FX_CHAR* err_ptr; + void (*_bmp_error_fn)(bmp_decompress_struct_p gif_ptr, + const FX_CHAR* err_msg); + + void* context_ptr; + + BmpFileHeaderPtr bmp_header_ptr; + BmpInfoHeaderPtr bmp_infoheader_ptr; + int32_t width; + int32_t height; + FX_DWORD compress_flag; + int32_t components; + int32_t src_row_bytes; + int32_t out_row_bytes; + uint8_t* out_row_buffer; + FX_WORD bitCounts; + FX_DWORD color_used; + FX_BOOL imgTB_flag; + int32_t pal_num; + int32_t pal_type; + FX_DWORD* pal_ptr; + FX_DWORD data_size; + FX_DWORD img_data_offset; + FX_DWORD img_ifh_size; + int32_t row_num; + int32_t col_num; + int32_t dpi_x; + int32_t dpi_y; +#ifdef BMP_SUPPORT_BITFIELD + FX_DWORD mask_red; + FX_DWORD mask_green; + FX_DWORD mask_blue; +#endif + + FX_BOOL (*_bmp_get_data_position_fn)(bmp_decompress_struct_p bmp_ptr, FX_DWORD cur_pos); + void (*_bmp_get_row_fn)(bmp_decompress_struct_p bmp_ptr, + int32_t row_num, + uint8_t* row_buf); + uint8_t* next_in; + FX_DWORD avail_in; + FX_DWORD skip_size; + int32_t decode_status; +}; +void _bmp_error(bmp_decompress_struct_p bmp_ptr, const FX_CHAR* err_msg); +bmp_decompress_struct_p _bmp_create_decompress(); +void _bmp_destroy_decompress(bmp_decompress_struct_pp bmp_ptr_ptr); +int32_t _bmp_read_header(bmp_decompress_struct_p bmp_ptr); +int32_t _bmp_decode_image(bmp_decompress_struct_p bmp_ptr); +int32_t _bmp_decode_rgb(bmp_decompress_struct_p bmp_ptr); +int32_t _bmp_decode_rle8(bmp_decompress_struct_p bmp_ptr); +int32_t _bmp_decode_rle4(bmp_decompress_struct_p bmp_ptr); +uint8_t* _bmp_read_data(bmp_decompress_struct_p bmp_ptr, + uint8_t** des_buf_pp, + FX_DWORD data_size); +void _bmp_save_decoding_status(bmp_decompress_struct_p bmp_ptr, int32_t status); +void _bmp_input_buffer(bmp_decompress_struct_p bmp_ptr, + uint8_t* src_buf, + FX_DWORD src_size); +FX_DWORD _bmp_get_avail_input(bmp_decompress_struct_p bmp_ptr, + uint8_t** avial_buf_ptr); +#define BMP_PTR_NOT_NULL(ptr, bmp_ptr) \ + if (ptr == NULL) { \ + _bmp_error(bmp_ptr, "Out Of Memory"); \ + return 0; \ + } +typedef struct tag_bmp_compress_struct bmp_compress_struct; +typedef bmp_compress_struct* bmp_compress_struct_p; +typedef bmp_compress_struct_p* bmp_compress_struct_pp; +struct tag_bmp_compress_struct { + BmpFileHeader file_header; + BmpInfoHeader info_header; + uint8_t* src_buf; + FX_DWORD src_pitch; + FX_DWORD src_row; + uint8_t src_bpp; + FX_DWORD src_width; + FX_BOOL src_free; + FX_DWORD* pal_ptr; + FX_WORD pal_num; +#ifdef BMP_SUPPORT_BITFIELD + uint8_t bit_type; +#endif +}; +bmp_compress_struct_p _bmp_create_compress(); +void _bmp_destroy_compress(bmp_compress_struct_p bmp_ptr); +FX_BOOL _bmp_encode_image(bmp_compress_struct_p bmp_ptr, + uint8_t*& dst_buf, + FX_DWORD& dst_size); diff --git a/core/src/fxcodec/lgif/fx_gif.cpp b/core/src/fxcodec/lgif/fx_gif.cpp index b07ebb3bc9..c00b7a74b2 100644 --- a/core/src/fxcodec/lgif/fx_gif.cpp +++ b/core/src/fxcodec/lgif/fx_gif.cpp @@ -1,1426 +1,1426 @@ -// 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 "fx_gif.h" -void CGifLZWDecoder::Input(uint8_t* src_buf, FX_DWORD src_size) { - next_in = src_buf; - avail_in = src_size; -} -FX_DWORD CGifLZWDecoder::GetAvailInput() { - return avail_in; -} -void CGifLZWDecoder::InitTable(uint8_t code_len) { - code_size = code_len; - code_clear = 1 << code_size; - code_end = code_clear + 1; - bits_left = 0; - code_store = 0; - next_in = NULL; - avail_in = 0; - stack_size = 0; - code_first = 0; - ClearTable(); -} -void CGifLZWDecoder::ClearTable() { - code_size_cur = code_size + 1; - code_next = code_end + 1; - code_old = (FX_WORD)-1; - FXSYS_memset(code_table, 0, sizeof(tag_Table) * GIF_MAX_LZW_CODE); - FXSYS_memset(stack, 0, GIF_MAX_LZW_CODE); - for (FX_WORD i = 0; i < code_clear; i++) { - code_table[i].suffix = (uint8_t)i; - } -} -void CGifLZWDecoder::DecodeString(FX_WORD code) { - stack_size = 0; - while (TRUE) { - ASSERT(code <= code_next); - if (code < code_clear || code > code_next) { - break; - } - stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = code_table[code].suffix; - code = code_table[code].prefix; - } - stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = (uint8_t)code; - code_first = (uint8_t)code; -} -void CGifLZWDecoder::AddCode(FX_WORD prefix_code, uint8_t append_char) { - if (code_next == GIF_MAX_LZW_CODE) { - return; - } - code_table[code_next].prefix = prefix_code; - code_table[code_next].suffix = append_char; - if (++code_next < GIF_MAX_LZW_CODE) { - if (code_next >> code_size_cur) { - code_size_cur++; - } - } -} -int32_t CGifLZWDecoder::Decode(uint8_t* des_buf, FX_DWORD& des_size) { - if (des_size == 0) { - return 3; - } - FX_DWORD i = 0; - if (stack_size != 0) { - if (des_size < stack_size) { - FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], des_size); - stack_size -= (FX_WORD)des_size; - return 3; - } - FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], stack_size); - des_buf += stack_size; - i += stack_size; - stack_size = 0; - } - FX_WORD code = 0; - while (i <= des_size && (avail_in > 0 || bits_left >= code_size_cur)) { - if (code_size_cur > 12) { - if (err_msg_ptr) { - FXSYS_strncpy(err_msg_ptr, "Code Length Out Of Range", - GIF_MAX_ERROR_SIZE - 1); - } - return 0; - } - if (avail_in > 0) { - code_store |= (*next_in++) << bits_left; - avail_in--; - bits_left += 8; - } - while (bits_left >= code_size_cur) { - code = (FX_WORD)code_store & ((1 << code_size_cur) - 1); - code_store >>= code_size_cur; - bits_left -= code_size_cur; - if (code == code_clear) { - ClearTable(); - continue; - } else if (code == code_end) { - des_size = i; - return 1; - } else { - if (code_old != (FX_WORD)-1) { - if (code_next < GIF_MAX_LZW_CODE) { - if (code == code_next) { - AddCode(code_old, code_first); - DecodeString(code); - } else if (code > code_next) { - if (err_msg_ptr) { - FXSYS_strncpy(err_msg_ptr, "Decode Error, Out Of Range", - GIF_MAX_ERROR_SIZE - 1); - } - return 0; - } else { - DecodeString(code); - uint8_t append_char = stack[GIF_MAX_LZW_CODE - stack_size]; - AddCode(code_old, append_char); - } - } - } else { - DecodeString(code); - } - code_old = code; - if (i + stack_size > des_size) { - FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], - des_size - i); - stack_size -= (FX_WORD)(des_size - i); - return 3; - } - FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], - stack_size); - des_buf += stack_size; - i += stack_size; - stack_size = 0; - } - } - } - if (avail_in == 0) { - des_size = i; - return 2; - } - return 0; -} -static FX_BOOL _gif_grow_buf(uint8_t*& dst_buf, - FX_DWORD& dst_len, - FX_DWORD size) { - if (dst_len < size) { - FX_DWORD len_org = dst_len; - while (dst_buf && dst_len < size) { - dst_len <<= 1; - dst_buf = FX_Realloc(uint8_t, dst_buf, dst_len); - } - if (dst_buf == NULL) { - dst_len = size; - dst_buf = FX_Realloc(uint8_t, dst_buf, dst_len); - if (dst_buf == NULL) { - return FALSE; - } - } - FXSYS_memset(dst_buf + len_org, 0, dst_len - len_org); - return dst_buf != NULL; - } - return TRUE; -} -static inline void _gif_cut_index(uint8_t& val, - FX_DWORD index, - uint8_t index_bit, - uint8_t index_bit_use, - uint8_t bit_use) { - FX_DWORD cut = ((1 << (index_bit - index_bit_use)) - 1) << index_bit_use; - val |= ((index & cut) >> index_bit_use) << bit_use; -} -static inline uint8_t _gif_cut_buf(const uint8_t* buf, - FX_DWORD& offset, - uint8_t bit_cut, - uint8_t& bit_offset, - FX_DWORD& bit_num) { - if (bit_cut != 8) { - FX_WORD index = 0; - index |= ((1 << bit_cut) - 1) << (7 - bit_offset); - uint8_t ret = ((index & buf[offset]) >> (7 - bit_offset)); - bit_offset += bit_cut; - if (bit_offset >= 8) { - if (bit_offset > 8) { - ret |= ((index & (buf[offset + 1] << 8)) >> 8); - } - bit_offset -= 8; - offset++; - } - bit_num += bit_cut; - return ret; - } - bit_num += bit_cut; - return buf[offset++]; -} -CGifLZWEncoder::CGifLZWEncoder() { - FXSYS_memset(this, 0, sizeof(CGifLZWEncoder)); -} -CGifLZWEncoder::~CGifLZWEncoder() {} -void CGifLZWEncoder::ClearTable() { - index_bit_cur = code_size + 1; - index_num = code_end + 1; - table_cur = code_end + 1; - for (FX_WORD i = 0; i < GIF_MAX_LZW_CODE; i++) { - code_table[i].prefix = 0; - code_table[i].suffix = 0; - } -} -void CGifLZWEncoder::Start(uint8_t code_len, - const uint8_t* src_buf, - uint8_t*& dst_buf, - FX_DWORD& offset) { - code_size = code_len + 1; - src_bit_cut = code_size; - if (code_len == 0) { - src_bit_cut = 1; - code_size = 2; - } - code_clear = 1 << code_size; - code_end = code_clear + 1; - dst_buf[offset++] = code_size; - bit_offset = 0; - ClearTable(); - src_offset = 0; - src_bit_offset = 0; - src_bit_num = 0; - code_table[index_num].prefix = _gif_cut_buf(src_buf, src_offset, src_bit_cut, - src_bit_offset, src_bit_num); - code_table[index_num].suffix = _gif_cut_buf(src_buf, src_offset, src_bit_cut, - src_bit_offset, src_bit_num); -} -void CGifLZWEncoder::WriteBlock(uint8_t*& dst_buf, - FX_DWORD& dst_len, - FX_DWORD& offset) { - if (!_gif_grow_buf(dst_buf, dst_len, offset + GIF_DATA_BLOCK + 1)) { - longjmp(jmp, 1); - } - dst_buf[offset++] = index_buf_len; - FXSYS_memcpy(&dst_buf[offset], index_buf, index_buf_len); - offset += index_buf_len; - FXSYS_memset(index_buf, 0, GIF_DATA_BLOCK); - index_buf_len = 0; -} -void CGifLZWEncoder::EncodeString(FX_DWORD index, - uint8_t*& dst_buf, - FX_DWORD& dst_len, - FX_DWORD& offset) { - uint8_t index_bit_use; - index_bit_use = 0; - if (index_buf_len == GIF_DATA_BLOCK) { - WriteBlock(dst_buf, dst_len, offset); - } - _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, index_bit_use, - bit_offset); - if (index_bit_cur <= (8 - bit_offset)) { - bit_offset += index_bit_cur; - } else if (index_bit_cur <= (16 - bit_offset)) { - index_bit_use += (8 - bit_offset); - bit_offset = 0; - index_buf_len++; - if (index_buf_len == GIF_DATA_BLOCK) { - WriteBlock(dst_buf, dst_len, offset); - } - _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, - index_bit_use, bit_offset); - bit_offset = index_bit_cur - index_bit_use; - } else { - index_bit_use += (8 - bit_offset); - bit_offset = 0; - index_buf_len++; - if (index_buf_len == GIF_DATA_BLOCK) { - WriteBlock(dst_buf, dst_len, offset); - } - _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, - index_bit_use, bit_offset); - index_bit_use += 8; - bit_offset = 0; - index_buf_len++; - if (index_buf_len == GIF_DATA_BLOCK) { - WriteBlock(dst_buf, dst_len, offset); - } - _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, - index_bit_use, bit_offset); - bit_offset = index_bit_cur - index_bit_use; - } - if (bit_offset == 8) { - bit_offset = 0; - index_buf_len++; - if (index_buf_len == GIF_DATA_BLOCK) { - WriteBlock(dst_buf, dst_len, offset); - } - } - if (index == code_end) { - index_buf_len++; - WriteBlock(dst_buf, dst_len, offset); - } - if (index_num++ >> index_bit_cur) { - index_bit_cur++; - } -} -FX_BOOL CGifLZWEncoder::Encode(const uint8_t* src_buf, - FX_DWORD src_len, - uint8_t*& dst_buf, - FX_DWORD& dst_len, - FX_DWORD& offset) { - uint8_t suffix; - if (setjmp(jmp)) { - return FALSE; - } - while (src_bit_num < src_len) { - if (!LookUpInTable(src_buf, src_offset, src_bit_offset)) { - EncodeString(code_table[index_num].prefix, dst_buf, dst_len, offset); - if (index_num == GIF_MAX_LZW_CODE) { - suffix = code_table[index_num - 1].suffix; - EncodeString(code_clear, dst_buf, dst_len, offset); - ClearTable(); - code_table[index_num].prefix = suffix; - code_table[index_num].suffix = _gif_cut_buf( - src_buf, src_offset, src_bit_cut, src_bit_offset, src_bit_num); - } else { - code_table[index_num].prefix = code_table[index_num - 1].suffix; - code_table[index_num].suffix = _gif_cut_buf( - src_buf, src_offset, src_bit_cut, src_bit_offset, src_bit_num); - } - } - } - src_offset = 0; - src_bit_offset = 0; - src_bit_num = 0; - return TRUE; -} -FX_BOOL CGifLZWEncoder::LookUpInTable(const uint8_t* buf, - FX_DWORD& offset, - uint8_t& bit_offset) { - for (FX_WORD i = table_cur; i < index_num; i++) { - if (code_table[i].prefix == code_table[index_num].prefix && - code_table[i].suffix == code_table[index_num].suffix) { - code_table[index_num].prefix = i; - code_table[index_num].suffix = - _gif_cut_buf(buf, offset, src_bit_cut, bit_offset, src_bit_num); - table_cur = i; - return TRUE; - } - } - table_cur = code_end + 1; - return FALSE; -} -void CGifLZWEncoder::Finish(uint8_t*& dst_buf, - FX_DWORD& dst_len, - FX_DWORD& offset) { - EncodeString(code_table[index_num].prefix, dst_buf, dst_len, offset); - EncodeString(code_end, dst_buf, dst_len, offset); - bit_offset = 0; - ClearTable(); -} -gif_decompress_struct_p _gif_create_decompress() { - gif_decompress_struct_p gif_ptr = - (gif_decompress_struct*)FX_Alloc(uint8_t, sizeof(gif_decompress_struct)); - if (gif_ptr == NULL) { - return NULL; - } - FXSYS_memset(gif_ptr, 0, sizeof(gif_decompress_struct)); - gif_ptr->decode_status = GIF_D_STATUS_SIG; - gif_ptr->img_ptr_arr_ptr = new CFX_ArrayTemplate; -#ifdef GIF_SUPPORT_COMMENT_EXTENSION - gif_ptr->cmt_data_ptr = new CFX_ByteString; -#endif -#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - gif_ptr->pt_ptr_arr_ptr = new CFX_ArrayTemplate; -#endif - return gif_ptr; -} -void _gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr) { - if (gif_ptr_ptr == NULL || *gif_ptr_ptr == NULL) { - return; - } - gif_decompress_struct_p gif_ptr = *gif_ptr_ptr; - *gif_ptr_ptr = NULL; - if (gif_ptr->global_pal_ptr != NULL) { - FX_Free(gif_ptr->global_pal_ptr); - } - if (gif_ptr->img_decoder_ptr != NULL) { - delete gif_ptr->img_decoder_ptr; - } - if (gif_ptr->img_ptr_arr_ptr != NULL) { - int32_t size_img_arr = gif_ptr->img_ptr_arr_ptr->GetSize(); - for (int32_t i = 0; i < size_img_arr; i++) { - GifImage* p = gif_ptr->img_ptr_arr_ptr->GetAt(i); - if (p->image_info_ptr != NULL) { - FX_Free(p->image_info_ptr); - } - if (p->image_gce_ptr != NULL) { - FX_Free(p->image_gce_ptr); - } - if (p->image_row_buf != NULL) { - FX_Free(p->image_row_buf); - } - if (p->local_pal_ptr != NULL && - p->local_pal_ptr != gif_ptr->global_pal_ptr) { - FX_Free(p->local_pal_ptr); - } - FX_Free(p); - } - gif_ptr->img_ptr_arr_ptr->RemoveAll(); - delete gif_ptr->img_ptr_arr_ptr; - } -#ifdef GIF_SUPPORT_APPLICATION_EXTENSION - if (gif_ptr->app_data != NULL) { - FX_Free(gif_ptr->app_data); - } -#endif -#ifdef GIF_SUPPORT_COMMENT_EXTENSION - if (gif_ptr->cmt_data_ptr != NULL) { - delete gif_ptr->cmt_data_ptr; - } -#endif -#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION - if (gif_ptr->gce_ptr != NULL) { - FX_Free(gif_ptr->gce_ptr); - } -#endif -#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - if (gif_ptr->pt_ptr_arr_ptr != NULL) { - int32_t size_pt_arr = gif_ptr->pt_ptr_arr_ptr->GetSize(); - for (int32_t i = 0; i < size_pt_arr; i++) { - GifPlainText* p = gif_ptr->pt_ptr_arr_ptr->GetAt(i); - if (p->gce_ptr != NULL) { - FX_Free(p->gce_ptr); - } - if (p->pte_ptr != NULL) { - FX_Free(p->pte_ptr); - } - if (p->string_ptr != NULL) { - delete p->string_ptr; - } - } - gif_ptr->pt_ptr_arr_ptr->RemoveAll(); - delete gif_ptr->pt_ptr_arr_ptr; - } -#endif - FX_Free(gif_ptr); -} -gif_compress_struct_p _gif_create_compress() { - gif_compress_struct_p gif_ptr = - (gif_compress_struct*)FX_Alloc(uint8_t, sizeof(gif_compress_struct)); - if (gif_ptr == NULL) { - return NULL; - } - FXSYS_memset(gif_ptr, 0, sizeof(gif_compress_struct)); - gif_ptr->img_encoder_ptr = new CGifLZWEncoder; - gif_ptr->header_ptr = (GifHeader*)FX_Alloc(uint8_t, sizeof(GifHeader)); - if (gif_ptr->header_ptr == NULL) { - delete (gif_ptr->img_encoder_ptr); - FX_Free(gif_ptr); - return NULL; - } - FXSYS_memcpy(gif_ptr->header_ptr->signature, GIF_SIGNATURE, 3); - FXSYS_memcpy(gif_ptr->header_ptr->version, "89a", 3); - gif_ptr->lsd_ptr = (GifLSD*)FX_Alloc(uint8_t, sizeof(GifLSD)); - if (gif_ptr->lsd_ptr == NULL) { - FX_Free(gif_ptr->header_ptr); - delete (gif_ptr->img_encoder_ptr); - FX_Free(gif_ptr); - return NULL; - } - FXSYS_memset(gif_ptr->lsd_ptr, 0, sizeof(GifLSD)); - gif_ptr->image_info_ptr = - (GifImageInfo*)FX_Alloc(uint8_t, sizeof(GifImageInfo)); - if (gif_ptr->image_info_ptr == NULL) { - FX_Free(gif_ptr->lsd_ptr); - FX_Free(gif_ptr->header_ptr); - delete (gif_ptr->img_encoder_ptr); - FX_Free(gif_ptr); - return NULL; - } - FXSYS_memset(gif_ptr->image_info_ptr, 0, sizeof(GifImageInfo)); -#ifdef GIF_SUPPORT_APPLICATION_EXTENSION - FXSYS_memcpy(gif_ptr->app_identify, "netscape", 8); - FXSYS_memcpy(gif_ptr->app_authentication, "2.0", 3); -#endif -#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION - gif_ptr->gce_ptr = (GifGCE*)FX_Alloc(uint8_t, sizeof(GifGCE)); - if (gif_ptr->gce_ptr == NULL) { - FX_Free(gif_ptr->image_info_ptr); - FX_Free(gif_ptr->lsd_ptr); - FX_Free(gif_ptr->header_ptr); - delete (gif_ptr->img_encoder_ptr); - FX_Free(gif_ptr); - return NULL; - } -#endif -#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - gif_ptr->pte_ptr = (GifPTE*)FX_Alloc(uint8_t, sizeof(GifPTE)); - if (gif_ptr->pte_ptr == NULL) { - FX_Free(gif_ptr->gce_ptr); - FX_Free(gif_ptr->image_info_ptr); - FX_Free(gif_ptr->lsd_ptr); - FX_Free(gif_ptr->header_ptr); - delete (gif_ptr->img_encoder_ptr); - FX_Free(gif_ptr); - return NULL; - } - FXSYS_memset(gif_ptr->pte_ptr, 0, sizeof(GifPTE)); - gif_ptr->pte_ptr->block_size = 12; -#endif - return gif_ptr; -} -void _gif_destroy_compress(gif_compress_struct_pp gif_ptr_ptr) { - if (gif_ptr_ptr == NULL || *gif_ptr_ptr == NULL) { - return; - } - gif_compress_struct_p gif_ptr = *gif_ptr_ptr; - *gif_ptr_ptr = NULL; - if (gif_ptr->header_ptr != NULL) { - FX_Free(gif_ptr->header_ptr); - } - if (gif_ptr->lsd_ptr != NULL) { - FX_Free(gif_ptr->lsd_ptr); - } - if (gif_ptr->global_pal != NULL) { - FX_Free(gif_ptr->global_pal); - } - if (gif_ptr->image_info_ptr != NULL) { - FX_Free(gif_ptr->image_info_ptr); - } - if (gif_ptr->local_pal != NULL) { - FX_Free(gif_ptr->local_pal); - } - if (gif_ptr->img_encoder_ptr != NULL) { - delete gif_ptr->img_encoder_ptr; - } -#ifdef GIF_SUPPORT_APPLICATION_EXTENSION - if (gif_ptr->app_data != NULL) { - FX_Free(gif_ptr->app_data); - } -#endif -#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION - if (gif_ptr->gce_ptr != NULL) { - FX_Free(gif_ptr->gce_ptr); - } -#endif -#ifdef GIF_SUPPORT_COMMENT_EXTENSION - if (gif_ptr->cmt_data_ptr != NULL) { - FX_Free(gif_ptr->cmt_data_ptr); - } -#endif -#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - if (gif_ptr->pte_ptr != NULL) { - FX_Free(gif_ptr->pte_ptr); - } -#endif - FX_Free(gif_ptr); -} -void _gif_error(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg) { - if (gif_ptr != NULL && gif_ptr->_gif_error_fn != NULL) { - gif_ptr->_gif_error_fn(gif_ptr, err_msg); - } -} -void _gif_warn(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg) {} -int32_t _gif_read_header(gif_decompress_struct_p gif_ptr) { - if (gif_ptr == NULL) { - return 0; - } - FX_DWORD skip_size_org = gif_ptr->skip_size; - ASSERT(sizeof(GifHeader) == 6); - GifHeader* gif_header_ptr = NULL; - if (_gif_read_data(gif_ptr, (uint8_t**)&gif_header_ptr, 6) == NULL) { - return 2; - } - if (FXSYS_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"); - return 0; - } - ASSERT(sizeof(GifLSD) == 7); - GifLSD* gif_lsd_ptr = NULL; - if (_gif_read_data(gif_ptr, (uint8_t**)&gif_lsd_ptr, 7) == NULL) { - gif_ptr->skip_size = skip_size_org; - return 2; - } - if (((GifGF*)&gif_lsd_ptr->global_flag)->global_pal) { - gif_ptr->global_pal_num = 2 - << ((GifGF*)&gif_lsd_ptr->global_flag)->pal_bits; - ASSERT(sizeof(GifPalette) == 3); - int32_t global_pal_size = gif_ptr->global_pal_num * 3; - uint8_t* global_pal_ptr = NULL; - if (_gif_read_data(gif_ptr, &global_pal_ptr, global_pal_size) == NULL) { - gif_ptr->skip_size = skip_size_org; - return 2; - } - 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; - if (gif_ptr->global_pal_ptr != NULL) { - FX_Free(gif_ptr->global_pal_ptr); - } - gif_ptr->global_pal_ptr = NULL; - gif_ptr->global_pal_ptr = (GifPalette*)FX_Alloc(uint8_t, global_pal_size); - GIF_PTR_NOT_NULL(gif_ptr->global_pal_ptr, gif_ptr); - FXSYS_memcpy(gif_ptr->global_pal_ptr, 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); - gif_ptr->bc_index = gif_lsd_ptr->bc_index; - gif_ptr->pixel_aspect = gif_lsd_ptr->pixel_aspect; - return 1; -} -int32_t _gif_get_frame(gif_decompress_struct_p gif_ptr) { - if (gif_ptr == NULL) { - return 0; - } - int32_t ret = 1; - while (TRUE) { - switch (gif_ptr->decode_status) { - case GIF_D_STATUS_TAIL: - return 1; - case GIF_D_STATUS_SIG: { - uint8_t* sig_ptr = NULL; - if (_gif_read_data(gif_ptr, &sig_ptr, 1) == NULL) { - return 2; - } - switch (*sig_ptr) { - case GIF_SIG_EXTENSION: - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT); - continue; - case GIF_SIG_IMAGE: - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_INFO); - continue; - case GIF_SIG_TRAILER: - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); - return 1; - default: - if (gif_ptr->avail_in) { - _gif_warn(gif_ptr, "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!"); - return 1; - } - } - case GIF_D_STATUS_EXT: { - uint8_t* ext_ptr = NULL; - if (_gif_read_data(gif_ptr, &ext_ptr, 1) == NULL) { - return 2; - } - switch (*ext_ptr) { -#ifdef GIF_SUPPORT_APPLICATION_EXTENSION - case GIF_BLOCK_AE: - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_AE); - continue; -#endif -#ifdef GIF_SUPPORT_COMMENT_EXTENSION - case GIF_BLOCK_CE: - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_CE); - continue; -#endif -#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION - case GIF_BLOCK_GCE: - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_GCE); - continue; -#endif -#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - case GIF_BLOCK_PTE: - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_PTE); - continue; -#endif - default: { - int32_t status = GIF_D_STATUS_EXT_UNE; -#ifndef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - if (*ext_ptr == GIF_BLOCK_PTE) { - status = GIF_D_STATUS_EXT_PTE; - } -#endif - _gif_save_decoding_status(gif_ptr, status); - continue; - } - } - } - case GIF_D_STATUS_IMG_INFO: { - ret = _gif_decode_image_info(gif_ptr); - if (ret != 1) { - return ret; - } - continue; - } - case GIF_D_STATUS_IMG_DATA: { - uint8_t* data_size_ptr = NULL; - uint8_t* data_ptr = NULL; - FX_DWORD skip_size_org = gif_ptr->skip_size; - if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - return 2; - } - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL) { - gif_ptr->skip_size = skip_size_org; - return 2; - } - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA); - skip_size_org = gif_ptr->skip_size; - if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - return 2; - } - } - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG); - continue; - } - default: { - ret = _gif_decode_extension(gif_ptr); - if (ret != 1) { - return ret; - } - continue; - } - } - } - return 1; -} -void _gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr, - GifGCE** gce_ptr_ptr) { - *gce_ptr_ptr = NULL; -#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION - if (gif_ptr->gce_ptr != NULL && gce_ptr_ptr != NULL) { - *gce_ptr_ptr = gif_ptr->gce_ptr; - gif_ptr->gce_ptr = NULL; - } -#endif -} -int32_t _gif_decode_extension(gif_decompress_struct_p gif_ptr) { - uint8_t* data_size_ptr = NULL; - uint8_t* data_ptr = NULL; - FX_DWORD skip_size_org = gif_ptr->skip_size; - switch (gif_ptr->decode_status) { -#ifdef GIF_SUPPORT_APPLICATION_EXTENSION - case GIF_D_STATUS_EXT_AE: { - ASSERT(sizeof(GifAE) == 12); - GifAE* gif_ae_ptr = NULL; - if (_gif_read_data(gif_ptr, (uint8_t**)&gif_ae_ptr, 12) == NULL) { - return 2; - } - CFX_ByteString gif_ae_data_str; - if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - gif_ptr->skip_size = skip_size_org; - return 2; - } - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - uint8_t data_size = *data_size_ptr; - if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL || - _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - gif_ptr->skip_size = skip_size_org; - return 2; - } - gif_ae_data_str += CFX_ByteString((const uint8_t*)data_ptr, data_size); - } - FXSYS_memcpy(gif_ptr->app_identify, gif_ae_ptr->app_identify, 8); - FXSYS_memcpy(gif_ptr->app_authentication, gif_ae_ptr->app_authentication, - 3); - gif_ptr->app_data_size = gif_ae_data_str.GetLength(); - if (gif_ptr->app_data != NULL) { - FX_Free(gif_ptr->app_data); - gif_ptr->app_data = NULL; - } - gif_ptr->app_data = FX_Alloc(uint8_t, gif_ptr->app_data_size); - GIF_PTR_NOT_NULL(gif_ptr->app_data, gif_ptr); - FXSYS_memcpy(gif_ptr->app_data, const uint8_t*(gif_ae_data_str), - gif_ptr->app_data_size); - } break; -#endif -#ifdef GIF_SUPPORT_COMMENT_EXTENSION - case GIF_D_STATUS_EXT_CE: { - if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - gif_ptr->skip_size = skip_size_org; - return 2; - } - gif_ptr->cmt_data_ptr->Empty(); - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - uint8_t data_size = *data_size_ptr; - if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL || - _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - gif_ptr->skip_size = skip_size_org; - return 2; - } - *(gif_ptr->cmt_data_ptr) += - CFX_ByteString((const FX_CHAR*)data_ptr, data_size); - } - } break; -#endif -#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - case GIF_D_STATUS_EXT_PTE: { - ASSERT(sizeof(GifPTE) == 13); - GifPTE* gif_pte_ptr = NULL; - if (_gif_read_data(gif_ptr, (uint8_t**)&gif_pte_ptr, 13) == NULL) { - return 2; - } - GifPlainText* gif_pt_ptr = FX_Alloc(GifPlainText, 1); - GIF_PTR_NOT_NULL(gif_pt_ptr, gif_ptr); - FXSYS_memset(gif_pt_ptr, 0, sizeof(GifPlainText)); - _gif_takeover_gce_ptr(gif_ptr, &gif_pt_ptr->gce_ptr); - gif_pt_ptr->pte_ptr = (GifPTE*)FX_Alloc(uint8_t, sizeof(GifPTE)); - GIF_PTR_NOT_NULL(gif_pt_ptr->pte_ptr, gif_ptr); - gif_pt_ptr->string_ptr = new CFX_ByteString; - GIF_PTR_NOT_NULL(gif_pt_ptr->string_ptr, gif_ptr); - gif_pt_ptr->pte_ptr->block_size = gif_pte_ptr->block_size; - gif_pt_ptr->pte_ptr->grid_left = - _GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_left); - gif_pt_ptr->pte_ptr->grid_top = - _GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_top); - gif_pt_ptr->pte_ptr->grid_width = - _GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_width); - gif_pt_ptr->pte_ptr->grid_height = - _GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_height); - gif_pt_ptr->pte_ptr->char_width = gif_pte_ptr->char_width; - gif_pt_ptr->pte_ptr->char_height = gif_pte_ptr->char_height; - gif_pt_ptr->pte_ptr->fc_index = gif_pte_ptr->fc_index; - gif_pt_ptr->pte_ptr->bc_index = gif_pte_ptr->bc_index; - if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - gif_ptr->skip_size = skip_size_org; - if (gif_pt_ptr != NULL) { - if (gif_pt_ptr->gce_ptr != NULL) { - FX_Free(gif_pt_ptr->gce_ptr); - } - if (gif_pt_ptr->pte_ptr != NULL) { - FX_Free(gif_pt_ptr->pte_ptr); - } - if (gif_pt_ptr->string_ptr != NULL) { - delete gif_pt_ptr->string_ptr; - } - FX_Free(gif_pt_ptr); - } - return 2; - } - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - uint8_t data_size = *data_size_ptr; - if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL || - _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - gif_ptr->skip_size = skip_size_org; - if (gif_pt_ptr != NULL) { - if (gif_pt_ptr->gce_ptr != NULL) { - FX_Free(gif_pt_ptr->gce_ptr); - } - if (gif_pt_ptr->pte_ptr != NULL) { - FX_Free(gif_pt_ptr->pte_ptr); - } - if (gif_pt_ptr->string_ptr != NULL) { - delete gif_pt_ptr->string_ptr; - } - FX_Free(gif_pt_ptr); - } - return 2; - } - *(gif_pt_ptr->string_ptr) += - CFX_ByteString((const FX_CHAR*)data_ptr, data_size); - } - gif_ptr->pt_ptr_arr_ptr->Add(gif_pt_ptr); - } break; -#endif -#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION - case GIF_D_STATUS_EXT_GCE: { - ASSERT(sizeof(GifGCE) == 5); - GifGCE* gif_gce_ptr = NULL; - if (_gif_read_data(gif_ptr, (uint8_t**)&gif_gce_ptr, 6) == NULL) { - return 2; - } - if (gif_ptr->gce_ptr == NULL) { - gif_ptr->gce_ptr = (GifGCE*)FX_Alloc(uint8_t, sizeof(GifGCE)); - GIF_PTR_NOT_NULL(gif_ptr->gce_ptr, gif_ptr); - } - gif_ptr->gce_ptr->block_size = gif_gce_ptr->block_size; - gif_ptr->gce_ptr->gce_flag = gif_gce_ptr->gce_flag; - gif_ptr->gce_ptr->delay_time = - _GetWord_LSBFirst((uint8_t*)&gif_gce_ptr->delay_time); - gif_ptr->gce_ptr->trans_index = gif_gce_ptr->trans_index; - } break; -#endif - default: { -#ifndef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - if (gif_ptr->decode_status == GIF_D_STATUS_EXT_PTE) { -#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION - if (gif_ptr->gce_ptr != NULL) { - FX_Free(gif_ptr->gce_ptr); - gif_ptr->gce_ptr = NULL; - } -#endif - } -#endif - if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - return 2; - } - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL || - _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - gif_ptr->skip_size = skip_size_org; - return 2; - } - } - } - } - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG); - return 1; -} -int32_t _gif_decode_image_info(gif_decompress_struct_p gif_ptr) { - if (gif_ptr->width == 0 || gif_ptr->height == 0) { - _gif_error(gif_ptr, "No Image Header Info"); - return 0; - } - FX_DWORD skip_size_org = gif_ptr->skip_size; - ASSERT(sizeof(GifImageInfo) == 9); - GifImageInfo* gif_img_info_ptr = NULL; - if (_gif_read_data(gif_ptr, (uint8_t**)&gif_img_info_ptr, 9) == NULL) { - return 2; - } - GifImage* gif_image_ptr = (GifImage*)FX_Alloc(uint8_t, sizeof(GifImage)); - GIF_PTR_NOT_NULL(gif_image_ptr, gif_ptr); - FXSYS_memset(gif_image_ptr, 0, sizeof(GifImage)); - gif_image_ptr->image_info_ptr = - (GifImageInfo*)FX_Alloc(uint8_t, sizeof(GifImageInfo)); - GIF_PTR_NOT_NULL(gif_image_ptr->image_info_ptr, gif_ptr); - gif_image_ptr->image_info_ptr->left = - _GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->left); - gif_image_ptr->image_info_ptr->top = - _GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->top); - gif_image_ptr->image_info_ptr->width = - _GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->width); - gif_image_ptr->image_info_ptr->height = - _GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->height); - gif_image_ptr->image_info_ptr->local_flag = gif_img_info_ptr->local_flag; - if (gif_image_ptr->image_info_ptr->left + - gif_image_ptr->image_info_ptr->width > - gif_ptr->width || - gif_image_ptr->image_info_ptr->top + - gif_image_ptr->image_info_ptr->height > - gif_ptr->height) { - if (gif_image_ptr->image_info_ptr != NULL) { - FX_Free(gif_image_ptr->image_info_ptr); - } - if (gif_image_ptr->image_row_buf != NULL) { - 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"); - return 0; - } - GifLF* gif_img_info_lf_ptr = (GifLF*)&gif_img_info_ptr->local_flag; - if (gif_img_info_lf_ptr->local_pal) { - ASSERT(sizeof(GifPalette) == 3); - int32_t loc_pal_size = (2 << gif_img_info_lf_ptr->pal_bits) * 3; - uint8_t* loc_pal_ptr = NULL; - if (_gif_read_data(gif_ptr, &loc_pal_ptr, loc_pal_size) == NULL) { - gif_ptr->skip_size = skip_size_org; - if (gif_image_ptr->image_info_ptr != NULL) { - FX_Free(gif_image_ptr->image_info_ptr); - } - if (gif_image_ptr->image_row_buf != NULL) { - FX_Free(gif_image_ptr->image_row_buf); - } - FX_Free(gif_image_ptr); - return 2; - } - gif_image_ptr->local_pal_ptr = - (GifPalette*)gif_ptr->_gif_ask_buf_for_pal_fn(gif_ptr, loc_pal_size); - if (gif_image_ptr->local_pal_ptr != NULL) { - FXSYS_memcpy((uint8_t*)gif_image_ptr->local_pal_ptr, loc_pal_ptr, - loc_pal_size); - } - } - uint8_t* code_size_ptr = NULL; - if (_gif_read_data(gif_ptr, &code_size_ptr, 1) == NULL) { - gif_ptr->skip_size = skip_size_org; - if (gif_image_ptr->image_info_ptr != NULL) { - FX_Free(gif_image_ptr->image_info_ptr); - } - if (gif_image_ptr->local_pal_ptr != NULL) { - FX_Free(gif_image_ptr->local_pal_ptr); - } - if (gif_image_ptr->image_row_buf != NULL) { - FX_Free(gif_image_ptr->image_row_buf); - } - FX_Free(gif_image_ptr); - return 2; - } - 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_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->Add(gif_image_ptr); - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA); - return 1; -} -int32_t _gif_load_frame(gif_decompress_struct_p gif_ptr, int32_t frame_num) { - if (gif_ptr == NULL || frame_num < 0 || - frame_num >= gif_ptr->img_ptr_arr_ptr->GetSize()) { - return 0; - } - uint8_t* data_size_ptr = NULL; - uint8_t* data_ptr = NULL; - FX_DWORD skip_size_org = gif_ptr->skip_size; - GifImage* gif_image_ptr = gif_ptr->img_ptr_arr_ptr->GetAt(frame_num); - FX_DWORD gif_img_row_bytes = gif_image_ptr->image_info_ptr->width; - if (gif_ptr->decode_status == GIF_D_STATUS_TAIL) { - if (gif_image_ptr->image_row_buf) { - FX_Free(gif_image_ptr->image_row_buf); - gif_image_ptr->image_row_buf = NULL; - } - gif_image_ptr->image_row_buf = FX_Alloc(uint8_t, gif_img_row_bytes); - GIF_PTR_NOT_NULL(gif_image_ptr->image_row_buf, gif_ptr); - GifGCE* gif_img_gce_ptr = gif_image_ptr->image_gce_ptr; - int32_t loc_pal_num = - ((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)->local_pal - ? (2 << ((GifLF*)&gif_image_ptr->image_info_ptr->local_flag) - ->pal_bits) - : 0; - gif_ptr->avail_in = 0; - if (gif_img_gce_ptr == NULL) { - FX_BOOL bRes = gif_ptr->_gif_get_record_position_fn( - gif_ptr, 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, - gif_image_ptr->local_pal_ptr, 0, 0, -1, 0, - (FX_BOOL)((GifLF*)&gif_image_ptr->image_info_ptr->local_flag) - ->interlace); - if (!bRes) { - FX_Free(gif_image_ptr->image_row_buf); - gif_image_ptr->image_row_buf = NULL; - _gif_error(gif_ptr, "Error Read Record Position Data"); - return 0; - } - } else { - FX_BOOL bRes = gif_ptr->_gif_get_record_position_fn( - gif_ptr, 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, - gif_image_ptr->local_pal_ptr, - (int32_t)gif_image_ptr->image_gce_ptr->delay_time, - (FX_BOOL)((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag) - ->user_input, - ((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag)->transparency - ? (int32_t)gif_image_ptr->image_gce_ptr->trans_index - : -1, - (int32_t)((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag) - ->disposal_method, - (FX_BOOL)((GifLF*)&gif_image_ptr->image_info_ptr->local_flag) - ->interlace); - if (!bRes) { - FX_Free(gif_image_ptr->image_row_buf); - gif_image_ptr->image_row_buf = NULL; - _gif_error(gif_ptr, "Error Read Record Position Data"); - return 0; - } - } - if (gif_ptr->img_decoder_ptr == NULL) { - gif_ptr->img_decoder_ptr = new CGifLZWDecoder(gif_ptr->err_ptr); - GIF_PTR_NOT_NULL(gif_ptr->img_decoder_ptr, gif_ptr); - } - gif_ptr->img_decoder_ptr->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; - if (gif_ptr->decode_status == GIF_D_STATUS_IMG_DATA) { - if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - return 2; - } - if (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL) { - gif_ptr->skip_size = skip_size_org; - return 2; - } - img_decoder_ptr->Input(data_ptr, *data_size_ptr); - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA); - gif_ptr->img_row_offset += gif_ptr->img_row_avail_size; - gif_ptr->img_row_avail_size = gif_img_row_bytes - gif_ptr->img_row_offset; - int32_t ret = img_decoder_ptr->Decode( - gif_image_ptr->image_row_buf + gif_ptr->img_row_offset, - gif_ptr->img_row_avail_size); - if (ret == 0) { - FX_Free(gif_image_ptr->image_row_buf); - gif_image_ptr->image_row_buf = NULL; - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); - _gif_error(gif_ptr, "Decode Image Data Error"); - return 0; - } - while (ret != 0) { - if (ret == 1) { - gif_ptr->_gif_get_row_fn(gif_ptr, 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 = NULL; - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); - return 1; - } - if (ret == 2) { - ASSERT(img_decoder_ptr->GetAvailInput() == 0); - skip_size_org = gif_ptr->skip_size; - if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { - return 2; - } - if (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL) { - gif_ptr->skip_size = skip_size_org; - return 2; - } - img_decoder_ptr->Input(data_ptr, *data_size_ptr); - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA); - gif_ptr->img_row_offset += gif_ptr->img_row_avail_size; - gif_ptr->img_row_avail_size = - gif_img_row_bytes - gif_ptr->img_row_offset; - ret = img_decoder_ptr->Decode( - gif_image_ptr->image_row_buf + gif_ptr->img_row_offset, - gif_ptr->img_row_avail_size); - } - } - if (ret == 3) { - 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_image_ptr->image_row_num += - s_gif_interlace_step[gif_ptr->img_pass_num]; - if (gif_image_ptr->image_row_num >= - (int32_t)gif_image_ptr->image_info_ptr->height) { - gif_ptr->img_pass_num++; - gif_image_ptr->image_row_num = - 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->img_row_offset = 0; - gif_ptr->img_row_avail_size = gif_img_row_bytes; - ret = img_decoder_ptr->Decode( - gif_image_ptr->image_row_buf + gif_ptr->img_row_offset, - gif_ptr->img_row_avail_size); - } - if (ret == 0) { - FX_Free(gif_image_ptr->image_row_buf); - gif_image_ptr->image_row_buf = NULL; - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); - _gif_error(gif_ptr, "Decode Image Data Error"); - return 0; - } - } - } - _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); - } - _gif_error(gif_ptr, "Decode Image Data Error"); - return 0; -} -void _gif_save_decoding_status(gif_decompress_struct_p 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; -} -uint8_t* _gif_read_data(gif_decompress_struct_p gif_ptr, - uint8_t** des_buf_pp, - FX_DWORD data_size) { - if (gif_ptr == NULL || gif_ptr->avail_in < gif_ptr->skip_size + data_size) { - return NULL; - } - *des_buf_pp = gif_ptr->next_in + gif_ptr->skip_size; - gif_ptr->skip_size += data_size; - return *des_buf_pp; -} -void _gif_input_buffer(gif_decompress_struct_p gif_ptr, - uint8_t* src_buf, - FX_DWORD src_size) { - gif_ptr->next_in = src_buf; - gif_ptr->avail_in = src_size; - gif_ptr->skip_size = 0; -} -FX_DWORD _gif_get_avail_input(gif_decompress_struct_p gif_ptr, - uint8_t** avial_buf_ptr) { - if (avial_buf_ptr != NULL) { - *avial_buf_ptr = NULL; - if (gif_ptr->avail_in > 0) { - *avial_buf_ptr = gif_ptr->next_in; - } - } - return gif_ptr->avail_in; -} -int32_t _gif_get_frame_num(gif_decompress_struct_p gif_ptr) { - return gif_ptr->img_ptr_arr_ptr->GetSize(); -} -static FX_BOOL _gif_write_header(gif_compress_struct_p gif_ptr, - uint8_t*& dst_buf, - FX_DWORD& dst_len) { - if (gif_ptr->cur_offset) { - return TRUE; - } - dst_len = sizeof(GifHeader) + sizeof(GifLSD) + sizeof(GifGF); - dst_buf = FX_TryAlloc(uint8_t, dst_len); - if (dst_buf == NULL) { - return FALSE; - } - FXSYS_memset(dst_buf, 0, dst_len); - FXSYS_memcpy(dst_buf, gif_ptr->header_ptr, sizeof(GifHeader)); - gif_ptr->cur_offset += sizeof(GifHeader); - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->width); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->height); - gif_ptr->cur_offset += 2; - dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->global_flag; - dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->bc_index; - dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->pixel_aspect; - if (gif_ptr->global_pal) { - FX_WORD size = sizeof(GifPalette) * gif_ptr->gpal_num; - if (!_gif_grow_buf(dst_buf, dst_len, gif_ptr->cur_offset + size)) { - return FALSE; - } - FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->global_pal, size); - gif_ptr->cur_offset += size; - } - return TRUE; -} -void interlace_buf(const uint8_t* buf, FX_DWORD pitch, FX_DWORD height) { - CFX_ArrayTemplate pass[4]; - int i, j; - FX_DWORD row; - row = 0; - uint8_t* temp; - while (row < height) { - if (row % 8 == 0) { - j = 0; - } else if (row % 4 == 0) { - j = 1; - } else if (row % 2 == 0) { - j = 2; - } else { - j = 3; - } - temp = FX_Alloc(uint8_t, pitch); - if (temp == NULL) { - return; - } - FXSYS_memcpy(temp, &buf[pitch * row], pitch); - pass[j].Add(temp); - row++; - } - for (i = 0, row = 0; i < 4; i++) { - for (j = 0; j < pass[i].GetSize(); j++, row++) { - FXSYS_memcpy((uint8_t*)&buf[pitch * row], pass[i].GetAt(j), pitch); - FX_Free(pass[i].GetAt(j)); - } - } -} -static void _gif_write_block_data(const uint8_t* src_buf, - FX_DWORD src_len, - uint8_t*& dst_buf, - FX_DWORD& dst_len, - FX_DWORD& dst_offset) { - FX_DWORD src_offset = 0; - while (src_len > GIF_DATA_BLOCK) { - dst_buf[dst_offset++] = GIF_DATA_BLOCK; - FXSYS_memcpy(&dst_buf[dst_offset], &src_buf[src_offset], GIF_DATA_BLOCK); - dst_offset += GIF_DATA_BLOCK; - src_offset += GIF_DATA_BLOCK; - src_len -= GIF_DATA_BLOCK; - } - dst_buf[dst_offset++] = (uint8_t)src_len; - FXSYS_memcpy(&dst_buf[dst_offset], &src_buf[src_offset], src_len); - dst_offset += src_len; -} -static FX_BOOL _gif_write_data(gif_compress_struct_p gif_ptr, - uint8_t*& dst_buf, - FX_DWORD& dst_len) { - if (!_gif_grow_buf(dst_buf, dst_len, gif_ptr->cur_offset + GIF_DATA_BLOCK)) { - return FALSE; - } -#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION - if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0) { - dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION; - dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_GCE; - gif_ptr->gce_ptr->block_size = 4; - dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->block_size; - gif_ptr->gce_ptr->gce_flag = 0; - dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->gce_flag; - gif_ptr->gce_ptr->delay_time = 10; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->gce_ptr->delay_time); - gif_ptr->cur_offset += 2; - gif_ptr->gce_ptr->trans_index = 0; - dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->trans_index; - dst_buf[gif_ptr->cur_offset++] = 0; - } -#endif - dst_buf[gif_ptr->cur_offset++] = GIF_SIG_IMAGE; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->image_info_ptr->left); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->image_info_ptr->top); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->image_info_ptr->width); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->image_info_ptr->height); - gif_ptr->cur_offset += 2; - GifLF& lf = (GifLF&)gif_ptr->image_info_ptr->local_flag; - dst_buf[gif_ptr->cur_offset++] = gif_ptr->image_info_ptr->local_flag; - if (gif_ptr->local_pal) { - FX_DWORD pal_size = sizeof(GifPalette) * gif_ptr->lpal_num; - if (!_gif_grow_buf(dst_buf, dst_len, pal_size + gif_ptr->cur_offset)) { - return FALSE; - } - FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->local_pal, pal_size); - gif_ptr->cur_offset += pal_size; - } - if (lf.interlace) { - interlace_buf(gif_ptr->src_buf, gif_ptr->src_pitch, - gif_ptr->image_info_ptr->height); - } - uint8_t code_bit = lf.pal_bits; - if (lf.local_pal == 0) { - GifGF& gf = (GifGF&)gif_ptr->lsd_ptr->global_flag; - code_bit = gf.pal_bits; - } - gif_ptr->img_encoder_ptr->Start(code_bit, gif_ptr->src_buf, dst_buf, - gif_ptr->cur_offset); - FX_DWORD i; - for (i = 0; i < gif_ptr->src_row; i++) { - if (!gif_ptr->img_encoder_ptr->Encode( - &gif_ptr->src_buf[i * gif_ptr->src_pitch], - gif_ptr->src_width * (code_bit + 1), dst_buf, dst_len, - gif_ptr->cur_offset)) { - return FALSE; - } - } - gif_ptr->img_encoder_ptr->Finish(dst_buf, dst_len, gif_ptr->cur_offset); - dst_buf[gif_ptr->cur_offset++] = 0; -#ifdef GIF_SUPPORT_COMMENT_EXTENSION - if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0 && - gif_ptr->cmt_data_ptr) { - dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION; - dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_CE; - _gif_write_block_data(gif_ptr->cmt_data_ptr, gif_ptr->cmt_data_len, dst_buf, - dst_len, gif_ptr->cur_offset); - dst_buf[gif_ptr->cur_offset++] = 0; - } -#endif -#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0 && - gif_ptr->pte_data_ptr) { - dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION; - dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_PTE; - dst_buf[gif_ptr->cur_offset++] = gif_ptr->pte_ptr->block_size; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->pte_ptr->grid_left); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->pte_ptr->grid_top); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->pte_ptr->grid_width); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->pte_ptr->grid_height); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->pte_ptr->char_width); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->pte_ptr->char_height); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->pte_ptr->fc_index); - gif_ptr->cur_offset += 2; - _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, - gif_ptr->pte_ptr->bc_index); - gif_ptr->cur_offset += 2; - _gif_write_block_data(gif_ptr->pte_data_ptr, gif_ptr->pte_data_len, dst_buf, - dst_len, gif_ptr->cur_offset); - gif_ptr->cur_offset += gif_ptr->pte_data_len; - dst_buf[gif_ptr->cur_offset++] = 0; - } -#endif -#ifdef GIF_SUPPORT_APPLICATION_EXTENSION - if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0 && - gif_ptr->app_data) { - dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION; - dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_AE; - dst_buf[gif_ptr->cur_offset++] = 11; - FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->app_identify, 8); - gif_ptr->cur_offset += 8; - FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->app_authentication, 8); - gif_ptr->cur_offset += 3; - FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->app_data, - gif_ptr->app_data_size); - gif_ptr->cur_offset += gif_ptr->app_data_size; - dst_buf[gif_ptr->cur_offset++] = 0; - } -#endif - dst_buf[gif_ptr->cur_offset++] = GIF_SIG_TRAILER; - return TRUE; -} -FX_BOOL _gif_encode(gif_compress_struct_p gif_ptr, - uint8_t*& dst_buf, - FX_DWORD& dst_len) { - if (!_gif_write_header(gif_ptr, dst_buf, dst_len)) { - return FALSE; - } - FX_DWORD cur_offset = gif_ptr->cur_offset; - FX_BOOL res = TRUE; - if (gif_ptr->frames) { - gif_ptr->cur_offset--; - } - if (!_gif_write_data(gif_ptr, dst_buf, dst_len)) { - gif_ptr->cur_offset = cur_offset; - res = FALSE; - } - dst_len = gif_ptr->cur_offset; - dst_buf[dst_len - 1] = GIF_SIG_TRAILER; - if (res) { - gif_ptr->frames++; - } - return res; -} +// 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 "fx_gif.h" +void CGifLZWDecoder::Input(uint8_t* src_buf, FX_DWORD src_size) { + next_in = src_buf; + avail_in = src_size; +} +FX_DWORD CGifLZWDecoder::GetAvailInput() { + return avail_in; +} +void CGifLZWDecoder::InitTable(uint8_t code_len) { + code_size = code_len; + code_clear = 1 << code_size; + code_end = code_clear + 1; + bits_left = 0; + code_store = 0; + next_in = NULL; + avail_in = 0; + stack_size = 0; + code_first = 0; + ClearTable(); +} +void CGifLZWDecoder::ClearTable() { + code_size_cur = code_size + 1; + code_next = code_end + 1; + code_old = (FX_WORD)-1; + FXSYS_memset(code_table, 0, sizeof(tag_Table) * GIF_MAX_LZW_CODE); + FXSYS_memset(stack, 0, GIF_MAX_LZW_CODE); + for (FX_WORD i = 0; i < code_clear; i++) { + code_table[i].suffix = (uint8_t)i; + } +} +void CGifLZWDecoder::DecodeString(FX_WORD code) { + stack_size = 0; + while (TRUE) { + ASSERT(code <= code_next); + if (code < code_clear || code > code_next) { + break; + } + stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = code_table[code].suffix; + code = code_table[code].prefix; + } + stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = (uint8_t)code; + code_first = (uint8_t)code; +} +void CGifLZWDecoder::AddCode(FX_WORD prefix_code, uint8_t append_char) { + if (code_next == GIF_MAX_LZW_CODE) { + return; + } + code_table[code_next].prefix = prefix_code; + code_table[code_next].suffix = append_char; + if (++code_next < GIF_MAX_LZW_CODE) { + if (code_next >> code_size_cur) { + code_size_cur++; + } + } +} +int32_t CGifLZWDecoder::Decode(uint8_t* des_buf, FX_DWORD& des_size) { + if (des_size == 0) { + return 3; + } + FX_DWORD i = 0; + if (stack_size != 0) { + if (des_size < stack_size) { + FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], des_size); + stack_size -= (FX_WORD)des_size; + return 3; + } + FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], stack_size); + des_buf += stack_size; + i += stack_size; + stack_size = 0; + } + FX_WORD code = 0; + while (i <= des_size && (avail_in > 0 || bits_left >= code_size_cur)) { + if (code_size_cur > 12) { + if (err_msg_ptr) { + FXSYS_strncpy(err_msg_ptr, "Code Length Out Of Range", + GIF_MAX_ERROR_SIZE - 1); + } + return 0; + } + if (avail_in > 0) { + code_store |= (*next_in++) << bits_left; + avail_in--; + bits_left += 8; + } + while (bits_left >= code_size_cur) { + code = (FX_WORD)code_store & ((1 << code_size_cur) - 1); + code_store >>= code_size_cur; + bits_left -= code_size_cur; + if (code == code_clear) { + ClearTable(); + continue; + } else if (code == code_end) { + des_size = i; + return 1; + } else { + if (code_old != (FX_WORD)-1) { + if (code_next < GIF_MAX_LZW_CODE) { + if (code == code_next) { + AddCode(code_old, code_first); + DecodeString(code); + } else if (code > code_next) { + if (err_msg_ptr) { + FXSYS_strncpy(err_msg_ptr, "Decode Error, Out Of Range", + GIF_MAX_ERROR_SIZE - 1); + } + return 0; + } else { + DecodeString(code); + uint8_t append_char = stack[GIF_MAX_LZW_CODE - stack_size]; + AddCode(code_old, append_char); + } + } + } else { + DecodeString(code); + } + code_old = code; + if (i + stack_size > des_size) { + FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], + des_size - i); + stack_size -= (FX_WORD)(des_size - i); + return 3; + } + FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], + stack_size); + des_buf += stack_size; + i += stack_size; + stack_size = 0; + } + } + } + if (avail_in == 0) { + des_size = i; + return 2; + } + return 0; +} +static FX_BOOL _gif_grow_buf(uint8_t*& dst_buf, + FX_DWORD& dst_len, + FX_DWORD size) { + if (dst_len < size) { + FX_DWORD len_org = dst_len; + while (dst_buf && dst_len < size) { + dst_len <<= 1; + dst_buf = FX_Realloc(uint8_t, dst_buf, dst_len); + } + if (dst_buf == NULL) { + dst_len = size; + dst_buf = FX_Realloc(uint8_t, dst_buf, dst_len); + if (dst_buf == NULL) { + return FALSE; + } + } + FXSYS_memset(dst_buf + len_org, 0, dst_len - len_org); + return dst_buf != NULL; + } + return TRUE; +} +static inline void _gif_cut_index(uint8_t& val, + FX_DWORD index, + uint8_t index_bit, + uint8_t index_bit_use, + uint8_t bit_use) { + FX_DWORD cut = ((1 << (index_bit - index_bit_use)) - 1) << index_bit_use; + val |= ((index & cut) >> index_bit_use) << bit_use; +} +static inline uint8_t _gif_cut_buf(const uint8_t* buf, + FX_DWORD& offset, + uint8_t bit_cut, + uint8_t& bit_offset, + FX_DWORD& bit_num) { + if (bit_cut != 8) { + FX_WORD index = 0; + index |= ((1 << bit_cut) - 1) << (7 - bit_offset); + uint8_t ret = ((index & buf[offset]) >> (7 - bit_offset)); + bit_offset += bit_cut; + if (bit_offset >= 8) { + if (bit_offset > 8) { + ret |= ((index & (buf[offset + 1] << 8)) >> 8); + } + bit_offset -= 8; + offset++; + } + bit_num += bit_cut; + return ret; + } + bit_num += bit_cut; + return buf[offset++]; +} +CGifLZWEncoder::CGifLZWEncoder() { + FXSYS_memset(this, 0, sizeof(CGifLZWEncoder)); +} +CGifLZWEncoder::~CGifLZWEncoder() {} +void CGifLZWEncoder::ClearTable() { + index_bit_cur = code_size + 1; + index_num = code_end + 1; + table_cur = code_end + 1; + for (FX_WORD i = 0; i < GIF_MAX_LZW_CODE; i++) { + code_table[i].prefix = 0; + code_table[i].suffix = 0; + } +} +void CGifLZWEncoder::Start(uint8_t code_len, + const uint8_t* src_buf, + uint8_t*& dst_buf, + FX_DWORD& offset) { + code_size = code_len + 1; + src_bit_cut = code_size; + if (code_len == 0) { + src_bit_cut = 1; + code_size = 2; + } + code_clear = 1 << code_size; + code_end = code_clear + 1; + dst_buf[offset++] = code_size; + bit_offset = 0; + ClearTable(); + src_offset = 0; + src_bit_offset = 0; + src_bit_num = 0; + code_table[index_num].prefix = _gif_cut_buf(src_buf, src_offset, src_bit_cut, + src_bit_offset, src_bit_num); + code_table[index_num].suffix = _gif_cut_buf(src_buf, src_offset, src_bit_cut, + src_bit_offset, src_bit_num); +} +void CGifLZWEncoder::WriteBlock(uint8_t*& dst_buf, + FX_DWORD& dst_len, + FX_DWORD& offset) { + if (!_gif_grow_buf(dst_buf, dst_len, offset + GIF_DATA_BLOCK + 1)) { + longjmp(jmp, 1); + } + dst_buf[offset++] = index_buf_len; + FXSYS_memcpy(&dst_buf[offset], index_buf, index_buf_len); + offset += index_buf_len; + FXSYS_memset(index_buf, 0, GIF_DATA_BLOCK); + index_buf_len = 0; +} +void CGifLZWEncoder::EncodeString(FX_DWORD index, + uint8_t*& dst_buf, + FX_DWORD& dst_len, + FX_DWORD& offset) { + uint8_t index_bit_use; + index_bit_use = 0; + if (index_buf_len == GIF_DATA_BLOCK) { + WriteBlock(dst_buf, dst_len, offset); + } + _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, index_bit_use, + bit_offset); + if (index_bit_cur <= (8 - bit_offset)) { + bit_offset += index_bit_cur; + } else if (index_bit_cur <= (16 - bit_offset)) { + index_bit_use += (8 - bit_offset); + bit_offset = 0; + index_buf_len++; + if (index_buf_len == GIF_DATA_BLOCK) { + WriteBlock(dst_buf, dst_len, offset); + } + _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, + index_bit_use, bit_offset); + bit_offset = index_bit_cur - index_bit_use; + } else { + index_bit_use += (8 - bit_offset); + bit_offset = 0; + index_buf_len++; + if (index_buf_len == GIF_DATA_BLOCK) { + WriteBlock(dst_buf, dst_len, offset); + } + _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, + index_bit_use, bit_offset); + index_bit_use += 8; + bit_offset = 0; + index_buf_len++; + if (index_buf_len == GIF_DATA_BLOCK) { + WriteBlock(dst_buf, dst_len, offset); + } + _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, + index_bit_use, bit_offset); + bit_offset = index_bit_cur - index_bit_use; + } + if (bit_offset == 8) { + bit_offset = 0; + index_buf_len++; + if (index_buf_len == GIF_DATA_BLOCK) { + WriteBlock(dst_buf, dst_len, offset); + } + } + if (index == code_end) { + index_buf_len++; + WriteBlock(dst_buf, dst_len, offset); + } + if (index_num++ >> index_bit_cur) { + index_bit_cur++; + } +} +FX_BOOL CGifLZWEncoder::Encode(const uint8_t* src_buf, + FX_DWORD src_len, + uint8_t*& dst_buf, + FX_DWORD& dst_len, + FX_DWORD& offset) { + uint8_t suffix; + if (setjmp(jmp)) { + return FALSE; + } + while (src_bit_num < src_len) { + if (!LookUpInTable(src_buf, src_offset, src_bit_offset)) { + EncodeString(code_table[index_num].prefix, dst_buf, dst_len, offset); + if (index_num == GIF_MAX_LZW_CODE) { + suffix = code_table[index_num - 1].suffix; + EncodeString(code_clear, dst_buf, dst_len, offset); + ClearTable(); + code_table[index_num].prefix = suffix; + code_table[index_num].suffix = _gif_cut_buf( + src_buf, src_offset, src_bit_cut, src_bit_offset, src_bit_num); + } else { + code_table[index_num].prefix = code_table[index_num - 1].suffix; + code_table[index_num].suffix = _gif_cut_buf( + src_buf, src_offset, src_bit_cut, src_bit_offset, src_bit_num); + } + } + } + src_offset = 0; + src_bit_offset = 0; + src_bit_num = 0; + return TRUE; +} +FX_BOOL CGifLZWEncoder::LookUpInTable(const uint8_t* buf, + FX_DWORD& offset, + uint8_t& bit_offset) { + for (FX_WORD i = table_cur; i < index_num; i++) { + if (code_table[i].prefix == code_table[index_num].prefix && + code_table[i].suffix == code_table[index_num].suffix) { + code_table[index_num].prefix = i; + code_table[index_num].suffix = + _gif_cut_buf(buf, offset, src_bit_cut, bit_offset, src_bit_num); + table_cur = i; + return TRUE; + } + } + table_cur = code_end + 1; + return FALSE; +} +void CGifLZWEncoder::Finish(uint8_t*& dst_buf, + FX_DWORD& dst_len, + FX_DWORD& offset) { + EncodeString(code_table[index_num].prefix, dst_buf, dst_len, offset); + EncodeString(code_end, dst_buf, dst_len, offset); + bit_offset = 0; + ClearTable(); +} +gif_decompress_struct_p _gif_create_decompress() { + gif_decompress_struct_p gif_ptr = + (gif_decompress_struct*)FX_Alloc(uint8_t, sizeof(gif_decompress_struct)); + if (gif_ptr == NULL) { + return NULL; + } + FXSYS_memset(gif_ptr, 0, sizeof(gif_decompress_struct)); + gif_ptr->decode_status = GIF_D_STATUS_SIG; + gif_ptr->img_ptr_arr_ptr = new CFX_ArrayTemplate; +#ifdef GIF_SUPPORT_COMMENT_EXTENSION + gif_ptr->cmt_data_ptr = new CFX_ByteString; +#endif +#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + gif_ptr->pt_ptr_arr_ptr = new CFX_ArrayTemplate; +#endif + return gif_ptr; +} +void _gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr) { + if (gif_ptr_ptr == NULL || *gif_ptr_ptr == NULL) { + return; + } + gif_decompress_struct_p gif_ptr = *gif_ptr_ptr; + *gif_ptr_ptr = NULL; + if (gif_ptr->global_pal_ptr != NULL) { + FX_Free(gif_ptr->global_pal_ptr); + } + if (gif_ptr->img_decoder_ptr != NULL) { + delete gif_ptr->img_decoder_ptr; + } + if (gif_ptr->img_ptr_arr_ptr != NULL) { + int32_t size_img_arr = gif_ptr->img_ptr_arr_ptr->GetSize(); + for (int32_t i = 0; i < size_img_arr; i++) { + GifImage* p = gif_ptr->img_ptr_arr_ptr->GetAt(i); + if (p->image_info_ptr != NULL) { + FX_Free(p->image_info_ptr); + } + if (p->image_gce_ptr != NULL) { + FX_Free(p->image_gce_ptr); + } + if (p->image_row_buf != NULL) { + FX_Free(p->image_row_buf); + } + if (p->local_pal_ptr != NULL && + p->local_pal_ptr != gif_ptr->global_pal_ptr) { + FX_Free(p->local_pal_ptr); + } + FX_Free(p); + } + gif_ptr->img_ptr_arr_ptr->RemoveAll(); + delete gif_ptr->img_ptr_arr_ptr; + } +#ifdef GIF_SUPPORT_APPLICATION_EXTENSION + if (gif_ptr->app_data != NULL) { + FX_Free(gif_ptr->app_data); + } +#endif +#ifdef GIF_SUPPORT_COMMENT_EXTENSION + if (gif_ptr->cmt_data_ptr != NULL) { + delete gif_ptr->cmt_data_ptr; + } +#endif +#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION + if (gif_ptr->gce_ptr != NULL) { + FX_Free(gif_ptr->gce_ptr); + } +#endif +#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + if (gif_ptr->pt_ptr_arr_ptr != NULL) { + int32_t size_pt_arr = gif_ptr->pt_ptr_arr_ptr->GetSize(); + for (int32_t i = 0; i < size_pt_arr; i++) { + GifPlainText* p = gif_ptr->pt_ptr_arr_ptr->GetAt(i); + if (p->gce_ptr != NULL) { + FX_Free(p->gce_ptr); + } + if (p->pte_ptr != NULL) { + FX_Free(p->pte_ptr); + } + if (p->string_ptr != NULL) { + delete p->string_ptr; + } + } + gif_ptr->pt_ptr_arr_ptr->RemoveAll(); + delete gif_ptr->pt_ptr_arr_ptr; + } +#endif + FX_Free(gif_ptr); +} +gif_compress_struct_p _gif_create_compress() { + gif_compress_struct_p gif_ptr = + (gif_compress_struct*)FX_Alloc(uint8_t, sizeof(gif_compress_struct)); + if (gif_ptr == NULL) { + return NULL; + } + FXSYS_memset(gif_ptr, 0, sizeof(gif_compress_struct)); + gif_ptr->img_encoder_ptr = new CGifLZWEncoder; + gif_ptr->header_ptr = (GifHeader*)FX_Alloc(uint8_t, sizeof(GifHeader)); + if (gif_ptr->header_ptr == NULL) { + delete (gif_ptr->img_encoder_ptr); + FX_Free(gif_ptr); + return NULL; + } + FXSYS_memcpy(gif_ptr->header_ptr->signature, GIF_SIGNATURE, 3); + FXSYS_memcpy(gif_ptr->header_ptr->version, "89a", 3); + gif_ptr->lsd_ptr = (GifLSD*)FX_Alloc(uint8_t, sizeof(GifLSD)); + if (gif_ptr->lsd_ptr == NULL) { + FX_Free(gif_ptr->header_ptr); + delete (gif_ptr->img_encoder_ptr); + FX_Free(gif_ptr); + return NULL; + } + FXSYS_memset(gif_ptr->lsd_ptr, 0, sizeof(GifLSD)); + gif_ptr->image_info_ptr = + (GifImageInfo*)FX_Alloc(uint8_t, sizeof(GifImageInfo)); + if (gif_ptr->image_info_ptr == NULL) { + FX_Free(gif_ptr->lsd_ptr); + FX_Free(gif_ptr->header_ptr); + delete (gif_ptr->img_encoder_ptr); + FX_Free(gif_ptr); + return NULL; + } + FXSYS_memset(gif_ptr->image_info_ptr, 0, sizeof(GifImageInfo)); +#ifdef GIF_SUPPORT_APPLICATION_EXTENSION + FXSYS_memcpy(gif_ptr->app_identify, "netscape", 8); + FXSYS_memcpy(gif_ptr->app_authentication, "2.0", 3); +#endif +#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION + gif_ptr->gce_ptr = (GifGCE*)FX_Alloc(uint8_t, sizeof(GifGCE)); + if (gif_ptr->gce_ptr == NULL) { + FX_Free(gif_ptr->image_info_ptr); + FX_Free(gif_ptr->lsd_ptr); + FX_Free(gif_ptr->header_ptr); + delete (gif_ptr->img_encoder_ptr); + FX_Free(gif_ptr); + return NULL; + } +#endif +#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + gif_ptr->pte_ptr = (GifPTE*)FX_Alloc(uint8_t, sizeof(GifPTE)); + if (gif_ptr->pte_ptr == NULL) { + FX_Free(gif_ptr->gce_ptr); + FX_Free(gif_ptr->image_info_ptr); + FX_Free(gif_ptr->lsd_ptr); + FX_Free(gif_ptr->header_ptr); + delete (gif_ptr->img_encoder_ptr); + FX_Free(gif_ptr); + return NULL; + } + FXSYS_memset(gif_ptr->pte_ptr, 0, sizeof(GifPTE)); + gif_ptr->pte_ptr->block_size = 12; +#endif + return gif_ptr; +} +void _gif_destroy_compress(gif_compress_struct_pp gif_ptr_ptr) { + if (gif_ptr_ptr == NULL || *gif_ptr_ptr == NULL) { + return; + } + gif_compress_struct_p gif_ptr = *gif_ptr_ptr; + *gif_ptr_ptr = NULL; + if (gif_ptr->header_ptr != NULL) { + FX_Free(gif_ptr->header_ptr); + } + if (gif_ptr->lsd_ptr != NULL) { + FX_Free(gif_ptr->lsd_ptr); + } + if (gif_ptr->global_pal != NULL) { + FX_Free(gif_ptr->global_pal); + } + if (gif_ptr->image_info_ptr != NULL) { + FX_Free(gif_ptr->image_info_ptr); + } + if (gif_ptr->local_pal != NULL) { + FX_Free(gif_ptr->local_pal); + } + if (gif_ptr->img_encoder_ptr != NULL) { + delete gif_ptr->img_encoder_ptr; + } +#ifdef GIF_SUPPORT_APPLICATION_EXTENSION + if (gif_ptr->app_data != NULL) { + FX_Free(gif_ptr->app_data); + } +#endif +#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION + if (gif_ptr->gce_ptr != NULL) { + FX_Free(gif_ptr->gce_ptr); + } +#endif +#ifdef GIF_SUPPORT_COMMENT_EXTENSION + if (gif_ptr->cmt_data_ptr != NULL) { + FX_Free(gif_ptr->cmt_data_ptr); + } +#endif +#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + if (gif_ptr->pte_ptr != NULL) { + FX_Free(gif_ptr->pte_ptr); + } +#endif + FX_Free(gif_ptr); +} +void _gif_error(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg) { + if (gif_ptr != NULL && gif_ptr->_gif_error_fn != NULL) { + gif_ptr->_gif_error_fn(gif_ptr, err_msg); + } +} +void _gif_warn(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg) {} +int32_t _gif_read_header(gif_decompress_struct_p gif_ptr) { + if (gif_ptr == NULL) { + return 0; + } + FX_DWORD skip_size_org = gif_ptr->skip_size; + ASSERT(sizeof(GifHeader) == 6); + GifHeader* gif_header_ptr = NULL; + if (_gif_read_data(gif_ptr, (uint8_t**)&gif_header_ptr, 6) == NULL) { + return 2; + } + if (FXSYS_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"); + return 0; + } + ASSERT(sizeof(GifLSD) == 7); + GifLSD* gif_lsd_ptr = NULL; + if (_gif_read_data(gif_ptr, (uint8_t**)&gif_lsd_ptr, 7) == NULL) { + gif_ptr->skip_size = skip_size_org; + return 2; + } + if (((GifGF*)&gif_lsd_ptr->global_flag)->global_pal) { + gif_ptr->global_pal_num = 2 + << ((GifGF*)&gif_lsd_ptr->global_flag)->pal_bits; + ASSERT(sizeof(GifPalette) == 3); + int32_t global_pal_size = gif_ptr->global_pal_num * 3; + uint8_t* global_pal_ptr = NULL; + if (_gif_read_data(gif_ptr, &global_pal_ptr, global_pal_size) == NULL) { + gif_ptr->skip_size = skip_size_org; + return 2; + } + 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; + if (gif_ptr->global_pal_ptr != NULL) { + FX_Free(gif_ptr->global_pal_ptr); + } + gif_ptr->global_pal_ptr = NULL; + gif_ptr->global_pal_ptr = (GifPalette*)FX_Alloc(uint8_t, global_pal_size); + GIF_PTR_NOT_NULL(gif_ptr->global_pal_ptr, gif_ptr); + FXSYS_memcpy(gif_ptr->global_pal_ptr, 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); + gif_ptr->bc_index = gif_lsd_ptr->bc_index; + gif_ptr->pixel_aspect = gif_lsd_ptr->pixel_aspect; + return 1; +} +int32_t _gif_get_frame(gif_decompress_struct_p gif_ptr) { + if (gif_ptr == NULL) { + return 0; + } + int32_t ret = 1; + while (TRUE) { + switch (gif_ptr->decode_status) { + case GIF_D_STATUS_TAIL: + return 1; + case GIF_D_STATUS_SIG: { + uint8_t* sig_ptr = NULL; + if (_gif_read_data(gif_ptr, &sig_ptr, 1) == NULL) { + return 2; + } + switch (*sig_ptr) { + case GIF_SIG_EXTENSION: + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT); + continue; + case GIF_SIG_IMAGE: + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_INFO); + continue; + case GIF_SIG_TRAILER: + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); + return 1; + default: + if (gif_ptr->avail_in) { + _gif_warn(gif_ptr, "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!"); + return 1; + } + } + case GIF_D_STATUS_EXT: { + uint8_t* ext_ptr = NULL; + if (_gif_read_data(gif_ptr, &ext_ptr, 1) == NULL) { + return 2; + } + switch (*ext_ptr) { +#ifdef GIF_SUPPORT_APPLICATION_EXTENSION + case GIF_BLOCK_AE: + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_AE); + continue; +#endif +#ifdef GIF_SUPPORT_COMMENT_EXTENSION + case GIF_BLOCK_CE: + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_CE); + continue; +#endif +#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION + case GIF_BLOCK_GCE: + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_GCE); + continue; +#endif +#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + case GIF_BLOCK_PTE: + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_PTE); + continue; +#endif + default: { + int32_t status = GIF_D_STATUS_EXT_UNE; +#ifndef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + if (*ext_ptr == GIF_BLOCK_PTE) { + status = GIF_D_STATUS_EXT_PTE; + } +#endif + _gif_save_decoding_status(gif_ptr, status); + continue; + } + } + } + case GIF_D_STATUS_IMG_INFO: { + ret = _gif_decode_image_info(gif_ptr); + if (ret != 1) { + return ret; + } + continue; + } + case GIF_D_STATUS_IMG_DATA: { + uint8_t* data_size_ptr = NULL; + uint8_t* data_ptr = NULL; + FX_DWORD skip_size_org = gif_ptr->skip_size; + if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + return 2; + } + while (*data_size_ptr != GIF_BLOCK_TERMINAL) { + if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL) { + gif_ptr->skip_size = skip_size_org; + return 2; + } + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA); + skip_size_org = gif_ptr->skip_size; + if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + return 2; + } + } + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG); + continue; + } + default: { + ret = _gif_decode_extension(gif_ptr); + if (ret != 1) { + return ret; + } + continue; + } + } + } + return 1; +} +void _gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr, + GifGCE** gce_ptr_ptr) { + *gce_ptr_ptr = NULL; +#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION + if (gif_ptr->gce_ptr != NULL && gce_ptr_ptr != NULL) { + *gce_ptr_ptr = gif_ptr->gce_ptr; + gif_ptr->gce_ptr = NULL; + } +#endif +} +int32_t _gif_decode_extension(gif_decompress_struct_p gif_ptr) { + uint8_t* data_size_ptr = NULL; + uint8_t* data_ptr = NULL; + FX_DWORD skip_size_org = gif_ptr->skip_size; + switch (gif_ptr->decode_status) { +#ifdef GIF_SUPPORT_APPLICATION_EXTENSION + case GIF_D_STATUS_EXT_AE: { + ASSERT(sizeof(GifAE) == 12); + GifAE* gif_ae_ptr = NULL; + if (_gif_read_data(gif_ptr, (uint8_t**)&gif_ae_ptr, 12) == NULL) { + return 2; + } + CFX_ByteString gif_ae_data_str; + if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + gif_ptr->skip_size = skip_size_org; + return 2; + } + while (*data_size_ptr != GIF_BLOCK_TERMINAL) { + uint8_t data_size = *data_size_ptr; + if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL || + _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + gif_ptr->skip_size = skip_size_org; + return 2; + } + gif_ae_data_str += CFX_ByteString((const uint8_t*)data_ptr, data_size); + } + FXSYS_memcpy(gif_ptr->app_identify, gif_ae_ptr->app_identify, 8); + FXSYS_memcpy(gif_ptr->app_authentication, gif_ae_ptr->app_authentication, + 3); + gif_ptr->app_data_size = gif_ae_data_str.GetLength(); + if (gif_ptr->app_data != NULL) { + FX_Free(gif_ptr->app_data); + gif_ptr->app_data = NULL; + } + gif_ptr->app_data = FX_Alloc(uint8_t, gif_ptr->app_data_size); + GIF_PTR_NOT_NULL(gif_ptr->app_data, gif_ptr); + FXSYS_memcpy(gif_ptr->app_data, const uint8_t*(gif_ae_data_str), + gif_ptr->app_data_size); + } break; +#endif +#ifdef GIF_SUPPORT_COMMENT_EXTENSION + case GIF_D_STATUS_EXT_CE: { + if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + gif_ptr->skip_size = skip_size_org; + return 2; + } + gif_ptr->cmt_data_ptr->Empty(); + while (*data_size_ptr != GIF_BLOCK_TERMINAL) { + uint8_t data_size = *data_size_ptr; + if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL || + _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + gif_ptr->skip_size = skip_size_org; + return 2; + } + *(gif_ptr->cmt_data_ptr) += + CFX_ByteString((const FX_CHAR*)data_ptr, data_size); + } + } break; +#endif +#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + case GIF_D_STATUS_EXT_PTE: { + ASSERT(sizeof(GifPTE) == 13); + GifPTE* gif_pte_ptr = NULL; + if (_gif_read_data(gif_ptr, (uint8_t**)&gif_pte_ptr, 13) == NULL) { + return 2; + } + GifPlainText* gif_pt_ptr = FX_Alloc(GifPlainText, 1); + GIF_PTR_NOT_NULL(gif_pt_ptr, gif_ptr); + FXSYS_memset(gif_pt_ptr, 0, sizeof(GifPlainText)); + _gif_takeover_gce_ptr(gif_ptr, &gif_pt_ptr->gce_ptr); + gif_pt_ptr->pte_ptr = (GifPTE*)FX_Alloc(uint8_t, sizeof(GifPTE)); + GIF_PTR_NOT_NULL(gif_pt_ptr->pte_ptr, gif_ptr); + gif_pt_ptr->string_ptr = new CFX_ByteString; + GIF_PTR_NOT_NULL(gif_pt_ptr->string_ptr, gif_ptr); + gif_pt_ptr->pte_ptr->block_size = gif_pte_ptr->block_size; + gif_pt_ptr->pte_ptr->grid_left = + _GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_left); + gif_pt_ptr->pte_ptr->grid_top = + _GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_top); + gif_pt_ptr->pte_ptr->grid_width = + _GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_width); + gif_pt_ptr->pte_ptr->grid_height = + _GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_height); + gif_pt_ptr->pte_ptr->char_width = gif_pte_ptr->char_width; + gif_pt_ptr->pte_ptr->char_height = gif_pte_ptr->char_height; + gif_pt_ptr->pte_ptr->fc_index = gif_pte_ptr->fc_index; + gif_pt_ptr->pte_ptr->bc_index = gif_pte_ptr->bc_index; + if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + gif_ptr->skip_size = skip_size_org; + if (gif_pt_ptr != NULL) { + if (gif_pt_ptr->gce_ptr != NULL) { + FX_Free(gif_pt_ptr->gce_ptr); + } + if (gif_pt_ptr->pte_ptr != NULL) { + FX_Free(gif_pt_ptr->pte_ptr); + } + if (gif_pt_ptr->string_ptr != NULL) { + delete gif_pt_ptr->string_ptr; + } + FX_Free(gif_pt_ptr); + } + return 2; + } + while (*data_size_ptr != GIF_BLOCK_TERMINAL) { + uint8_t data_size = *data_size_ptr; + if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL || + _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + gif_ptr->skip_size = skip_size_org; + if (gif_pt_ptr != NULL) { + if (gif_pt_ptr->gce_ptr != NULL) { + FX_Free(gif_pt_ptr->gce_ptr); + } + if (gif_pt_ptr->pte_ptr != NULL) { + FX_Free(gif_pt_ptr->pte_ptr); + } + if (gif_pt_ptr->string_ptr != NULL) { + delete gif_pt_ptr->string_ptr; + } + FX_Free(gif_pt_ptr); + } + return 2; + } + *(gif_pt_ptr->string_ptr) += + CFX_ByteString((const FX_CHAR*)data_ptr, data_size); + } + gif_ptr->pt_ptr_arr_ptr->Add(gif_pt_ptr); + } break; +#endif +#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION + case GIF_D_STATUS_EXT_GCE: { + ASSERT(sizeof(GifGCE) == 5); + GifGCE* gif_gce_ptr = NULL; + if (_gif_read_data(gif_ptr, (uint8_t**)&gif_gce_ptr, 6) == NULL) { + return 2; + } + if (gif_ptr->gce_ptr == NULL) { + gif_ptr->gce_ptr = (GifGCE*)FX_Alloc(uint8_t, sizeof(GifGCE)); + GIF_PTR_NOT_NULL(gif_ptr->gce_ptr, gif_ptr); + } + gif_ptr->gce_ptr->block_size = gif_gce_ptr->block_size; + gif_ptr->gce_ptr->gce_flag = gif_gce_ptr->gce_flag; + gif_ptr->gce_ptr->delay_time = + _GetWord_LSBFirst((uint8_t*)&gif_gce_ptr->delay_time); + gif_ptr->gce_ptr->trans_index = gif_gce_ptr->trans_index; + } break; +#endif + default: { +#ifndef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + if (gif_ptr->decode_status == GIF_D_STATUS_EXT_PTE) { +#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION + if (gif_ptr->gce_ptr != NULL) { + FX_Free(gif_ptr->gce_ptr); + gif_ptr->gce_ptr = NULL; + } +#endif + } +#endif + if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + return 2; + } + while (*data_size_ptr != GIF_BLOCK_TERMINAL) { + if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL || + _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + gif_ptr->skip_size = skip_size_org; + return 2; + } + } + } + } + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG); + return 1; +} +int32_t _gif_decode_image_info(gif_decompress_struct_p gif_ptr) { + if (gif_ptr->width == 0 || gif_ptr->height == 0) { + _gif_error(gif_ptr, "No Image Header Info"); + return 0; + } + FX_DWORD skip_size_org = gif_ptr->skip_size; + ASSERT(sizeof(GifImageInfo) == 9); + GifImageInfo* gif_img_info_ptr = NULL; + if (_gif_read_data(gif_ptr, (uint8_t**)&gif_img_info_ptr, 9) == NULL) { + return 2; + } + GifImage* gif_image_ptr = (GifImage*)FX_Alloc(uint8_t, sizeof(GifImage)); + GIF_PTR_NOT_NULL(gif_image_ptr, gif_ptr); + FXSYS_memset(gif_image_ptr, 0, sizeof(GifImage)); + gif_image_ptr->image_info_ptr = + (GifImageInfo*)FX_Alloc(uint8_t, sizeof(GifImageInfo)); + GIF_PTR_NOT_NULL(gif_image_ptr->image_info_ptr, gif_ptr); + gif_image_ptr->image_info_ptr->left = + _GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->left); + gif_image_ptr->image_info_ptr->top = + _GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->top); + gif_image_ptr->image_info_ptr->width = + _GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->width); + gif_image_ptr->image_info_ptr->height = + _GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->height); + gif_image_ptr->image_info_ptr->local_flag = gif_img_info_ptr->local_flag; + if (gif_image_ptr->image_info_ptr->left + + gif_image_ptr->image_info_ptr->width > + gif_ptr->width || + gif_image_ptr->image_info_ptr->top + + gif_image_ptr->image_info_ptr->height > + gif_ptr->height) { + if (gif_image_ptr->image_info_ptr != NULL) { + FX_Free(gif_image_ptr->image_info_ptr); + } + if (gif_image_ptr->image_row_buf != NULL) { + 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"); + return 0; + } + GifLF* gif_img_info_lf_ptr = (GifLF*)&gif_img_info_ptr->local_flag; + if (gif_img_info_lf_ptr->local_pal) { + ASSERT(sizeof(GifPalette) == 3); + int32_t loc_pal_size = (2 << gif_img_info_lf_ptr->pal_bits) * 3; + uint8_t* loc_pal_ptr = NULL; + if (_gif_read_data(gif_ptr, &loc_pal_ptr, loc_pal_size) == NULL) { + gif_ptr->skip_size = skip_size_org; + if (gif_image_ptr->image_info_ptr != NULL) { + FX_Free(gif_image_ptr->image_info_ptr); + } + if (gif_image_ptr->image_row_buf != NULL) { + FX_Free(gif_image_ptr->image_row_buf); + } + FX_Free(gif_image_ptr); + return 2; + } + gif_image_ptr->local_pal_ptr = + (GifPalette*)gif_ptr->_gif_ask_buf_for_pal_fn(gif_ptr, loc_pal_size); + if (gif_image_ptr->local_pal_ptr != NULL) { + FXSYS_memcpy((uint8_t*)gif_image_ptr->local_pal_ptr, loc_pal_ptr, + loc_pal_size); + } + } + uint8_t* code_size_ptr = NULL; + if (_gif_read_data(gif_ptr, &code_size_ptr, 1) == NULL) { + gif_ptr->skip_size = skip_size_org; + if (gif_image_ptr->image_info_ptr != NULL) { + FX_Free(gif_image_ptr->image_info_ptr); + } + if (gif_image_ptr->local_pal_ptr != NULL) { + FX_Free(gif_image_ptr->local_pal_ptr); + } + if (gif_image_ptr->image_row_buf != NULL) { + FX_Free(gif_image_ptr->image_row_buf); + } + FX_Free(gif_image_ptr); + return 2; + } + 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_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->Add(gif_image_ptr); + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA); + return 1; +} +int32_t _gif_load_frame(gif_decompress_struct_p gif_ptr, int32_t frame_num) { + if (gif_ptr == NULL || frame_num < 0 || + frame_num >= gif_ptr->img_ptr_arr_ptr->GetSize()) { + return 0; + } + uint8_t* data_size_ptr = NULL; + uint8_t* data_ptr = NULL; + FX_DWORD skip_size_org = gif_ptr->skip_size; + GifImage* gif_image_ptr = gif_ptr->img_ptr_arr_ptr->GetAt(frame_num); + FX_DWORD gif_img_row_bytes = gif_image_ptr->image_info_ptr->width; + if (gif_ptr->decode_status == GIF_D_STATUS_TAIL) { + if (gif_image_ptr->image_row_buf) { + FX_Free(gif_image_ptr->image_row_buf); + gif_image_ptr->image_row_buf = NULL; + } + gif_image_ptr->image_row_buf = FX_Alloc(uint8_t, gif_img_row_bytes); + GIF_PTR_NOT_NULL(gif_image_ptr->image_row_buf, gif_ptr); + GifGCE* gif_img_gce_ptr = gif_image_ptr->image_gce_ptr; + int32_t loc_pal_num = + ((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)->local_pal + ? (2 << ((GifLF*)&gif_image_ptr->image_info_ptr->local_flag) + ->pal_bits) + : 0; + gif_ptr->avail_in = 0; + if (gif_img_gce_ptr == NULL) { + FX_BOOL bRes = gif_ptr->_gif_get_record_position_fn( + gif_ptr, 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, + gif_image_ptr->local_pal_ptr, 0, 0, -1, 0, + (FX_BOOL)((GifLF*)&gif_image_ptr->image_info_ptr->local_flag) + ->interlace); + if (!bRes) { + FX_Free(gif_image_ptr->image_row_buf); + gif_image_ptr->image_row_buf = NULL; + _gif_error(gif_ptr, "Error Read Record Position Data"); + return 0; + } + } else { + FX_BOOL bRes = gif_ptr->_gif_get_record_position_fn( + gif_ptr, 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, + gif_image_ptr->local_pal_ptr, + (int32_t)gif_image_ptr->image_gce_ptr->delay_time, + (FX_BOOL)((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag) + ->user_input, + ((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag)->transparency + ? (int32_t)gif_image_ptr->image_gce_ptr->trans_index + : -1, + (int32_t)((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag) + ->disposal_method, + (FX_BOOL)((GifLF*)&gif_image_ptr->image_info_ptr->local_flag) + ->interlace); + if (!bRes) { + FX_Free(gif_image_ptr->image_row_buf); + gif_image_ptr->image_row_buf = NULL; + _gif_error(gif_ptr, "Error Read Record Position Data"); + return 0; + } + } + if (gif_ptr->img_decoder_ptr == NULL) { + gif_ptr->img_decoder_ptr = new CGifLZWDecoder(gif_ptr->err_ptr); + GIF_PTR_NOT_NULL(gif_ptr->img_decoder_ptr, gif_ptr); + } + gif_ptr->img_decoder_ptr->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; + if (gif_ptr->decode_status == GIF_D_STATUS_IMG_DATA) { + if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + return 2; + } + if (*data_size_ptr != GIF_BLOCK_TERMINAL) { + if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL) { + gif_ptr->skip_size = skip_size_org; + return 2; + } + img_decoder_ptr->Input(data_ptr, *data_size_ptr); + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA); + gif_ptr->img_row_offset += gif_ptr->img_row_avail_size; + gif_ptr->img_row_avail_size = gif_img_row_bytes - gif_ptr->img_row_offset; + int32_t ret = img_decoder_ptr->Decode( + gif_image_ptr->image_row_buf + gif_ptr->img_row_offset, + gif_ptr->img_row_avail_size); + if (ret == 0) { + FX_Free(gif_image_ptr->image_row_buf); + gif_image_ptr->image_row_buf = NULL; + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); + _gif_error(gif_ptr, "Decode Image Data Error"); + return 0; + } + while (ret != 0) { + if (ret == 1) { + gif_ptr->_gif_get_row_fn(gif_ptr, 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 = NULL; + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); + return 1; + } + if (ret == 2) { + ASSERT(img_decoder_ptr->GetAvailInput() == 0); + skip_size_org = gif_ptr->skip_size; + if (_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) { + return 2; + } + if (*data_size_ptr != GIF_BLOCK_TERMINAL) { + if (_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL) { + gif_ptr->skip_size = skip_size_org; + return 2; + } + img_decoder_ptr->Input(data_ptr, *data_size_ptr); + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA); + gif_ptr->img_row_offset += gif_ptr->img_row_avail_size; + gif_ptr->img_row_avail_size = + gif_img_row_bytes - gif_ptr->img_row_offset; + ret = img_decoder_ptr->Decode( + gif_image_ptr->image_row_buf + gif_ptr->img_row_offset, + gif_ptr->img_row_avail_size); + } + } + if (ret == 3) { + 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_image_ptr->image_row_num += + s_gif_interlace_step[gif_ptr->img_pass_num]; + if (gif_image_ptr->image_row_num >= + (int32_t)gif_image_ptr->image_info_ptr->height) { + gif_ptr->img_pass_num++; + gif_image_ptr->image_row_num = + 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->img_row_offset = 0; + gif_ptr->img_row_avail_size = gif_img_row_bytes; + ret = img_decoder_ptr->Decode( + gif_image_ptr->image_row_buf + gif_ptr->img_row_offset, + gif_ptr->img_row_avail_size); + } + if (ret == 0) { + FX_Free(gif_image_ptr->image_row_buf); + gif_image_ptr->image_row_buf = NULL; + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); + _gif_error(gif_ptr, "Decode Image Data Error"); + return 0; + } + } + } + _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL); + } + _gif_error(gif_ptr, "Decode Image Data Error"); + return 0; +} +void _gif_save_decoding_status(gif_decompress_struct_p 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; +} +uint8_t* _gif_read_data(gif_decompress_struct_p gif_ptr, + uint8_t** des_buf_pp, + FX_DWORD data_size) { + if (gif_ptr == NULL || gif_ptr->avail_in < gif_ptr->skip_size + data_size) { + return NULL; + } + *des_buf_pp = gif_ptr->next_in + gif_ptr->skip_size; + gif_ptr->skip_size += data_size; + return *des_buf_pp; +} +void _gif_input_buffer(gif_decompress_struct_p gif_ptr, + uint8_t* src_buf, + FX_DWORD src_size) { + gif_ptr->next_in = src_buf; + gif_ptr->avail_in = src_size; + gif_ptr->skip_size = 0; +} +FX_DWORD _gif_get_avail_input(gif_decompress_struct_p gif_ptr, + uint8_t** avial_buf_ptr) { + if (avial_buf_ptr != NULL) { + *avial_buf_ptr = NULL; + if (gif_ptr->avail_in > 0) { + *avial_buf_ptr = gif_ptr->next_in; + } + } + return gif_ptr->avail_in; +} +int32_t _gif_get_frame_num(gif_decompress_struct_p gif_ptr) { + return gif_ptr->img_ptr_arr_ptr->GetSize(); +} +static FX_BOOL _gif_write_header(gif_compress_struct_p gif_ptr, + uint8_t*& dst_buf, + FX_DWORD& dst_len) { + if (gif_ptr->cur_offset) { + return TRUE; + } + dst_len = sizeof(GifHeader) + sizeof(GifLSD) + sizeof(GifGF); + dst_buf = FX_TryAlloc(uint8_t, dst_len); + if (dst_buf == NULL) { + return FALSE; + } + FXSYS_memset(dst_buf, 0, dst_len); + FXSYS_memcpy(dst_buf, gif_ptr->header_ptr, sizeof(GifHeader)); + gif_ptr->cur_offset += sizeof(GifHeader); + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->width); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->height); + gif_ptr->cur_offset += 2; + dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->global_flag; + dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->bc_index; + dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->pixel_aspect; + if (gif_ptr->global_pal) { + FX_WORD size = sizeof(GifPalette) * gif_ptr->gpal_num; + if (!_gif_grow_buf(dst_buf, dst_len, gif_ptr->cur_offset + size)) { + return FALSE; + } + FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->global_pal, size); + gif_ptr->cur_offset += size; + } + return TRUE; +} +void interlace_buf(const uint8_t* buf, FX_DWORD pitch, FX_DWORD height) { + CFX_ArrayTemplate pass[4]; + int i, j; + FX_DWORD row; + row = 0; + uint8_t* temp; + while (row < height) { + if (row % 8 == 0) { + j = 0; + } else if (row % 4 == 0) { + j = 1; + } else if (row % 2 == 0) { + j = 2; + } else { + j = 3; + } + temp = FX_Alloc(uint8_t, pitch); + if (temp == NULL) { + return; + } + FXSYS_memcpy(temp, &buf[pitch * row], pitch); + pass[j].Add(temp); + row++; + } + for (i = 0, row = 0; i < 4; i++) { + for (j = 0; j < pass[i].GetSize(); j++, row++) { + FXSYS_memcpy((uint8_t*)&buf[pitch * row], pass[i].GetAt(j), pitch); + FX_Free(pass[i].GetAt(j)); + } + } +} +static void _gif_write_block_data(const uint8_t* src_buf, + FX_DWORD src_len, + uint8_t*& dst_buf, + FX_DWORD& dst_len, + FX_DWORD& dst_offset) { + FX_DWORD src_offset = 0; + while (src_len > GIF_DATA_BLOCK) { + dst_buf[dst_offset++] = GIF_DATA_BLOCK; + FXSYS_memcpy(&dst_buf[dst_offset], &src_buf[src_offset], GIF_DATA_BLOCK); + dst_offset += GIF_DATA_BLOCK; + src_offset += GIF_DATA_BLOCK; + src_len -= GIF_DATA_BLOCK; + } + dst_buf[dst_offset++] = (uint8_t)src_len; + FXSYS_memcpy(&dst_buf[dst_offset], &src_buf[src_offset], src_len); + dst_offset += src_len; +} +static FX_BOOL _gif_write_data(gif_compress_struct_p gif_ptr, + uint8_t*& dst_buf, + FX_DWORD& dst_len) { + if (!_gif_grow_buf(dst_buf, dst_len, gif_ptr->cur_offset + GIF_DATA_BLOCK)) { + return FALSE; + } +#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION + if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0) { + dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION; + dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_GCE; + gif_ptr->gce_ptr->block_size = 4; + dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->block_size; + gif_ptr->gce_ptr->gce_flag = 0; + dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->gce_flag; + gif_ptr->gce_ptr->delay_time = 10; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->gce_ptr->delay_time); + gif_ptr->cur_offset += 2; + gif_ptr->gce_ptr->trans_index = 0; + dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->trans_index; + dst_buf[gif_ptr->cur_offset++] = 0; + } +#endif + dst_buf[gif_ptr->cur_offset++] = GIF_SIG_IMAGE; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->image_info_ptr->left); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->image_info_ptr->top); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->image_info_ptr->width); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->image_info_ptr->height); + gif_ptr->cur_offset += 2; + GifLF& lf = (GifLF&)gif_ptr->image_info_ptr->local_flag; + dst_buf[gif_ptr->cur_offset++] = gif_ptr->image_info_ptr->local_flag; + if (gif_ptr->local_pal) { + FX_DWORD pal_size = sizeof(GifPalette) * gif_ptr->lpal_num; + if (!_gif_grow_buf(dst_buf, dst_len, pal_size + gif_ptr->cur_offset)) { + return FALSE; + } + FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->local_pal, pal_size); + gif_ptr->cur_offset += pal_size; + } + if (lf.interlace) { + interlace_buf(gif_ptr->src_buf, gif_ptr->src_pitch, + gif_ptr->image_info_ptr->height); + } + uint8_t code_bit = lf.pal_bits; + if (lf.local_pal == 0) { + GifGF& gf = (GifGF&)gif_ptr->lsd_ptr->global_flag; + code_bit = gf.pal_bits; + } + gif_ptr->img_encoder_ptr->Start(code_bit, gif_ptr->src_buf, dst_buf, + gif_ptr->cur_offset); + FX_DWORD i; + for (i = 0; i < gif_ptr->src_row; i++) { + if (!gif_ptr->img_encoder_ptr->Encode( + &gif_ptr->src_buf[i * gif_ptr->src_pitch], + gif_ptr->src_width * (code_bit + 1), dst_buf, dst_len, + gif_ptr->cur_offset)) { + return FALSE; + } + } + gif_ptr->img_encoder_ptr->Finish(dst_buf, dst_len, gif_ptr->cur_offset); + dst_buf[gif_ptr->cur_offset++] = 0; +#ifdef GIF_SUPPORT_COMMENT_EXTENSION + if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0 && + gif_ptr->cmt_data_ptr) { + dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION; + dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_CE; + _gif_write_block_data(gif_ptr->cmt_data_ptr, gif_ptr->cmt_data_len, dst_buf, + dst_len, gif_ptr->cur_offset); + dst_buf[gif_ptr->cur_offset++] = 0; + } +#endif +#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0 && + gif_ptr->pte_data_ptr) { + dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION; + dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_PTE; + dst_buf[gif_ptr->cur_offset++] = gif_ptr->pte_ptr->block_size; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->pte_ptr->grid_left); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->pte_ptr->grid_top); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->pte_ptr->grid_width); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->pte_ptr->grid_height); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->pte_ptr->char_width); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->pte_ptr->char_height); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->pte_ptr->fc_index); + gif_ptr->cur_offset += 2; + _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, + gif_ptr->pte_ptr->bc_index); + gif_ptr->cur_offset += 2; + _gif_write_block_data(gif_ptr->pte_data_ptr, gif_ptr->pte_data_len, dst_buf, + dst_len, gif_ptr->cur_offset); + gif_ptr->cur_offset += gif_ptr->pte_data_len; + dst_buf[gif_ptr->cur_offset++] = 0; + } +#endif +#ifdef GIF_SUPPORT_APPLICATION_EXTENSION + if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0 && + gif_ptr->app_data) { + dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION; + dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_AE; + dst_buf[gif_ptr->cur_offset++] = 11; + FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->app_identify, 8); + gif_ptr->cur_offset += 8; + FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->app_authentication, 8); + gif_ptr->cur_offset += 3; + FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->app_data, + gif_ptr->app_data_size); + gif_ptr->cur_offset += gif_ptr->app_data_size; + dst_buf[gif_ptr->cur_offset++] = 0; + } +#endif + dst_buf[gif_ptr->cur_offset++] = GIF_SIG_TRAILER; + return TRUE; +} +FX_BOOL _gif_encode(gif_compress_struct_p gif_ptr, + uint8_t*& dst_buf, + FX_DWORD& dst_len) { + if (!_gif_write_header(gif_ptr, dst_buf, dst_len)) { + return FALSE; + } + FX_DWORD cur_offset = gif_ptr->cur_offset; + FX_BOOL res = TRUE; + if (gif_ptr->frames) { + gif_ptr->cur_offset--; + } + if (!_gif_write_data(gif_ptr, dst_buf, dst_len)) { + gif_ptr->cur_offset = cur_offset; + res = FALSE; + } + dst_len = gif_ptr->cur_offset; + dst_buf[dst_len - 1] = GIF_SIG_TRAILER; + if (res) { + gif_ptr->frames++; + } + return res; +} diff --git a/core/src/fxcodec/lgif/fx_gif.h b/core/src/fxcodec/lgif/fx_gif.h index 8b2acc86ae..3b4ec0f0e6 100644 --- a/core/src/fxcodec/lgif/fx_gif.h +++ b/core/src/fxcodec/lgif/fx_gif.h @@ -1,332 +1,332 @@ -// 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/include/fxcrt/fx_basic.h" - -extern FX_WORD _GetWord_LSBFirst(uint8_t* p); -extern void _SetWord_LSBFirst(uint8_t* p, FX_WORD v); -extern void _BpcConvert(const uint8_t* src_buf, - FX_DWORD src_len, - int32_t src_bpc, - int32_t dst_bpc, - uint8_t*& dst_buf, - FX_DWORD& dst_len); -#define GIF_SUPPORT_COMMENT_EXTENSION -#define GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION -#define GIF_SUPPORT_PLAIN_TEXT_EXTENSION -#define GIF_SIGNATURE "GIF" -#define GIF_SIG_EXTENSION 0x21 -#define GIF_SIG_IMAGE 0x2C -#define GIF_SIG_TRAILER 0x3B -#define GIF_BLOCK_GCE 0xF9 -#define GIF_BLOCK_PTE 0x01 -#define GIF_BLOCK_CE 0xFE -#define GIF_BLOCK_AE 0xFF -#define GIF_BLOCK_TERMINAL 0x00 -#define GIF_MAX_LZW_CODE 4096 -#define GIF_DATA_BLOCK 255 -#define GIF_MAX_ERROR_SIZE 256 -#define GIF_D_STATUS_SIG 0x01 -#define GIF_D_STATUS_TAIL 0x02 -#define GIF_D_STATUS_EXT 0x03 -#define GIF_D_STATUS_EXT_AE 0x04 -#define GIF_D_STATUS_EXT_CE 0x05 -#define GIF_D_STATUS_EXT_GCE 0x06 -#define GIF_D_STATUS_EXT_PTE 0x07 -#define GIF_D_STATUS_EXT_UNE 0x08 -#define GIF_D_STATUS_IMG_INFO 0x09 -#define GIF_D_STATUS_IMG_DATA 0x0A -#pragma pack(1) -typedef struct tagGifGF { - uint8_t pal_bits : 3; - uint8_t sort_flag : 1; - uint8_t color_resolution : 3; - uint8_t global_pal : 1; -} GifGF; -typedef struct tagGifLF { - uint8_t pal_bits : 3; - uint8_t reserved : 2; - uint8_t sort_flag : 1; - uint8_t interlace : 1; - uint8_t local_pal : 1; -} GifLF; -typedef struct tagGifHeader { - char signature[3]; - char version[3]; -} GifHeader; -typedef struct tagGifLSD { - FX_WORD width; - FX_WORD height; - uint8_t global_flag; - uint8_t bc_index; - uint8_t pixel_aspect; -} GifLSD; -typedef struct tagGifImageInfo { - FX_WORD left; - FX_WORD top; - FX_WORD width; - FX_WORD height; - - uint8_t local_flag; -} GifImageInfo; -typedef struct tagGifCEF { - uint8_t transparency : 1; - uint8_t user_input : 1; - uint8_t disposal_method : 3; - uint8_t reserved : 3; -} GifCEF; -typedef struct tagGifGCE { - uint8_t block_size; - uint8_t gce_flag; - FX_WORD delay_time; - uint8_t trans_index; -} GifGCE; -typedef struct tagGifPTE { - uint8_t block_size; - FX_WORD grid_left; - FX_WORD grid_top; - FX_WORD grid_width; - FX_WORD grid_height; - - uint8_t char_width; - uint8_t char_height; - - uint8_t fc_index; - uint8_t bc_index; -} GifPTE; -typedef struct tagGifAE { - uint8_t block_size; - uint8_t app_identify[8]; - uint8_t app_authentication[3]; -} GifAE; -typedef struct tagGifPalette { uint8_t r, g, b; } GifPalette; -#pragma pack() -typedef struct tagGifImage { - GifGCE* image_gce_ptr; - GifPalette* local_pal_ptr; - GifImageInfo* image_info_ptr; - uint8_t image_code_size; - FX_DWORD image_data_pos; - uint8_t* image_row_buf; - int32_t image_row_num; -} GifImage; -typedef struct tagGifPlainText { - GifGCE* gce_ptr; - GifPTE* pte_ptr; - CFX_ByteString* string_ptr; -} GifPlainText; -class CGifLZWDecoder { - public: - struct tag_Table { - FX_WORD prefix; - uint8_t suffix; - }; - CGifLZWDecoder(FX_CHAR* error_ptr = NULL) { err_msg_ptr = error_ptr; } - void InitTable(uint8_t code_len); - - int32_t Decode(uint8_t* des_buf, FX_DWORD& des_size); - - void Input(uint8_t* src_buf, FX_DWORD src_size); - FX_DWORD GetAvailInput(); - - private: - void ClearTable(); - void AddCode(FX_WORD prefix_code, uint8_t append_char); - void DecodeString(FX_WORD code); - uint8_t code_size; - uint8_t code_size_cur; - FX_WORD code_clear; - FX_WORD code_end; - FX_WORD code_next; - uint8_t code_first; - uint8_t stack[GIF_MAX_LZW_CODE]; - FX_WORD stack_size; - tag_Table code_table[GIF_MAX_LZW_CODE]; - FX_WORD code_old; - - uint8_t* next_in; - FX_DWORD avail_in; - - uint8_t bits_left; - FX_DWORD code_store; - - FX_CHAR* err_msg_ptr; -}; -class CGifLZWEncoder { - public: - struct tag_Table { - FX_WORD prefix; - uint8_t suffix; - }; - CGifLZWEncoder(); - ~CGifLZWEncoder(); - void Start(uint8_t code_len, - const uint8_t* src_buf, - uint8_t*& dst_buf, - FX_DWORD& offset); - FX_BOOL Encode(const uint8_t* src_buf, - FX_DWORD src_len, - uint8_t*& dst_buf, - FX_DWORD& dst_len, - FX_DWORD& offset); - void Finish(uint8_t*& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset); - - private: - void ClearTable(); - FX_BOOL LookUpInTable(const uint8_t* buf, - FX_DWORD& offset, - uint8_t& bit_offset); - void EncodeString(FX_DWORD index, - uint8_t*& dst_buf, - FX_DWORD& dst_len, - FX_DWORD& offset); - void WriteBlock(uint8_t*& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset); - jmp_buf jmp; - FX_DWORD src_offset; - uint8_t src_bit_offset; - uint8_t src_bit_cut; - FX_DWORD src_bit_num; - uint8_t code_size; - FX_WORD code_clear; - FX_WORD code_end; - FX_WORD index_num; - uint8_t bit_offset; - uint8_t index_bit_cur; - uint8_t index_buf[GIF_DATA_BLOCK]; - uint8_t index_buf_len; - tag_Table code_table[GIF_MAX_LZW_CODE]; - FX_WORD table_cur; -}; -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 int32_t s_gif_interlace_step[4] = {8, 8, 4, 2}; -struct tag_gif_decompress_struct { - jmp_buf jmpbuf; - FX_CHAR* err_ptr; - void (*_gif_error_fn)(gif_decompress_struct_p gif_ptr, - const FX_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; - FX_DWORD img_row_offset; - FX_DWORD img_row_avail_size; - uint8_t img_pass_num; - CFX_ArrayTemplate* 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; - FX_DWORD avail_in; - int32_t decode_status; - FX_DWORD skip_size; - void (*_gif_record_current_position_fn)(gif_decompress_struct_p gif_ptr, - FX_DWORD* cur_pos_ptr); - void (*_gif_get_row_fn)(gif_decompress_struct_p gif_ptr, - int32_t row_num, - uint8_t* row_buf); - FX_BOOL (*_gif_get_record_position_fn)(gif_decompress_struct_p gif_ptr, FX_DWORD 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, FX_BOOL user_input, - int32_t trans_index, int32_t disposal_method, FX_BOOL interlace); -#ifdef GIF_SUPPORT_APPLICATION_EXTENSION - uint8_t app_identify[8]; - uint8_t app_authentication[3]; - FX_DWORD app_data_size; - uint8_t* app_data; -#endif -#ifdef GIF_SUPPORT_COMMENT_EXTENSION - CFX_ByteString* cmt_data_ptr; -#endif -#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION - GifGCE* gce_ptr; -#endif -#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - CFX_ArrayTemplate* pt_ptr_arr_ptr; -#endif -}; -typedef struct tag_gif_compress_struct gif_compress_struct; -typedef gif_compress_struct* gif_compress_struct_p; -typedef gif_compress_struct_p* gif_compress_struct_pp; -struct tag_gif_compress_struct { - const uint8_t* src_buf; - FX_DWORD src_pitch; - FX_DWORD src_width; - FX_DWORD src_row; - FX_DWORD cur_offset; - FX_DWORD frames; - GifHeader* header_ptr; - GifLSD* lsd_ptr; - GifPalette* global_pal; - FX_WORD gpal_num; - GifPalette* local_pal; - FX_WORD lpal_num; - GifImageInfo* image_info_ptr; - CGifLZWEncoder* img_encoder_ptr; -#ifdef GIF_SUPPORT_APPLICATION_EXTENSION - uint8_t app_identify[8]; - uint8_t app_authentication[3]; - FX_DWORD app_data_size; - uint8_t* app_data; -#endif - -#ifdef GIF_SUPPORT_COMMENT_EXTENSION - uint8_t* cmt_data_ptr; - FX_DWORD cmt_data_len; -#endif - -#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION - GifGCE* gce_ptr; -#endif - -#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION - GifPTE* pte_ptr; - const uint8_t* pte_data_ptr; - FX_DWORD pte_data_len; -#endif -}; -void _gif_error(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg); -void _gif_warn(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg); -gif_decompress_struct_p _gif_create_decompress(); -void _gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr); -gif_compress_struct_p _gif_create_compress(); -void _gif_destroy_compress(gif_compress_struct_pp gif_ptr_ptr); -int32_t _gif_read_header(gif_decompress_struct_p gif_ptr); -int32_t _gif_get_frame(gif_decompress_struct_p gif_ptr); -int32_t _gif_get_frame_num(gif_decompress_struct_p gif_ptr); -int32_t _gif_decode_extension(gif_decompress_struct_p gif_ptr); -int32_t _gif_decode_image_info(gif_decompress_struct_p gif_ptr); -void _gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr, - GifGCE** gce_ptr_ptr); -int32_t _gif_load_frame(gif_decompress_struct_p gif_ptr, int32_t frame_num); -uint8_t* _gif_read_data(gif_decompress_struct_p gif_ptr, - uint8_t** des_buf_pp, - FX_DWORD data_size); -void _gif_save_decoding_status(gif_decompress_struct_p gif_ptr, int32_t status); -void _gif_input_buffer(gif_decompress_struct_p gif_ptr, - uint8_t* src_buf, - FX_DWORD src_size); -FX_DWORD _gif_get_avail_input(gif_decompress_struct_p gif_ptr, - uint8_t** avial_buf_ptr); -void interlace_buf(const uint8_t* buf, FX_DWORD width, FX_DWORD height); -FX_BOOL _gif_encode(gif_compress_struct_p gif_ptr, - uint8_t*& dst_buf, - FX_DWORD& dst_len); -#define GIF_PTR_NOT_NULL(ptr, gif_ptr) \ - if (ptr == NULL) { \ - _gif_error(gif_ptr, "Out Of Memory"); \ - return 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/include/fxcrt/fx_basic.h" + +extern FX_WORD _GetWord_LSBFirst(uint8_t* p); +extern void _SetWord_LSBFirst(uint8_t* p, FX_WORD v); +extern void _BpcConvert(const uint8_t* src_buf, + FX_DWORD src_len, + int32_t src_bpc, + int32_t dst_bpc, + uint8_t*& dst_buf, + FX_DWORD& dst_len); +#define GIF_SUPPORT_COMMENT_EXTENSION +#define GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION +#define GIF_SUPPORT_PLAIN_TEXT_EXTENSION +#define GIF_SIGNATURE "GIF" +#define GIF_SIG_EXTENSION 0x21 +#define GIF_SIG_IMAGE 0x2C +#define GIF_SIG_TRAILER 0x3B +#define GIF_BLOCK_GCE 0xF9 +#define GIF_BLOCK_PTE 0x01 +#define GIF_BLOCK_CE 0xFE +#define GIF_BLOCK_AE 0xFF +#define GIF_BLOCK_TERMINAL 0x00 +#define GIF_MAX_LZW_CODE 4096 +#define GIF_DATA_BLOCK 255 +#define GIF_MAX_ERROR_SIZE 256 +#define GIF_D_STATUS_SIG 0x01 +#define GIF_D_STATUS_TAIL 0x02 +#define GIF_D_STATUS_EXT 0x03 +#define GIF_D_STATUS_EXT_AE 0x04 +#define GIF_D_STATUS_EXT_CE 0x05 +#define GIF_D_STATUS_EXT_GCE 0x06 +#define GIF_D_STATUS_EXT_PTE 0x07 +#define GIF_D_STATUS_EXT_UNE 0x08 +#define GIF_D_STATUS_IMG_INFO 0x09 +#define GIF_D_STATUS_IMG_DATA 0x0A +#pragma pack(1) +typedef struct tagGifGF { + uint8_t pal_bits : 3; + uint8_t sort_flag : 1; + uint8_t color_resolution : 3; + uint8_t global_pal : 1; +} GifGF; +typedef struct tagGifLF { + uint8_t pal_bits : 3; + uint8_t reserved : 2; + uint8_t sort_flag : 1; + uint8_t interlace : 1; + uint8_t local_pal : 1; +} GifLF; +typedef struct tagGifHeader { + char signature[3]; + char version[3]; +} GifHeader; +typedef struct tagGifLSD { + FX_WORD width; + FX_WORD height; + uint8_t global_flag; + uint8_t bc_index; + uint8_t pixel_aspect; +} GifLSD; +typedef struct tagGifImageInfo { + FX_WORD left; + FX_WORD top; + FX_WORD width; + FX_WORD height; + + uint8_t local_flag; +} GifImageInfo; +typedef struct tagGifCEF { + uint8_t transparency : 1; + uint8_t user_input : 1; + uint8_t disposal_method : 3; + uint8_t reserved : 3; +} GifCEF; +typedef struct tagGifGCE { + uint8_t block_size; + uint8_t gce_flag; + FX_WORD delay_time; + uint8_t trans_index; +} GifGCE; +typedef struct tagGifPTE { + uint8_t block_size; + FX_WORD grid_left; + FX_WORD grid_top; + FX_WORD grid_width; + FX_WORD grid_height; + + uint8_t char_width; + uint8_t char_height; + + uint8_t fc_index; + uint8_t bc_index; +} GifPTE; +typedef struct tagGifAE { + uint8_t block_size; + uint8_t app_identify[8]; + uint8_t app_authentication[3]; +} GifAE; +typedef struct tagGifPalette { uint8_t r, g, b; } GifPalette; +#pragma pack() +typedef struct tagGifImage { + GifGCE* image_gce_ptr; + GifPalette* local_pal_ptr; + GifImageInfo* image_info_ptr; + uint8_t image_code_size; + FX_DWORD image_data_pos; + uint8_t* image_row_buf; + int32_t image_row_num; +} GifImage; +typedef struct tagGifPlainText { + GifGCE* gce_ptr; + GifPTE* pte_ptr; + CFX_ByteString* string_ptr; +} GifPlainText; +class CGifLZWDecoder { + public: + struct tag_Table { + FX_WORD prefix; + uint8_t suffix; + }; + CGifLZWDecoder(FX_CHAR* error_ptr = NULL) { err_msg_ptr = error_ptr; } + void InitTable(uint8_t code_len); + + int32_t Decode(uint8_t* des_buf, FX_DWORD& des_size); + + void Input(uint8_t* src_buf, FX_DWORD src_size); + FX_DWORD GetAvailInput(); + + private: + void ClearTable(); + void AddCode(FX_WORD prefix_code, uint8_t append_char); + void DecodeString(FX_WORD code); + uint8_t code_size; + uint8_t code_size_cur; + FX_WORD code_clear; + FX_WORD code_end; + FX_WORD code_next; + uint8_t code_first; + uint8_t stack[GIF_MAX_LZW_CODE]; + FX_WORD stack_size; + tag_Table code_table[GIF_MAX_LZW_CODE]; + FX_WORD code_old; + + uint8_t* next_in; + FX_DWORD avail_in; + + uint8_t bits_left; + FX_DWORD code_store; + + FX_CHAR* err_msg_ptr; +}; +class CGifLZWEncoder { + public: + struct tag_Table { + FX_WORD prefix; + uint8_t suffix; + }; + CGifLZWEncoder(); + ~CGifLZWEncoder(); + void Start(uint8_t code_len, + const uint8_t* src_buf, + uint8_t*& dst_buf, + FX_DWORD& offset); + FX_BOOL Encode(const uint8_t* src_buf, + FX_DWORD src_len, + uint8_t*& dst_buf, + FX_DWORD& dst_len, + FX_DWORD& offset); + void Finish(uint8_t*& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset); + + private: + void ClearTable(); + FX_BOOL LookUpInTable(const uint8_t* buf, + FX_DWORD& offset, + uint8_t& bit_offset); + void EncodeString(FX_DWORD index, + uint8_t*& dst_buf, + FX_DWORD& dst_len, + FX_DWORD& offset); + void WriteBlock(uint8_t*& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset); + jmp_buf jmp; + FX_DWORD src_offset; + uint8_t src_bit_offset; + uint8_t src_bit_cut; + FX_DWORD src_bit_num; + uint8_t code_size; + FX_WORD code_clear; + FX_WORD code_end; + FX_WORD index_num; + uint8_t bit_offset; + uint8_t index_bit_cur; + uint8_t index_buf[GIF_DATA_BLOCK]; + uint8_t index_buf_len; + tag_Table code_table[GIF_MAX_LZW_CODE]; + FX_WORD table_cur; +}; +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 int32_t s_gif_interlace_step[4] = {8, 8, 4, 2}; +struct tag_gif_decompress_struct { + jmp_buf jmpbuf; + FX_CHAR* err_ptr; + void (*_gif_error_fn)(gif_decompress_struct_p gif_ptr, + const FX_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; + FX_DWORD img_row_offset; + FX_DWORD img_row_avail_size; + uint8_t img_pass_num; + CFX_ArrayTemplate* 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; + FX_DWORD avail_in; + int32_t decode_status; + FX_DWORD skip_size; + void (*_gif_record_current_position_fn)(gif_decompress_struct_p gif_ptr, + FX_DWORD* cur_pos_ptr); + void (*_gif_get_row_fn)(gif_decompress_struct_p gif_ptr, + int32_t row_num, + uint8_t* row_buf); + FX_BOOL (*_gif_get_record_position_fn)(gif_decompress_struct_p gif_ptr, FX_DWORD 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, FX_BOOL user_input, + int32_t trans_index, int32_t disposal_method, FX_BOOL interlace); +#ifdef GIF_SUPPORT_APPLICATION_EXTENSION + uint8_t app_identify[8]; + uint8_t app_authentication[3]; + FX_DWORD app_data_size; + uint8_t* app_data; +#endif +#ifdef GIF_SUPPORT_COMMENT_EXTENSION + CFX_ByteString* cmt_data_ptr; +#endif +#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION + GifGCE* gce_ptr; +#endif +#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + CFX_ArrayTemplate* pt_ptr_arr_ptr; +#endif +}; +typedef struct tag_gif_compress_struct gif_compress_struct; +typedef gif_compress_struct* gif_compress_struct_p; +typedef gif_compress_struct_p* gif_compress_struct_pp; +struct tag_gif_compress_struct { + const uint8_t* src_buf; + FX_DWORD src_pitch; + FX_DWORD src_width; + FX_DWORD src_row; + FX_DWORD cur_offset; + FX_DWORD frames; + GifHeader* header_ptr; + GifLSD* lsd_ptr; + GifPalette* global_pal; + FX_WORD gpal_num; + GifPalette* local_pal; + FX_WORD lpal_num; + GifImageInfo* image_info_ptr; + CGifLZWEncoder* img_encoder_ptr; +#ifdef GIF_SUPPORT_APPLICATION_EXTENSION + uint8_t app_identify[8]; + uint8_t app_authentication[3]; + FX_DWORD app_data_size; + uint8_t* app_data; +#endif + +#ifdef GIF_SUPPORT_COMMENT_EXTENSION + uint8_t* cmt_data_ptr; + FX_DWORD cmt_data_len; +#endif + +#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION + GifGCE* gce_ptr; +#endif + +#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION + GifPTE* pte_ptr; + const uint8_t* pte_data_ptr; + FX_DWORD pte_data_len; +#endif +}; +void _gif_error(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg); +void _gif_warn(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg); +gif_decompress_struct_p _gif_create_decompress(); +void _gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr); +gif_compress_struct_p _gif_create_compress(); +void _gif_destroy_compress(gif_compress_struct_pp gif_ptr_ptr); +int32_t _gif_read_header(gif_decompress_struct_p gif_ptr); +int32_t _gif_get_frame(gif_decompress_struct_p gif_ptr); +int32_t _gif_get_frame_num(gif_decompress_struct_p gif_ptr); +int32_t _gif_decode_extension(gif_decompress_struct_p gif_ptr); +int32_t _gif_decode_image_info(gif_decompress_struct_p gif_ptr); +void _gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr, + GifGCE** gce_ptr_ptr); +int32_t _gif_load_frame(gif_decompress_struct_p gif_ptr, int32_t frame_num); +uint8_t* _gif_read_data(gif_decompress_struct_p gif_ptr, + uint8_t** des_buf_pp, + FX_DWORD data_size); +void _gif_save_decoding_status(gif_decompress_struct_p gif_ptr, int32_t status); +void _gif_input_buffer(gif_decompress_struct_p gif_ptr, + uint8_t* src_buf, + FX_DWORD src_size); +FX_DWORD _gif_get_avail_input(gif_decompress_struct_p gif_ptr, + uint8_t** avial_buf_ptr); +void interlace_buf(const uint8_t* buf, FX_DWORD width, FX_DWORD height); +FX_BOOL _gif_encode(gif_compress_struct_p gif_ptr, + uint8_t*& dst_buf, + FX_DWORD& dst_len); +#define GIF_PTR_NOT_NULL(ptr, gif_ptr) \ + if (ptr == NULL) { \ + _gif_error(gif_ptr, "Out Of Memory"); \ + return 0; \ + } diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h index b25a9039ad..dd65042189 100644 --- a/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h +++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h @@ -1,97 +1,97 @@ -// 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 - -#ifndef FPDFXFA_APP_H_ -#define FPDFXFA_APP_H_ - -#include "xfa/include/fxfa/fxfa.h" - -class IFXJS_Runtime; - -class CPDFXFA_App : public IXFA_AppProvider { - public: - static CPDFXFA_App* GetInstance(); - static void ReleaseInstance(); - - CPDFXFA_App(); - ~CPDFXFA_App() override; - - FX_BOOL Initialize(); - IXFA_App* GetXFAApp() { return m_pXFAApp; } - - FX_BOOL AddFormFillEnv(CPDFDoc_Environment* pEnv); - FX_BOOL RemoveFormFillEnv(CPDFDoc_Environment* pEnv); - - FX_BOOL IsJavaScriptInitialized() const { return m_bJavaScriptInitialized; } - void SetJavaScriptInitialized(FX_BOOL bInitialized) { - m_bJavaScriptInitialized = bInitialized; - } - - FXJSE_HRUNTIME GetJSERuntime() const { return m_hJSERuntime; } - - // IFXA_AppProvider: - void GetAppType(CFX_WideString& wsAppType) override; - void SetAppType(const CFX_WideStringC& wsAppType) override; - - void GetLanguage(CFX_WideString& wsLanguage) override; - void GetPlatform(CFX_WideString& wsPlatform) override; - void GetVariation(CFX_WideString& wsVariation) override; - void GetVersion(CFX_WideString& wsVersion) override; - void GetFoxitVersion(CFX_WideString& wsFoxitVersion) override { - wsFoxitVersion = L"7.0"; - } - - void GetAppName(CFX_WideString& wsName) override; - void GetFoxitAppName(CFX_WideString& wsFoxitName) override { - wsFoxitName = L"Foxit"; - } - - void Beep(FX_DWORD dwType) override; - int32_t MsgBox(const CFX_WideStringC& wsMessage, - const CFX_WideStringC& wsTitle, - FX_DWORD dwIconType, - FX_DWORD dwButtonType) override; - void Response(CFX_WideString& wsAnswer, - const CFX_WideStringC& wsQuestion, - const CFX_WideStringC& wsTitle, - const CFX_WideStringC& wsDefaultAnswer, - FX_BOOL bMark) override; - - int32_t GetDocumentCountInBatch() override; - int32_t GetCurDocumentInBatch() override; - - IFX_FileRead* DownloadURL(const CFX_WideStringC& wsURL) override; - FX_BOOL PostRequestURL(const CFX_WideStringC& wsURL, - const CFX_WideStringC& wsData, - const CFX_WideStringC& wsContentType, - const CFX_WideStringC& wsEncode, - const CFX_WideStringC& wsHeader, - CFX_WideString& wsResponse) override; - FX_BOOL PutRequestURL(const CFX_WideStringC& wsURL, - const CFX_WideStringC& wsData, - const CFX_WideStringC& wsEncode) override; - - void LoadString(int32_t iStringID, CFX_WideString& wsString) override; - FX_BOOL ShowFileDialog(const CFX_WideStringC& wsTitle, - const CFX_WideStringC& wsFilter, - CFX_WideStringArray& wsPathArr, - FX_BOOL bOpen) override; - IFWL_AdapterTimerMgr* GetTimerMgr() override; - - CFX_ArrayTemplate m_pEnvList; - - protected: - static CPDFXFA_App* g_pApp; - - FX_BOOL m_bJavaScriptInitialized; - IXFA_App* m_pXFAApp; - IXFA_FontMgr* m_pFontMgr; - FXJSE_HRUNTIME m_hJSERuntime; - IFXJS_Runtime* m_pJSRuntime; - CFX_WideString m_csAppType; -}; - -#endif // FPDFXFA_APP_H_ +// 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 + +#ifndef FPDFXFA_APP_H_ +#define FPDFXFA_APP_H_ + +#include "xfa/include/fxfa/fxfa.h" + +class IFXJS_Runtime; + +class CPDFXFA_App : public IXFA_AppProvider { + public: + static CPDFXFA_App* GetInstance(); + static void ReleaseInstance(); + + CPDFXFA_App(); + ~CPDFXFA_App() override; + + FX_BOOL Initialize(); + IXFA_App* GetXFAApp() { return m_pXFAApp; } + + FX_BOOL AddFormFillEnv(CPDFDoc_Environment* pEnv); + FX_BOOL RemoveFormFillEnv(CPDFDoc_Environment* pEnv); + + FX_BOOL IsJavaScriptInitialized() const { return m_bJavaScriptInitialized; } + void SetJavaScriptInitialized(FX_BOOL bInitialized) { + m_bJavaScriptInitialized = bInitialized; + } + + FXJSE_HRUNTIME GetJSERuntime() const { return m_hJSERuntime; } + + // IFXA_AppProvider: + void GetAppType(CFX_WideString& wsAppType) override; + void SetAppType(const CFX_WideStringC& wsAppType) override; + + void GetLanguage(CFX_WideString& wsLanguage) override; + void GetPlatform(CFX_WideString& wsPlatform) override; + void GetVariation(CFX_WideString& wsVariation) override; + void GetVersion(CFX_WideString& wsVersion) override; + void GetFoxitVersion(CFX_WideString& wsFoxitVersion) override { + wsFoxitVersion = L"7.0"; + } + + void GetAppName(CFX_WideString& wsName) override; + void GetFoxitAppName(CFX_WideString& wsFoxitName) override { + wsFoxitName = L"Foxit"; + } + + void Beep(FX_DWORD dwType) override; + int32_t MsgBox(const CFX_WideStringC& wsMessage, + const CFX_WideStringC& wsTitle, + FX_DWORD dwIconType, + FX_DWORD dwButtonType) override; + void Response(CFX_WideString& wsAnswer, + const CFX_WideStringC& wsQuestion, + const CFX_WideStringC& wsTitle, + const CFX_WideStringC& wsDefaultAnswer, + FX_BOOL bMark) override; + + int32_t GetDocumentCountInBatch() override; + int32_t GetCurDocumentInBatch() override; + + IFX_FileRead* DownloadURL(const CFX_WideStringC& wsURL) override; + FX_BOOL PostRequestURL(const CFX_WideStringC& wsURL, + const CFX_WideStringC& wsData, + const CFX_WideStringC& wsContentType, + const CFX_WideStringC& wsEncode, + const CFX_WideStringC& wsHeader, + CFX_WideString& wsResponse) override; + FX_BOOL PutRequestURL(const CFX_WideStringC& wsURL, + const CFX_WideStringC& wsData, + const CFX_WideStringC& wsEncode) override; + + void LoadString(int32_t iStringID, CFX_WideString& wsString) override; + FX_BOOL ShowFileDialog(const CFX_WideStringC& wsTitle, + const CFX_WideStringC& wsFilter, + CFX_WideStringArray& wsPathArr, + FX_BOOL bOpen) override; + IFWL_AdapterTimerMgr* GetTimerMgr() override; + + CFX_ArrayTemplate m_pEnvList; + + protected: + static CPDFXFA_App* g_pApp; + + FX_BOOL m_bJavaScriptInitialized; + IXFA_App* m_pXFAApp; + IXFA_FontMgr* m_pFontMgr; + FXJSE_HRUNTIME m_hJSERuntime; + IFXJS_Runtime* m_pJSRuntime; + CFX_WideString m_csAppType; +}; + +#endif // FPDFXFA_APP_H_ diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h index 14b07c3059..64b3875629 100644 --- a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h +++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h @@ -1,228 +1,228 @@ -// 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 - -#ifndef FPDFXFA_DOC_H_ -#define FPDFXFA_DOC_H_ - -#include "public/fpdfview.h" -#include "xfa/include/fxfa/fxfa.h" - -class CPDFXFA_App; -class CPDFXFA_Document; -class CPDFXFA_Page; -class CPDFSDK_Document; -class CPDFDoc_Environment; -class IJS_Runtime; -class IJS_Context; -class IXFA_DocHandler; - -class CPDFXFA_Document : public IXFA_DocProvider { - public: - CPDFXFA_Document(CPDF_Document* pPDFDoc, CPDFXFA_App* pProvider); - ~CPDFXFA_Document(); - - FX_BOOL LoadXFADoc(); - CPDFXFA_App* GetApp() { return m_pApp; } - CPDF_Document* GetPDFDoc() { return m_pPDFDoc; } - IXFA_Doc* GetXFADoc() { return m_pXFADoc; } - IXFA_DocView* GetXFADocView() { return m_pXFADocView; } - - int GetPageCount(); - CPDFXFA_Page* GetPage(int page_index); - CPDFXFA_Page* GetPage(IXFA_PageView* pPage); - void RemovePage(CPDFXFA_Page* page); - int GetDocType() { return m_iDocType; } - - CPDFSDK_Document* GetSDKDocument(CPDFDoc_Environment* pFormFillEnv); - - void FXRect2PDFRect(const CFX_RectF& fxRectF, CPDF_Rect& pdfRect); - - virtual void SetChangeMark(IXFA_Doc* hDoc); - virtual FX_BOOL GetChangeMark(IXFA_Doc* hDoc); - // used in dynamic xfa, dwFlags refer to XFA_INVALIDATE_XXX macros. - virtual void InvalidateRect(IXFA_PageView* pPageView, - const CFX_RectF& rt, - FX_DWORD dwFlags = 0); - // used in static xfa, dwFlags refer to XFA_INVALIDATE_XXX macros. - virtual void InvalidateRect(IXFA_Widget* hWidget, FX_DWORD dwFlags = 0); - // show or hide caret - virtual void DisplayCaret(IXFA_Widget* hWidget, - FX_BOOL bVisible, - const CFX_RectF* pRtAnchor); - // dwPos: (0:bottom 1:top) - virtual FX_BOOL GetPopupPos(IXFA_Widget* hWidget, - FX_FLOAT fMinPopup, - FX_FLOAT fMaxPopup, - const CFX_RectF& rtAnchor, - CFX_RectF& rtPopup); - virtual FX_BOOL PopupMenu(IXFA_Widget* hWidget, - CFX_PointF ptPopup, - const CFX_RectF* pRectExclude = NULL); - - // dwFlags XFA_PAGEVIEWEVENT_Added, XFA_PAGEVIEWEVENT_Removing - virtual void PageViewEvent(IXFA_PageView* pPageView, FX_DWORD dwFlags); - // dwEvent refer to XFA_WIDGETEVENT_XXX - virtual void WidgetEvent(IXFA_Widget* hWidget, - CXFA_WidgetAcc* pWidgetData, - FX_DWORD dwEvent, - void* pParam = NULL, - void* pAdditional = NULL); - - // return true if render it. - virtual FX_BOOL RenderCustomWidget(IXFA_Widget* hWidget, - CFX_Graphics* pGS, - CFX_Matrix* pMatrix, - const CFX_RectF& rtUI) { - return FALSE; - } - - // host method - virtual int32_t CountPages(IXFA_Doc* hDoc); - virtual int32_t GetCurrentPage(IXFA_Doc* hDoc); - virtual void SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage); - virtual FX_BOOL IsCalculationsEnabled(IXFA_Doc* hDoc); - virtual void SetCalculationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled); - virtual void GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle); - virtual void SetTitle(IXFA_Doc* hDoc, const CFX_WideStringC& wsTitle); - virtual void ExportData(IXFA_Doc* hDoc, - const CFX_WideStringC& wsFilePath, - FX_BOOL bXDP = TRUE); - virtual void ImportData(IXFA_Doc* hDoc, const CFX_WideStringC& wsFilePath); - virtual void GotoURL(IXFA_Doc* hDoc, - const CFX_WideStringC& bsURL, - FX_BOOL bAppend = TRUE); - virtual FX_BOOL IsValidationsEnabled(IXFA_Doc* hDoc); - virtual void SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled); - virtual void SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget); - virtual void Print(IXFA_Doc* hDoc, - int32_t nStartPage, - int32_t nEndPage, - FX_DWORD dwOptions); - - // LayoutPseudo method - virtual int32_t AbsPageCountInBatch(IXFA_Doc* hDoc) { return 0; } - virtual int32_t AbsPageInBatch(IXFA_Doc* hDoc, IXFA_Widget* hWidget) { - return 0; - } - virtual int32_t SheetCountInBatch(IXFA_Doc* hDoc) { return 0; } - virtual int32_t SheetInBatch(IXFA_Doc* hDoc, IXFA_Widget* hWidget) { - return 0; - } - - // SignaturePseudoModel method - // TODO: - virtual int32_t Verify( - IXFA_Doc* hDoc, - CXFA_Node* pSigNode, - FX_BOOL - bUsed = TRUE /*, SecurityHandler* pHandler, SignatureInfo &info*/) { - return 0; - } - virtual FX_BOOL Sign( - IXFA_Doc* hDoc, - CXFA_NodeList* pNodeList, - const CFX_WideStringC& wsExpression, - const CFX_WideStringC& wsXMLIdent, - const CFX_WideStringC& wsValue = FX_WSTRC(L"open"), - FX_BOOL - bUsed = TRUE /*, SecurityHandler* pHandler = NULL, SignatureInfo &info*/) { - return 0; - } - virtual CXFA_NodeList* Enumerate(IXFA_Doc* hDoc) { return 0; } - virtual FX_BOOL Clear(IXFA_Doc* hDoc, - CXFA_Node* pSigNode, - FX_BOOL bCleared = TRUE) { - return 0; - } - - // Get document path - virtual void GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL); - virtual FX_ARGB GetHighlightColor(IXFA_Doc* hDoc); - - /** - *Submit data to email, http, ftp. - * @param[in] hDoc The document handler. - * @param[in] eFormat Determines the format in which the data will be - *submitted. XFA_ATTRIBUTEENUM_Xdp, XFA_ATTRIBUTEENUM_Xml... - * @param[in] wsTarget The URL to which the data will be submitted. - * @param[in] eEncoding The encoding of text content. - * @param[in] pXDPContent Controls what subset of the data is submitted, used - *only when the format property is xdp. - * @param[in] bEmbedPDF, specifies whether PDF is embedded in the submitted - *content or not. - */ - virtual FX_BOOL SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit); - - virtual FX_BOOL CheckWord(IXFA_Doc* hDoc, const CFX_ByteStringC& sWord) { - return FALSE; - } - virtual FX_BOOL GetSuggestWords(IXFA_Doc* hDoc, - const CFX_ByteStringC& sWord, - CFX_ByteStringArray& sSuggest) { - return FALSE; - } - - // Get PDF javascript object, set the object to hValue. - virtual FX_BOOL GetPDFScriptObject(IXFA_Doc* hDoc, - const CFX_ByteStringC& utf8Name, - FXJSE_HVALUE hValue); - - virtual FX_BOOL GetGlobalProperty(IXFA_Doc* hDoc, - const CFX_ByteStringC& szPropName, - FXJSE_HVALUE hValue); - virtual FX_BOOL SetGlobalProperty(IXFA_Doc* hDoc, - const CFX_ByteStringC& szPropName, - FXJSE_HVALUE hValue); - virtual CPDF_Document* OpenPDF(IXFA_Doc* hDoc, - IFX_FileRead* pFile, - FX_BOOL bTakeOverFile) { - return NULL; - } - - virtual IFX_FileRead* OpenLinkedFile(IXFA_Doc* hDoc, - const CFX_WideString& wsLink); - - FX_BOOL _GetHValueByName(const CFX_ByteStringC& utf8Name, - FXJSE_HVALUE hValue, - IJS_Runtime* runTime); - FX_BOOL _OnBeforeNotifySumbit(); - void _OnAfterNotifySumbit(); - FX_BOOL _NotifySubmit(FX_BOOL bPrevOrPost); - FX_BOOL _SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit); - FX_BOOL _MailToInfo(CFX_WideString& csURL, - CFX_WideString& csToAddress, - CFX_WideString& csCCAddress, - CFX_WideString& csBCCAddress, - CFX_WideString& csSubject, - CFX_WideString& csMsg); - FX_BOOL _ExportSubmitFile(FPDF_FILEHANDLER* ppFileHandler, - int fileType, - FPDF_DWORD encodeType, - FPDF_DWORD flag = 0x01111111); - void _ToXFAContentFlags(CFX_WideString csSrcContent, FPDF_DWORD& flag); - void _ClearChangeMark(); - - private: - void CloseXFADoc(IXFA_DocHandler* pDoc) { - if (pDoc) { - pDoc->CloseDoc(m_pXFADoc); - pDoc->ReleaseDoc(m_pXFADoc); - m_pXFADoc = NULL; - m_pXFADocView = NULL; - } - } - - int m_iDocType; - CPDF_Document* m_pPDFDoc; - CPDFSDK_Document* m_pSDKDoc; - IXFA_Doc* m_pXFADoc; - IXFA_DocView* m_pXFADocView; - CPDFXFA_App* m_pApp; - IJS_Context* m_pJSContext; - CFX_ArrayTemplate m_XFAPageList; -}; - -#endif // FPDFXFA_DOC_H_ +// 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 + +#ifndef FPDFXFA_DOC_H_ +#define FPDFXFA_DOC_H_ + +#include "public/fpdfview.h" +#include "xfa/include/fxfa/fxfa.h" + +class CPDFXFA_App; +class CPDFXFA_Document; +class CPDFXFA_Page; +class CPDFSDK_Document; +class CPDFDoc_Environment; +class IJS_Runtime; +class IJS_Context; +class IXFA_DocHandler; + +class CPDFXFA_Document : public IXFA_DocProvider { + public: + CPDFXFA_Document(CPDF_Document* pPDFDoc, CPDFXFA_App* pProvider); + ~CPDFXFA_Document(); + + FX_BOOL LoadXFADoc(); + CPDFXFA_App* GetApp() { return m_pApp; } + CPDF_Document* GetPDFDoc() { return m_pPDFDoc; } + IXFA_Doc* GetXFADoc() { return m_pXFADoc; } + IXFA_DocView* GetXFADocView() { return m_pXFADocView; } + + int GetPageCount(); + CPDFXFA_Page* GetPage(int page_index); + CPDFXFA_Page* GetPage(IXFA_PageView* pPage); + void RemovePage(CPDFXFA_Page* page); + int GetDocType() { return m_iDocType; } + + CPDFSDK_Document* GetSDKDocument(CPDFDoc_Environment* pFormFillEnv); + + void FXRect2PDFRect(const CFX_RectF& fxRectF, CPDF_Rect& pdfRect); + + virtual void SetChangeMark(IXFA_Doc* hDoc); + virtual FX_BOOL GetChangeMark(IXFA_Doc* hDoc); + // used in dynamic xfa, dwFlags refer to XFA_INVALIDATE_XXX macros. + virtual void InvalidateRect(IXFA_PageView* pPageView, + const CFX_RectF& rt, + FX_DWORD dwFlags = 0); + // used in static xfa, dwFlags refer to XFA_INVALIDATE_XXX macros. + virtual void InvalidateRect(IXFA_Widget* hWidget, FX_DWORD dwFlags = 0); + // show or hide caret + virtual void DisplayCaret(IXFA_Widget* hWidget, + FX_BOOL bVisible, + const CFX_RectF* pRtAnchor); + // dwPos: (0:bottom 1:top) + virtual FX_BOOL GetPopupPos(IXFA_Widget* hWidget, + FX_FLOAT fMinPopup, + FX_FLOAT fMaxPopup, + const CFX_RectF& rtAnchor, + CFX_RectF& rtPopup); + virtual FX_BOOL PopupMenu(IXFA_Widget* hWidget, + CFX_PointF ptPopup, + const CFX_RectF* pRectExclude = NULL); + + // dwFlags XFA_PAGEVIEWEVENT_Added, XFA_PAGEVIEWEVENT_Removing + virtual void PageViewEvent(IXFA_PageView* pPageView, FX_DWORD dwFlags); + // dwEvent refer to XFA_WIDGETEVENT_XXX + virtual void WidgetEvent(IXFA_Widget* hWidget, + CXFA_WidgetAcc* pWidgetData, + FX_DWORD dwEvent, + void* pParam = NULL, + void* pAdditional = NULL); + + // return true if render it. + virtual FX_BOOL RenderCustomWidget(IXFA_Widget* hWidget, + CFX_Graphics* pGS, + CFX_Matrix* pMatrix, + const CFX_RectF& rtUI) { + return FALSE; + } + + // host method + virtual int32_t CountPages(IXFA_Doc* hDoc); + virtual int32_t GetCurrentPage(IXFA_Doc* hDoc); + virtual void SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage); + virtual FX_BOOL IsCalculationsEnabled(IXFA_Doc* hDoc); + virtual void SetCalculationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled); + virtual void GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle); + virtual void SetTitle(IXFA_Doc* hDoc, const CFX_WideStringC& wsTitle); + virtual void ExportData(IXFA_Doc* hDoc, + const CFX_WideStringC& wsFilePath, + FX_BOOL bXDP = TRUE); + virtual void ImportData(IXFA_Doc* hDoc, const CFX_WideStringC& wsFilePath); + virtual void GotoURL(IXFA_Doc* hDoc, + const CFX_WideStringC& bsURL, + FX_BOOL bAppend = TRUE); + virtual FX_BOOL IsValidationsEnabled(IXFA_Doc* hDoc); + virtual void SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled); + virtual void SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget); + virtual void Print(IXFA_Doc* hDoc, + int32_t nStartPage, + int32_t nEndPage, + FX_DWORD dwOptions); + + // LayoutPseudo method + virtual int32_t AbsPageCountInBatch(IXFA_Doc* hDoc) { return 0; } + virtual int32_t AbsPageInBatch(IXFA_Doc* hDoc, IXFA_Widget* hWidget) { + return 0; + } + virtual int32_t SheetCountInBatch(IXFA_Doc* hDoc) { return 0; } + virtual int32_t SheetInBatch(IXFA_Doc* hDoc, IXFA_Widget* hWidget) { + return 0; + } + + // SignaturePseudoModel method + // TODO: + virtual int32_t Verify( + IXFA_Doc* hDoc, + CXFA_Node* pSigNode, + FX_BOOL + bUsed = TRUE /*, SecurityHandler* pHandler, SignatureInfo &info*/) { + return 0; + } + virtual FX_BOOL Sign( + IXFA_Doc* hDoc, + CXFA_NodeList* pNodeList, + const CFX_WideStringC& wsExpression, + const CFX_WideStringC& wsXMLIdent, + const CFX_WideStringC& wsValue = FX_WSTRC(L"open"), + FX_BOOL + bUsed = TRUE /*, SecurityHandler* pHandler = NULL, SignatureInfo &info*/) { + return 0; + } + virtual CXFA_NodeList* Enumerate(IXFA_Doc* hDoc) { return 0; } + virtual FX_BOOL Clear(IXFA_Doc* hDoc, + CXFA_Node* pSigNode, + FX_BOOL bCleared = TRUE) { + return 0; + } + + // Get document path + virtual void GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL); + virtual FX_ARGB GetHighlightColor(IXFA_Doc* hDoc); + + /** + *Submit data to email, http, ftp. + * @param[in] hDoc The document handler. + * @param[in] eFormat Determines the format in which the data will be + *submitted. XFA_ATTRIBUTEENUM_Xdp, XFA_ATTRIBUTEENUM_Xml... + * @param[in] wsTarget The URL to which the data will be submitted. + * @param[in] eEncoding The encoding of text content. + * @param[in] pXDPContent Controls what subset of the data is submitted, used + *only when the format property is xdp. + * @param[in] bEmbedPDF, specifies whether PDF is embedded in the submitted + *content or not. + */ + virtual FX_BOOL SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit); + + virtual FX_BOOL CheckWord(IXFA_Doc* hDoc, const CFX_ByteStringC& sWord) { + return FALSE; + } + virtual FX_BOOL GetSuggestWords(IXFA_Doc* hDoc, + const CFX_ByteStringC& sWord, + CFX_ByteStringArray& sSuggest) { + return FALSE; + } + + // Get PDF javascript object, set the object to hValue. + virtual FX_BOOL GetPDFScriptObject(IXFA_Doc* hDoc, + const CFX_ByteStringC& utf8Name, + FXJSE_HVALUE hValue); + + virtual FX_BOOL GetGlobalProperty(IXFA_Doc* hDoc, + const CFX_ByteStringC& szPropName, + FXJSE_HVALUE hValue); + virtual FX_BOOL SetGlobalProperty(IXFA_Doc* hDoc, + const CFX_ByteStringC& szPropName, + FXJSE_HVALUE hValue); + virtual CPDF_Document* OpenPDF(IXFA_Doc* hDoc, + IFX_FileRead* pFile, + FX_BOOL bTakeOverFile) { + return NULL; + } + + virtual IFX_FileRead* OpenLinkedFile(IXFA_Doc* hDoc, + const CFX_WideString& wsLink); + + FX_BOOL _GetHValueByName(const CFX_ByteStringC& utf8Name, + FXJSE_HVALUE hValue, + IJS_Runtime* runTime); + FX_BOOL _OnBeforeNotifySumbit(); + void _OnAfterNotifySumbit(); + FX_BOOL _NotifySubmit(FX_BOOL bPrevOrPost); + FX_BOOL _SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit); + FX_BOOL _MailToInfo(CFX_WideString& csURL, + CFX_WideString& csToAddress, + CFX_WideString& csCCAddress, + CFX_WideString& csBCCAddress, + CFX_WideString& csSubject, + CFX_WideString& csMsg); + FX_BOOL _ExportSubmitFile(FPDF_FILEHANDLER* ppFileHandler, + int fileType, + FPDF_DWORD encodeType, + FPDF_DWORD flag = 0x01111111); + void _ToXFAContentFlags(CFX_WideString csSrcContent, FPDF_DWORD& flag); + void _ClearChangeMark(); + + private: + void CloseXFADoc(IXFA_DocHandler* pDoc) { + if (pDoc) { + pDoc->CloseDoc(m_pXFADoc); + pDoc->ReleaseDoc(m_pXFADoc); + m_pXFADoc = NULL; + m_pXFADocView = NULL; + } + } + + int m_iDocType; + CPDF_Document* m_pPDFDoc; + CPDFSDK_Document* m_pSDKDoc; + IXFA_Doc* m_pXFADoc; + IXFA_DocView* m_pXFADocView; + CPDFXFA_App* m_pApp; + IJS_Context* m_pJSContext; + CFX_ArrayTemplate m_XFAPageList; +}; + +#endif // FPDFXFA_DOC_H_ diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h index db47784704..814599cc7e 100644 --- a/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h +++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h @@ -1,66 +1,66 @@ -// 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 - -#ifndef _FPDFXFA_PAGEVIEW_H_ -#define _FPDFXFA_PAGEVIEW_H_ - -class CPDFXFA_Page { - public: - CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index); - ~CPDFXFA_Page(); - - void Release(); - void AddRef() { m_iRef++; } - FX_BOOL LoadPage(); - FX_BOOL LoadPDFPage(CPDF_Dictionary* pageDict); - CPDFXFA_Document* GetDocument() { return m_pDocument; } - int GetPageIndex() { return m_iPageIndex; } - CPDF_Page* GetPDFPage() { return m_pPDFPage; } - IXFA_PageView* GetXFAPageView() { return m_pXFAPageView; } - void SetXFAPageView(IXFA_PageView* pPageView) { m_pXFAPageView = pPageView; } - - FX_FLOAT GetPageWidth(); - FX_FLOAT GetPageHeight(); - - void DeviceToPage(int start_x, - int start_y, - int size_x, - int size_y, - int rotate, - int device_x, - int device_y, - double* page_x, - double* page_y); - void PageToDevice(int start_x, - int start_y, - int size_x, - int size_y, - int rotate, - double page_x, - double page_y, - int* device_x, - int* device_y); - - void GetDisplayMatrix(CFX_Matrix& matrix, - int xPos, - int yPos, - int xSize, - int ySize, - int iRotate) const; - - protected: - FX_BOOL LoadPDFPage(); - FX_BOOL LoadXFAPageView(); - - private: - CPDF_Page* m_pPDFPage; - IXFA_PageView* m_pXFAPageView; - int m_iPageIndex; - CPDFXFA_Document* m_pDocument; - int m_iRef; -}; - -#endif +// 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 + +#ifndef _FPDFXFA_PAGEVIEW_H_ +#define _FPDFXFA_PAGEVIEW_H_ + +class CPDFXFA_Page { + public: + CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index); + ~CPDFXFA_Page(); + + void Release(); + void AddRef() { m_iRef++; } + FX_BOOL LoadPage(); + FX_BOOL LoadPDFPage(CPDF_Dictionary* pageDict); + CPDFXFA_Document* GetDocument() { return m_pDocument; } + int GetPageIndex() { return m_iPageIndex; } + CPDF_Page* GetPDFPage() { return m_pPDFPage; } + IXFA_PageView* GetXFAPageView() { return m_pXFAPageView; } + void SetXFAPageView(IXFA_PageView* pPageView) { m_pXFAPageView = pPageView; } + + FX_FLOAT GetPageWidth(); + FX_FLOAT GetPageHeight(); + + void DeviceToPage(int start_x, + int start_y, + int size_x, + int size_y, + int rotate, + int device_x, + int device_y, + double* page_x, + double* page_y); + void PageToDevice(int start_x, + int start_y, + int size_x, + int size_y, + int rotate, + double page_x, + double page_y, + int* device_x, + int* device_y); + + void GetDisplayMatrix(CFX_Matrix& matrix, + int xPos, + int yPos, + int xSize, + int ySize, + int iRotate) const; + + protected: + FX_BOOL LoadPDFPage(); + FX_BOOL LoadXFAPageView(); + + private: + CPDF_Page* m_pPDFPage; + IXFA_PageView* m_pXFAPageView; + int m_iPageIndex; + CPDFXFA_Document* m_pDocument; + int m_iRef; +}; + +#endif diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h index a64d030de5..ca675bf27a 100644 --- a/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h +++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h @@ -1,40 +1,40 @@ -// 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 - -#ifndef FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_ -#define FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_ - -#include "xfa/include/fwl/adapter/fwl_adaptertimermgr.h" - -#define JS_STR_VIEWERTYPE_STANDARD L"Exchange" -#define JS_STR_LANGUANGE L"ENU" -#define JS_STR_VIEWERVARIATION L"Full" -#define JS_STR_VIEWERVERSION_XFA L"11" - -class CXFA_FWLAdapterTimerMgr : public IFWL_AdapterTimerMgr { - public: - CXFA_FWLAdapterTimerMgr(CPDFDoc_Environment* pEnv) : m_pEnv(pEnv) {} - virtual FWL_ERR Start(IFWL_Timer* pTimer, - FX_DWORD dwElapse, - FWL_HTIMER& hTimer, - FX_BOOL bImmediately = TRUE); - virtual FWL_ERR Stop(FWL_HTIMER hTimer); - - protected: - static void TimerProc(int32_t idEvent); - - static CFX_PtrArray ms_timerArray; - CPDFDoc_Environment* m_pEnv; -}; - -class CFWL_TimerInfo { - public: - CFWL_TimerInfo() : pTimer(nullptr) {} - uint32_t uIDEvent; - IFWL_Timer* pTimer; -}; - -#endif // FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_ +// 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 + +#ifndef FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_ +#define FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_ + +#include "xfa/include/fwl/adapter/fwl_adaptertimermgr.h" + +#define JS_STR_VIEWERTYPE_STANDARD L"Exchange" +#define JS_STR_LANGUANGE L"ENU" +#define JS_STR_VIEWERVARIATION L"Full" +#define JS_STR_VIEWERVERSION_XFA L"11" + +class CXFA_FWLAdapterTimerMgr : public IFWL_AdapterTimerMgr { + public: + CXFA_FWLAdapterTimerMgr(CPDFDoc_Environment* pEnv) : m_pEnv(pEnv) {} + virtual FWL_ERR Start(IFWL_Timer* pTimer, + FX_DWORD dwElapse, + FWL_HTIMER& hTimer, + FX_BOOL bImmediately = TRUE); + virtual FWL_ERR Stop(FWL_HTIMER hTimer); + + protected: + static void TimerProc(int32_t idEvent); + + static CFX_PtrArray ms_timerArray; + CPDFDoc_Environment* m_pEnv; +}; + +class CFWL_TimerInfo { + public: + CFWL_TimerInfo() : pTimer(nullptr) {} + uint32_t uIDEvent; + IFWL_Timer* pTimer; +}; + +#endif // FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_ diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp index 853eb30d82..44e9c72ddc 100644 --- a/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp +++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp @@ -1,537 +1,537 @@ -// 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 "fpdfsdk/include/fsdk_define.h" -#include "fpdfsdk/include/fsdk_mgr.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" -#include "fpdfsdk/include/javascript/IJavaScript.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h" -#include "public/fpdf_formfill.h" - -CPDFXFA_App* CPDFXFA_App::g_pApp = NULL; - -CPDFXFA_App* CPDFXFA_App::GetInstance() { - if (!g_pApp) { - g_pApp = new CPDFXFA_App(); - } - return g_pApp; -} - -void CPDFXFA_App::ReleaseInstance() { - delete g_pApp; - g_pApp = NULL; -} - -CPDFXFA_App::CPDFXFA_App() - : m_bJavaScriptInitialized(FALSE), - m_pXFAApp(NULL), - m_pFontMgr(NULL), - m_hJSERuntime(NULL), - m_csAppType(JS_STR_VIEWERTYPE_STANDARD) { - m_pEnvList.RemoveAll(); -} - -CPDFXFA_App::~CPDFXFA_App() { - delete m_pFontMgr; - m_pFontMgr = NULL; - - delete m_pXFAApp; - m_pXFAApp = NULL; - -#ifdef PDF_ENABLE_XFA - FXJSE_Runtime_Release(m_hJSERuntime); - m_hJSERuntime = NULL; - - FXJSE_Finalize(); - BC_Library_Destory(); -#endif -} - -FX_BOOL CPDFXFA_App::Initialize() { -#ifdef PDF_ENABLE_XFA - BC_Library_Init(); - FXJSE_Initialize(); - - m_hJSERuntime = FXJSE_Runtime_Create(); - if (!m_hJSERuntime) - return FALSE; - - m_pXFAApp = IXFA_App::Create(this); - if (!m_pXFAApp) - return FALSE; - - m_pFontMgr = IXFA_FontMgr::CreateDefault(); - if (!m_pFontMgr) - return FALSE; - - m_pXFAApp->SetDefaultFontMgr(m_pFontMgr); -#endif - return TRUE; -} - -FX_BOOL CPDFXFA_App::AddFormFillEnv(CPDFDoc_Environment* pEnv) { - if (!pEnv) - return FALSE; - - m_pEnvList.Add(pEnv); - return TRUE; -} - -FX_BOOL CPDFXFA_App::RemoveFormFillEnv(CPDFDoc_Environment* pEnv) { - if (!pEnv) - return FALSE; - - int nFind = m_pEnvList.Find(pEnv); - if (nFind != -1) { - m_pEnvList.RemoveAt(nFind); - return TRUE; - } - - return FALSE; -} - -void CPDFXFA_App::GetAppType(CFX_WideString& wsAppType) { - wsAppType = m_csAppType; -} - -void CPDFXFA_App::GetAppName(CFX_WideString& wsName) { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) { - wsName = pEnv->FFI_GetAppName(); - } -} - -void CPDFXFA_App::SetAppType(const CFX_WideStringC& wsAppType) { - m_csAppType = wsAppType; -} - -void CPDFXFA_App::GetLanguage(CFX_WideString& wsLanguage) { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) { - wsLanguage = pEnv->FFI_GetLanguage(); - } -} - -void CPDFXFA_App::GetPlatform(CFX_WideString& wsPlatform) { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) { - wsPlatform = pEnv->FFI_GetPlatform(); - } -} - -void CPDFXFA_App::GetVariation(CFX_WideString& wsVariation) { - wsVariation = JS_STR_VIEWERVARIATION; -} - -void CPDFXFA_App::GetVersion(CFX_WideString& wsVersion) { - wsVersion = JS_STR_VIEWERVERSION_XFA; -} - -void CPDFXFA_App::Beep(FX_DWORD dwType) { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) { - pEnv->JS_appBeep(dwType); - } -} - -int32_t CPDFXFA_App::MsgBox(const CFX_WideStringC& wsMessage, - const CFX_WideStringC& wsTitle, - FX_DWORD dwIconType, - FX_DWORD dwButtonType) { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (!pEnv) - return -1; - - FX_DWORD iconType = 0; - int iButtonType = 0; - switch (dwIconType) { - case XFA_MBICON_Error: - iconType |= 0; - break; - case XFA_MBICON_Warning: - iconType |= 1; - break; - case XFA_MBICON_Question: - iconType |= 2; - break; - case XFA_MBICON_Status: - iconType |= 3; - break; - } - switch (dwButtonType) { - case XFA_MB_OK: - iButtonType |= 0; - break; - case XFA_MB_OKCancel: - iButtonType |= 1; - break; - case XFA_MB_YesNo: - iButtonType |= 2; - break; - case XFA_MB_YesNoCancel: - iButtonType |= 3; - break; - } - int32_t iRet = pEnv->JS_appAlert(wsMessage.GetPtr(), wsTitle.GetPtr(), - iButtonType, iconType); - switch (iRet) { - case 1: - return XFA_IDOK; - case 2: - return XFA_IDCancel; - case 3: - return XFA_IDNo; - case 4: - return XFA_IDYes; - } - return XFA_IDYes; -} - -void CPDFXFA_App::Response(CFX_WideString& wsAnswer, - const CFX_WideStringC& wsQuestion, - const CFX_WideStringC& wsTitle, - const CFX_WideStringC& wsDefaultAnswer, - FX_BOOL bMark) { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) { - int nLength = 2048; - char* pBuff = new char[nLength]; - nLength = pEnv->JS_appResponse(wsQuestion.GetPtr(), wsTitle.GetPtr(), - wsDefaultAnswer.GetPtr(), NULL, bMark, pBuff, - nLength); - if (nLength > 0) { - nLength = nLength > 2046 ? 2046 : nLength; - pBuff[nLength] = 0; - pBuff[nLength + 1] = 0; - wsAnswer = CFX_WideString::FromUTF16LE( - reinterpret_cast(pBuff), - nLength / sizeof(unsigned short)); - } - delete[] pBuff; - } -} - -int32_t CPDFXFA_App::GetCurDocumentInBatch() { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) { - return pEnv->FFI_GetCurDocument(); - } - return 0; -} - -int32_t CPDFXFA_App::GetDocumentCountInBatch() { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) { - return pEnv->FFI_GetDocumentCount(); - } - - return 0; -} - -IFX_FileRead* CPDFXFA_App::DownloadURL(const CFX_WideStringC& wsURL) { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) { - return pEnv->FFI_DownloadFromURL(wsURL.GetPtr()); - } - return NULL; -} - -FX_BOOL CPDFXFA_App::PostRequestURL(const CFX_WideStringC& wsURL, - const CFX_WideStringC& wsData, - const CFX_WideStringC& wsContentType, - const CFX_WideStringC& wsEncode, - const CFX_WideStringC& wsHeader, - CFX_WideString& wsResponse) { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) { - wsResponse = pEnv->FFI_PostRequestURL(wsURL.GetPtr(), wsData.GetPtr(), - wsContentType.GetPtr(), - wsEncode.GetPtr(), wsHeader.GetPtr()); - return TRUE; - } - return FALSE; -} - -FX_BOOL CPDFXFA_App::PutRequestURL(const CFX_WideStringC& wsURL, - const CFX_WideStringC& wsData, - const CFX_WideStringC& wsEncode) { - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) { - return pEnv->FFI_PutRequestURL(wsURL.GetPtr(), wsData.GetPtr(), - wsEncode.GetPtr()); - } - return FALSE; -} - -void CPDFXFA_App::LoadString(int32_t iStringID, CFX_WideString& wsString) { - switch (iStringID) { - case XFA_IDS_ValidateFailed: - wsString = L"%s validate failed"; - return; - case XFA_IDS_CalcOverride: - wsString = L"Calculate Override"; - return; - case XFA_IDS_ModifyField: - wsString = L"Are you sure you want to modify this field?"; - return; - case XFA_IDS_NotModifyField: - wsString = L"You are not allowed to modify this field."; - return; - case XFA_IDS_AppName: - wsString = L"Foxit"; - return; - case XFA_IDS_ImageFilter: - wsString = - L"Image " - L"Files(*.bmp;*.jpg;*.png;*.gif;*.tif)|*.bmp;*.jpg;*.png;*.gif;*.tif|" - L"All Files(*.*)|*.*||"; - return; - case XFA_IDS_UNKNOW_CATCHED: - wsString = L"unknown error is catched!"; - return; - case XFA_IDS_Unable_TO_SET: - wsString = L"Unable to set "; - return; - case XFA_IDS_VALUE_EXCALMATORY: - wsString = L" value!"; - return; - case XFA_IDS_INVALID_ENUM_VALUE: - wsString = L"Invalid enumerated value: "; - return; - case XFA_IDS_UNSUPPORT_METHOD: - wsString = L"unsupport %s method."; - return; - case XFA_IDS_UNSUPPORT_PROP: - wsString = L"unsupport %s property."; - return; - case XFA_IDS_INVAlID_PROP_SET: - wsString = L"Invalid property set operation;"; - return; - case XFA_IDS_NOT_DEFAUL_VALUE: - wsString = L" doesn't have a default property"; - return; - case XFA_IDS_UNABLE_SET_LANGUAGE: - wsString = L"Unable to set language value!"; - return; - case XFA_IDS_UNABLE_SET_NUMPAGES: - wsString = L"Unable to set numPages value!"; - return; - case XFA_IDS_UNABLE_SET_PLATFORM: - wsString = L"Unable to set platform value!"; - return; - case XFA_IDS_UNABLE_SET_VALIDATIONENABLE: - wsString = L"Unable to set validationsEnabled value!"; - return; - case XFA_IDS_UNABLE_SET_VARIATION: - wsString = L"Unable to set variation value!"; - return; - case XFA_IDS_UNABLE_SET_VERSION: - wsString = L"Unable to set version value!"; - return; - case XFA_IDS_UNABLE_SET_READY: - wsString = L"Unable to set ready value!"; - return; - case XFA_IDS_NUMBER_OF_OCCUR: - wsString = - L"The element [%s] has violated its allowable number of occurrences"; - return; - case XFA_IDS_UNABLE_SET_CLASS_NAME: - wsString = L"Unable to set className value!"; - return; - case XFA_IDS_UNABLE_SET_LENGTH_VALUE: - wsString = L"Unable to set length value!"; - return; - case XFA_IDS_UNSUPPORT_CHAR: - wsString = L"unsupported char '%c'"; - return; - case XFA_IDS_BAD_SUFFIX: - wsString = L"bad suffix on number"; - return; - case XFA_IDS_EXPECTED_IDENT: - wsString = L"expected identifier instead of '%s'"; - return; - case XFA_IDS_EXPECTED_STRING: - wsString = L"expected '%s' instead of '%s'"; - return; - case XFA_IDS_INVALIDATE_CHAR: - wsString = L"invalidate char '%c'"; - return; - case XFA_IDS_REDEFINITION: - wsString = L"'%s' redefinition "; - return; - case XFA_IDS_INVALIDATE_TOKEN: - wsString = L"invalidate token '%s'"; - return; - case XFA_IDS_INVALIDATE_EXPRESSION: - wsString = L"invalidate expression '%s'"; - return; - case XFA_IDS_UNDEFINE_IDENTIFIER: - wsString = L"undefined identifier '%s'"; - return; - case XFA_IDS_INVALIDATE_LEFTVALUE: - wsString = L"invalidate left-value '%s'"; - return; - case XFA_IDS_COMPILER_ERROR: - wsString = L"compiler error"; - return; - case XFA_IDS_CANNOT_MODIFY_VALUE: - wsString = L"can't modify the '%s' value"; - return; - case XFA_IDS_ERROR_PARAMETERS: - wsString = L"function '%s' has not %d parameters"; - return; - case XFA_IDS_EXPECT_ENDIF: - wsString = L"expected 'endif' instead of '%s'"; - return; - case XFA_IDS_UNEXPECTED_EXPRESSION: - wsString = L"unexpected expression '%s'"; - return; - case XFA_IDS_CONDITION_IS_NULL: - wsString = L"condition is null"; - return; - case XFA_IDS_ILLEGALBREAK: - wsString = L"illegal break"; - return; - case XFA_IDS_ILLEGALCONTINUE: - wsString = L"illegal continue"; - return; - case XFA_IDS_EXPECTED_OPERATOR: - wsString = L"expected operator '%s' instead of '%s'"; - return; - case XFA_IDS_DIVIDE_ZERO: - wsString = L"divide by zero"; - return; - case XFA_IDS_CANNOT_COVERT_OBJECT: - wsString = L"%s.%s can not covert to object"; - return; - case XFA_IDS_NOT_FOUND_CONTAINER: - wsString = L"can not found container '%s'"; - return; - case XFA_IDS_NOT_FOUND_PROPERTY: - wsString = L"can not found property '%s'"; - return; - case XFA_IDS_NOT_FOUND_METHOD: - wsString = L"can not found method '%s'"; - return; - case XFA_IDS_NOT_FOUND_CONST: - wsString = L"can not found const '%s'"; - return; - case XFA_IDS_NOT_ASSIGN_OBJECT: - wsString = L"can not direct assign value to object"; - return; - case XFA_IDS_IVALIDATE_INSTRUCTION: - wsString = L"invalidate instruction"; - return; - case XFA_IDS_EXPECT_NUMBER: - wsString = L"expected number instead of '%s'"; - return; - case XFA_IDS_VALIDATE_OUT_ARRAY: - wsString = L"validate access index '%s' out of array"; - return; - case XFA_IDS_CANNOT_ASSIGN_IDENT: - wsString = L"can not assign to %s"; - return; - case XFA_IDS_NOT_FOUNT_FUNCTION: - wsString = L"can not found '%s' function"; - return; - case XFA_IDS_NOT_ARRAY: - wsString = L"'%s' doesn't an array"; - return; - case XFA_IDS_OUT_ARRAY: - wsString = L"out of range of '%s' array"; - return; - case XFA_IDS_NOT_SUPPORT_CALC: - wsString = L"'%s' operator can not support array calculate"; - return; - case XFA_IDS_ARGUMENT_NOT_ARRAY: - wsString = L"'%s' function's %d argument can not be array"; - return; - case XFA_IDS_ARGUMENT_EXPECT_CONTAINER: - wsString = L"'%s' argument expected a container"; - return; - case XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT: - wsString = - L"an attempt was made to reference property '%s' of a non-object in " - L"SOM expression %s"; - return; - case XFA_IDS_FUNCTION_IS_BUILDIN: - wsString = L"function '%s' is buildin"; - return; - case XFA_IDS_ERROR_MSG: - wsString = L"%s : %s"; - return; - case XFA_IDS_INDEX_OUT_OF_BOUNDS: - wsString = L"Index value is out of bounds"; - return; - case XFA_IDS_INCORRECT_NUMBER_OF_METHOD: - wsString = L"Incorrect number of parameters calling method '%s'"; - return; - case XFA_IDS_ARGUMENT_MISMATCH: - wsString = L"Argument mismatch in property or function argument"; - return; - case XFA_IDS_INVALID_ENUMERATE: - wsString = L"Invalid enumerated value: %s"; - return; - case XFA_IDS_INVALID_APPEND: - wsString = - L"Invalid append operation: %s cannot have a child element of %s"; - return; - case XFA_IDS_SOM_EXPECTED_LIST: - wsString = - L"SOM expression returned list when single result was expected"; - return; - case XFA_IDS_NOT_HAVE_PROPERTY: - wsString = L"'%s' doesn't have property '%s'"; - return; - case XFA_IDS_INVALID_NODE_TYPE: - wsString = L"Invalid node type : '%s'"; - return; - case XFA_IDS_VIOLATE_BOUNDARY: - wsString = - L"The element [%s] has violated its allowable number of occurrences"; - return; - case XFA_IDS_SERVER_DENY: - wsString = L"Server does not permit"; - return; - case XFA_IDS_ValidateLimit: - wsString = FX_WSTRC( - L"Message limit exceeded. Remaining %d validation errors not " - L"reported."); - return; - case XFA_IDS_ValidateNullWarning: - wsString = FX_WSTRC( - L"%s cannot be left blank. To ignore validations for %s, click " - L"Ignore."); - return; - case XFA_IDS_ValidateNullError: - wsString = FX_WSTRC(L"%s cannot be left blank."); - return; - case XFA_IDS_ValidateWarning: - wsString = FX_WSTRC( - L"The value you entered for %s is invalid. To ignore validations for " - L"%s, click Ignore."); - return; - case XFA_IDS_ValidateError: - wsString = FX_WSTRC(L"The value you entered for %s is invalid."); - return; - } -} - -FX_BOOL CPDFXFA_App::ShowFileDialog(const CFX_WideStringC& wsTitle, - const CFX_WideStringC& wsFilter, - CFX_WideStringArray& wsPathArr, - FX_BOOL bOpen) { - return FALSE; -} - -IFWL_AdapterTimerMgr* CPDFXFA_App::GetTimerMgr() { - CXFA_FWLAdapterTimerMgr* pAdapter = NULL; - CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); - if (pEnv) - pAdapter = new CXFA_FWLAdapterTimerMgr(pEnv); - return pAdapter; -} +// 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 "fpdfsdk/include/fsdk_define.h" +#include "fpdfsdk/include/fsdk_mgr.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" +#include "fpdfsdk/include/javascript/IJavaScript.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h" +#include "public/fpdf_formfill.h" + +CPDFXFA_App* CPDFXFA_App::g_pApp = NULL; + +CPDFXFA_App* CPDFXFA_App::GetInstance() { + if (!g_pApp) { + g_pApp = new CPDFXFA_App(); + } + return g_pApp; +} + +void CPDFXFA_App::ReleaseInstance() { + delete g_pApp; + g_pApp = NULL; +} + +CPDFXFA_App::CPDFXFA_App() + : m_bJavaScriptInitialized(FALSE), + m_pXFAApp(NULL), + m_pFontMgr(NULL), + m_hJSERuntime(NULL), + m_csAppType(JS_STR_VIEWERTYPE_STANDARD) { + m_pEnvList.RemoveAll(); +} + +CPDFXFA_App::~CPDFXFA_App() { + delete m_pFontMgr; + m_pFontMgr = NULL; + + delete m_pXFAApp; + m_pXFAApp = NULL; + +#ifdef PDF_ENABLE_XFA + FXJSE_Runtime_Release(m_hJSERuntime); + m_hJSERuntime = NULL; + + FXJSE_Finalize(); + BC_Library_Destory(); +#endif +} + +FX_BOOL CPDFXFA_App::Initialize() { +#ifdef PDF_ENABLE_XFA + BC_Library_Init(); + FXJSE_Initialize(); + + m_hJSERuntime = FXJSE_Runtime_Create(); + if (!m_hJSERuntime) + return FALSE; + + m_pXFAApp = IXFA_App::Create(this); + if (!m_pXFAApp) + return FALSE; + + m_pFontMgr = IXFA_FontMgr::CreateDefault(); + if (!m_pFontMgr) + return FALSE; + + m_pXFAApp->SetDefaultFontMgr(m_pFontMgr); +#endif + return TRUE; +} + +FX_BOOL CPDFXFA_App::AddFormFillEnv(CPDFDoc_Environment* pEnv) { + if (!pEnv) + return FALSE; + + m_pEnvList.Add(pEnv); + return TRUE; +} + +FX_BOOL CPDFXFA_App::RemoveFormFillEnv(CPDFDoc_Environment* pEnv) { + if (!pEnv) + return FALSE; + + int nFind = m_pEnvList.Find(pEnv); + if (nFind != -1) { + m_pEnvList.RemoveAt(nFind); + return TRUE; + } + + return FALSE; +} + +void CPDFXFA_App::GetAppType(CFX_WideString& wsAppType) { + wsAppType = m_csAppType; +} + +void CPDFXFA_App::GetAppName(CFX_WideString& wsName) { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) { + wsName = pEnv->FFI_GetAppName(); + } +} + +void CPDFXFA_App::SetAppType(const CFX_WideStringC& wsAppType) { + m_csAppType = wsAppType; +} + +void CPDFXFA_App::GetLanguage(CFX_WideString& wsLanguage) { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) { + wsLanguage = pEnv->FFI_GetLanguage(); + } +} + +void CPDFXFA_App::GetPlatform(CFX_WideString& wsPlatform) { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) { + wsPlatform = pEnv->FFI_GetPlatform(); + } +} + +void CPDFXFA_App::GetVariation(CFX_WideString& wsVariation) { + wsVariation = JS_STR_VIEWERVARIATION; +} + +void CPDFXFA_App::GetVersion(CFX_WideString& wsVersion) { + wsVersion = JS_STR_VIEWERVERSION_XFA; +} + +void CPDFXFA_App::Beep(FX_DWORD dwType) { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) { + pEnv->JS_appBeep(dwType); + } +} + +int32_t CPDFXFA_App::MsgBox(const CFX_WideStringC& wsMessage, + const CFX_WideStringC& wsTitle, + FX_DWORD dwIconType, + FX_DWORD dwButtonType) { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (!pEnv) + return -1; + + FX_DWORD iconType = 0; + int iButtonType = 0; + switch (dwIconType) { + case XFA_MBICON_Error: + iconType |= 0; + break; + case XFA_MBICON_Warning: + iconType |= 1; + break; + case XFA_MBICON_Question: + iconType |= 2; + break; + case XFA_MBICON_Status: + iconType |= 3; + break; + } + switch (dwButtonType) { + case XFA_MB_OK: + iButtonType |= 0; + break; + case XFA_MB_OKCancel: + iButtonType |= 1; + break; + case XFA_MB_YesNo: + iButtonType |= 2; + break; + case XFA_MB_YesNoCancel: + iButtonType |= 3; + break; + } + int32_t iRet = pEnv->JS_appAlert(wsMessage.GetPtr(), wsTitle.GetPtr(), + iButtonType, iconType); + switch (iRet) { + case 1: + return XFA_IDOK; + case 2: + return XFA_IDCancel; + case 3: + return XFA_IDNo; + case 4: + return XFA_IDYes; + } + return XFA_IDYes; +} + +void CPDFXFA_App::Response(CFX_WideString& wsAnswer, + const CFX_WideStringC& wsQuestion, + const CFX_WideStringC& wsTitle, + const CFX_WideStringC& wsDefaultAnswer, + FX_BOOL bMark) { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) { + int nLength = 2048; + char* pBuff = new char[nLength]; + nLength = pEnv->JS_appResponse(wsQuestion.GetPtr(), wsTitle.GetPtr(), + wsDefaultAnswer.GetPtr(), NULL, bMark, pBuff, + nLength); + if (nLength > 0) { + nLength = nLength > 2046 ? 2046 : nLength; + pBuff[nLength] = 0; + pBuff[nLength + 1] = 0; + wsAnswer = CFX_WideString::FromUTF16LE( + reinterpret_cast(pBuff), + nLength / sizeof(unsigned short)); + } + delete[] pBuff; + } +} + +int32_t CPDFXFA_App::GetCurDocumentInBatch() { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) { + return pEnv->FFI_GetCurDocument(); + } + return 0; +} + +int32_t CPDFXFA_App::GetDocumentCountInBatch() { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) { + return pEnv->FFI_GetDocumentCount(); + } + + return 0; +} + +IFX_FileRead* CPDFXFA_App::DownloadURL(const CFX_WideStringC& wsURL) { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) { + return pEnv->FFI_DownloadFromURL(wsURL.GetPtr()); + } + return NULL; +} + +FX_BOOL CPDFXFA_App::PostRequestURL(const CFX_WideStringC& wsURL, + const CFX_WideStringC& wsData, + const CFX_WideStringC& wsContentType, + const CFX_WideStringC& wsEncode, + const CFX_WideStringC& wsHeader, + CFX_WideString& wsResponse) { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) { + wsResponse = pEnv->FFI_PostRequestURL(wsURL.GetPtr(), wsData.GetPtr(), + wsContentType.GetPtr(), + wsEncode.GetPtr(), wsHeader.GetPtr()); + return TRUE; + } + return FALSE; +} + +FX_BOOL CPDFXFA_App::PutRequestURL(const CFX_WideStringC& wsURL, + const CFX_WideStringC& wsData, + const CFX_WideStringC& wsEncode) { + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) { + return pEnv->FFI_PutRequestURL(wsURL.GetPtr(), wsData.GetPtr(), + wsEncode.GetPtr()); + } + return FALSE; +} + +void CPDFXFA_App::LoadString(int32_t iStringID, CFX_WideString& wsString) { + switch (iStringID) { + case XFA_IDS_ValidateFailed: + wsString = L"%s validate failed"; + return; + case XFA_IDS_CalcOverride: + wsString = L"Calculate Override"; + return; + case XFA_IDS_ModifyField: + wsString = L"Are you sure you want to modify this field?"; + return; + case XFA_IDS_NotModifyField: + wsString = L"You are not allowed to modify this field."; + return; + case XFA_IDS_AppName: + wsString = L"Foxit"; + return; + case XFA_IDS_ImageFilter: + wsString = + L"Image " + L"Files(*.bmp;*.jpg;*.png;*.gif;*.tif)|*.bmp;*.jpg;*.png;*.gif;*.tif|" + L"All Files(*.*)|*.*||"; + return; + case XFA_IDS_UNKNOW_CATCHED: + wsString = L"unknown error is catched!"; + return; + case XFA_IDS_Unable_TO_SET: + wsString = L"Unable to set "; + return; + case XFA_IDS_VALUE_EXCALMATORY: + wsString = L" value!"; + return; + case XFA_IDS_INVALID_ENUM_VALUE: + wsString = L"Invalid enumerated value: "; + return; + case XFA_IDS_UNSUPPORT_METHOD: + wsString = L"unsupport %s method."; + return; + case XFA_IDS_UNSUPPORT_PROP: + wsString = L"unsupport %s property."; + return; + case XFA_IDS_INVAlID_PROP_SET: + wsString = L"Invalid property set operation;"; + return; + case XFA_IDS_NOT_DEFAUL_VALUE: + wsString = L" doesn't have a default property"; + return; + case XFA_IDS_UNABLE_SET_LANGUAGE: + wsString = L"Unable to set language value!"; + return; + case XFA_IDS_UNABLE_SET_NUMPAGES: + wsString = L"Unable to set numPages value!"; + return; + case XFA_IDS_UNABLE_SET_PLATFORM: + wsString = L"Unable to set platform value!"; + return; + case XFA_IDS_UNABLE_SET_VALIDATIONENABLE: + wsString = L"Unable to set validationsEnabled value!"; + return; + case XFA_IDS_UNABLE_SET_VARIATION: + wsString = L"Unable to set variation value!"; + return; + case XFA_IDS_UNABLE_SET_VERSION: + wsString = L"Unable to set version value!"; + return; + case XFA_IDS_UNABLE_SET_READY: + wsString = L"Unable to set ready value!"; + return; + case XFA_IDS_NUMBER_OF_OCCUR: + wsString = + L"The element [%s] has violated its allowable number of occurrences"; + return; + case XFA_IDS_UNABLE_SET_CLASS_NAME: + wsString = L"Unable to set className value!"; + return; + case XFA_IDS_UNABLE_SET_LENGTH_VALUE: + wsString = L"Unable to set length value!"; + return; + case XFA_IDS_UNSUPPORT_CHAR: + wsString = L"unsupported char '%c'"; + return; + case XFA_IDS_BAD_SUFFIX: + wsString = L"bad suffix on number"; + return; + case XFA_IDS_EXPECTED_IDENT: + wsString = L"expected identifier instead of '%s'"; + return; + case XFA_IDS_EXPECTED_STRING: + wsString = L"expected '%s' instead of '%s'"; + return; + case XFA_IDS_INVALIDATE_CHAR: + wsString = L"invalidate char '%c'"; + return; + case XFA_IDS_REDEFINITION: + wsString = L"'%s' redefinition "; + return; + case XFA_IDS_INVALIDATE_TOKEN: + wsString = L"invalidate token '%s'"; + return; + case XFA_IDS_INVALIDATE_EXPRESSION: + wsString = L"invalidate expression '%s'"; + return; + case XFA_IDS_UNDEFINE_IDENTIFIER: + wsString = L"undefined identifier '%s'"; + return; + case XFA_IDS_INVALIDATE_LEFTVALUE: + wsString = L"invalidate left-value '%s'"; + return; + case XFA_IDS_COMPILER_ERROR: + wsString = L"compiler error"; + return; + case XFA_IDS_CANNOT_MODIFY_VALUE: + wsString = L"can't modify the '%s' value"; + return; + case XFA_IDS_ERROR_PARAMETERS: + wsString = L"function '%s' has not %d parameters"; + return; + case XFA_IDS_EXPECT_ENDIF: + wsString = L"expected 'endif' instead of '%s'"; + return; + case XFA_IDS_UNEXPECTED_EXPRESSION: + wsString = L"unexpected expression '%s'"; + return; + case XFA_IDS_CONDITION_IS_NULL: + wsString = L"condition is null"; + return; + case XFA_IDS_ILLEGALBREAK: + wsString = L"illegal break"; + return; + case XFA_IDS_ILLEGALCONTINUE: + wsString = L"illegal continue"; + return; + case XFA_IDS_EXPECTED_OPERATOR: + wsString = L"expected operator '%s' instead of '%s'"; + return; + case XFA_IDS_DIVIDE_ZERO: + wsString = L"divide by zero"; + return; + case XFA_IDS_CANNOT_COVERT_OBJECT: + wsString = L"%s.%s can not covert to object"; + return; + case XFA_IDS_NOT_FOUND_CONTAINER: + wsString = L"can not found container '%s'"; + return; + case XFA_IDS_NOT_FOUND_PROPERTY: + wsString = L"can not found property '%s'"; + return; + case XFA_IDS_NOT_FOUND_METHOD: + wsString = L"can not found method '%s'"; + return; + case XFA_IDS_NOT_FOUND_CONST: + wsString = L"can not found const '%s'"; + return; + case XFA_IDS_NOT_ASSIGN_OBJECT: + wsString = L"can not direct assign value to object"; + return; + case XFA_IDS_IVALIDATE_INSTRUCTION: + wsString = L"invalidate instruction"; + return; + case XFA_IDS_EXPECT_NUMBER: + wsString = L"expected number instead of '%s'"; + return; + case XFA_IDS_VALIDATE_OUT_ARRAY: + wsString = L"validate access index '%s' out of array"; + return; + case XFA_IDS_CANNOT_ASSIGN_IDENT: + wsString = L"can not assign to %s"; + return; + case XFA_IDS_NOT_FOUNT_FUNCTION: + wsString = L"can not found '%s' function"; + return; + case XFA_IDS_NOT_ARRAY: + wsString = L"'%s' doesn't an array"; + return; + case XFA_IDS_OUT_ARRAY: + wsString = L"out of range of '%s' array"; + return; + case XFA_IDS_NOT_SUPPORT_CALC: + wsString = L"'%s' operator can not support array calculate"; + return; + case XFA_IDS_ARGUMENT_NOT_ARRAY: + wsString = L"'%s' function's %d argument can not be array"; + return; + case XFA_IDS_ARGUMENT_EXPECT_CONTAINER: + wsString = L"'%s' argument expected a container"; + return; + case XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT: + wsString = + L"an attempt was made to reference property '%s' of a non-object in " + L"SOM expression %s"; + return; + case XFA_IDS_FUNCTION_IS_BUILDIN: + wsString = L"function '%s' is buildin"; + return; + case XFA_IDS_ERROR_MSG: + wsString = L"%s : %s"; + return; + case XFA_IDS_INDEX_OUT_OF_BOUNDS: + wsString = L"Index value is out of bounds"; + return; + case XFA_IDS_INCORRECT_NUMBER_OF_METHOD: + wsString = L"Incorrect number of parameters calling method '%s'"; + return; + case XFA_IDS_ARGUMENT_MISMATCH: + wsString = L"Argument mismatch in property or function argument"; + return; + case XFA_IDS_INVALID_ENUMERATE: + wsString = L"Invalid enumerated value: %s"; + return; + case XFA_IDS_INVALID_APPEND: + wsString = + L"Invalid append operation: %s cannot have a child element of %s"; + return; + case XFA_IDS_SOM_EXPECTED_LIST: + wsString = + L"SOM expression returned list when single result was expected"; + return; + case XFA_IDS_NOT_HAVE_PROPERTY: + wsString = L"'%s' doesn't have property '%s'"; + return; + case XFA_IDS_INVALID_NODE_TYPE: + wsString = L"Invalid node type : '%s'"; + return; + case XFA_IDS_VIOLATE_BOUNDARY: + wsString = + L"The element [%s] has violated its allowable number of occurrences"; + return; + case XFA_IDS_SERVER_DENY: + wsString = L"Server does not permit"; + return; + case XFA_IDS_ValidateLimit: + wsString = FX_WSTRC( + L"Message limit exceeded. Remaining %d validation errors not " + L"reported."); + return; + case XFA_IDS_ValidateNullWarning: + wsString = FX_WSTRC( + L"%s cannot be left blank. To ignore validations for %s, click " + L"Ignore."); + return; + case XFA_IDS_ValidateNullError: + wsString = FX_WSTRC(L"%s cannot be left blank."); + return; + case XFA_IDS_ValidateWarning: + wsString = FX_WSTRC( + L"The value you entered for %s is invalid. To ignore validations for " + L"%s, click Ignore."); + return; + case XFA_IDS_ValidateError: + wsString = FX_WSTRC(L"The value you entered for %s is invalid."); + return; + } +} + +FX_BOOL CPDFXFA_App::ShowFileDialog(const CFX_WideStringC& wsTitle, + const CFX_WideStringC& wsFilter, + CFX_WideStringArray& wsPathArr, + FX_BOOL bOpen) { + return FALSE; +} + +IFWL_AdapterTimerMgr* CPDFXFA_App::GetTimerMgr() { + CXFA_FWLAdapterTimerMgr* pAdapter = NULL; + CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0); + if (pEnv) + pAdapter = new CXFA_FWLAdapterTimerMgr(pEnv); + return pAdapter; +} diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp index 09c444eb67..254dc7df74 100644 --- a/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp +++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp @@ -1,1265 +1,1265 @@ -// 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 "fpdfsdk/include/fsdk_define.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" -#include "fpdfsdk/include/fsdk_mgr.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h" -#include "fpdfsdk/include/javascript/IJavaScript.h" -#include "public/fpdf_formfill.h" - -#define IDS_XFA_Validate_Input \ - "At least one required field was empty. Please fill in the required " \ - "fields\r\n(highlighted) before continuing." - -// submit -#define FXFA_CONFIG 0x00000001 -#define FXFA_TEMPLATE 0x00000010 -#define FXFA_LOCALESET 0x00000100 -#define FXFA_DATASETS 0x00001000 -#define FXFA_XMPMETA 0x00010000 -#define FXFA_XFDF 0x00100000 -#define FXFA_FORM 0x01000000 -#define FXFA_PDF 0x10000000 - -#ifndef _WIN32 -extern void SetLastError(int err); - -extern int GetLastError(); -#endif - -CPDFXFA_Document::CPDFXFA_Document(CPDF_Document* pPDFDoc, - CPDFXFA_App* pProvider) - : m_iDocType(DOCTYPE_PDF), - m_pPDFDoc(pPDFDoc), - m_pSDKDoc(nullptr), - m_pXFADoc(nullptr), - m_pXFADocView(nullptr), - m_pApp(pProvider), - m_pJSContext(nullptr) { -} - -CPDFXFA_Document::~CPDFXFA_Document() { - if (m_pJSContext && m_pSDKDoc && m_pSDKDoc->GetEnv()) - m_pSDKDoc->GetEnv()->GetJSRuntime()->ReleaseContext(m_pJSContext); - - delete m_pSDKDoc; - - if (m_pPDFDoc) { - CPDF_Parser* pParser = m_pPDFDoc->GetParser(); - if (pParser) - delete pParser; - else - delete m_pPDFDoc; - } - if (m_pXFADoc) { - IXFA_App* pApp = m_pApp->GetXFAApp(); - if (pApp) { - IXFA_DocHandler* pDocHandler = pApp->GetDocHandler(); - if (pDocHandler) { - CloseXFADoc(pDocHandler); - } - } - delete m_pXFADoc; - } -} - -FX_BOOL CPDFXFA_Document::LoadXFADoc() { - if (!m_pPDFDoc) - return FALSE; - - m_XFAPageList.RemoveAll(); - - IXFA_App* pApp = m_pApp->GetXFAApp(); - if (!pApp) - return FALSE; - - m_pXFADoc = pApp->CreateDoc(this, m_pPDFDoc); - if (!m_pXFADoc) { - SetLastError(FPDF_ERR_XFALOAD); - return FALSE; - } - - IXFA_DocHandler* pDocHandler = pApp->GetDocHandler(); - if (!pDocHandler) { - SetLastError(FPDF_ERR_XFALOAD); - return FALSE; - } - - pDocHandler->StartLoad(m_pXFADoc); - int iStatus = pDocHandler->DoLoad(m_pXFADoc, NULL); - if (iStatus != XFA_PARSESTATUS_Done) { - CloseXFADoc(pDocHandler); - SetLastError(FPDF_ERR_XFALOAD); - return FALSE; - } - pDocHandler->StopLoad(m_pXFADoc); - pDocHandler->SetJSERuntime(m_pXFADoc, m_pApp->GetJSERuntime()); - - if (pDocHandler->GetDocType(m_pXFADoc) == XFA_DOCTYPE_Dynamic) - m_iDocType = DOCTYPE_DYNAMIC_XFA; - else - m_iDocType = DOCTYPE_STATIC_XFA; - - m_pXFADocView = pDocHandler->CreateDocView(m_pXFADoc, XFA_DOCVIEW_View); - if (m_pXFADocView->StartLayout() < 0) { - CloseXFADoc(pDocHandler); - SetLastError(FPDF_ERR_XFALAYOUT); - return FALSE; - } - - m_pXFADocView->DoLayout(NULL); - m_pXFADocView->StopLayout(); - return TRUE; -} - -int CPDFXFA_Document::GetPageCount() { - if (!m_pPDFDoc && !m_pXFADoc) - return 0; - - switch (m_iDocType) { - case DOCTYPE_PDF: - case DOCTYPE_STATIC_XFA: - if (m_pPDFDoc) - return m_pPDFDoc->GetPageCount(); - case DOCTYPE_DYNAMIC_XFA: - if (m_pXFADoc) - return m_pXFADocView->CountPageViews(); - default: - return 0; - } - - return 0; -} - -CPDFXFA_Page* CPDFXFA_Document::GetPage(int page_index) { - if (page_index < 0) - return nullptr; - CPDFXFA_Page* pPage = nullptr; - int nCount = m_XFAPageList.GetSize(); - if (nCount > 0 && page_index < nCount) { - pPage = m_XFAPageList.GetAt(page_index); - if (pPage) - pPage->AddRef(); - } else { - m_XFAPageList.SetSize(GetPageCount()); - } - if (pPage) - return pPage; - pPage = new CPDFXFA_Page(this, page_index); - if (!pPage->LoadPage()) { - delete pPage; - return nullptr; - } - m_XFAPageList.SetAt(page_index, pPage); - return pPage; -} - -CPDFXFA_Page* CPDFXFA_Document::GetPage(IXFA_PageView* pPage) { - if (!pPage) - return NULL; - - if (!m_pXFADoc) - return NULL; - - if (m_iDocType != DOCTYPE_DYNAMIC_XFA) - return NULL; - - int nSize = m_XFAPageList.GetSize(); - for (int i = 0; i < nSize; i++) { - CPDFXFA_Page* pTempPage = m_XFAPageList.GetAt(i); - if (!pTempPage) - continue; - if (pTempPage->GetXFAPageView() && pTempPage->GetXFAPageView() == pPage) - return pTempPage; - } - - return NULL; -} - -void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) { - m_XFAPageList.SetAt(page->GetPageIndex(), NULL); -} - -CPDFSDK_Document* CPDFXFA_Document::GetSDKDocument( - CPDFDoc_Environment* pFormFillEnv) { - if (!m_pSDKDoc && pFormFillEnv) - m_pSDKDoc = new CPDFSDK_Document(this, pFormFillEnv); - return m_pSDKDoc; -} - -void CPDFXFA_Document::FXRect2PDFRect(const CFX_RectF& fxRectF, - CPDF_Rect& pdfRect) { - pdfRect.left = fxRectF.left; - pdfRect.top = fxRectF.bottom(); - pdfRect.right = fxRectF.right(); - pdfRect.bottom = fxRectF.top; -} - -void CPDFXFA_Document::SetChangeMark(IXFA_Doc* hDoc) { - if (hDoc == m_pXFADoc && m_pSDKDoc) { - m_pSDKDoc->SetChangeMark(); - } -} - -FX_BOOL CPDFXFA_Document::GetChangeMark(IXFA_Doc* hDoc) { - if (hDoc == m_pXFADoc && m_pSDKDoc) - return m_pSDKDoc->GetChangeMark(); - return FALSE; -} - -void CPDFXFA_Document::InvalidateRect(IXFA_PageView* pPageView, - const CFX_RectF& rt, - FX_DWORD dwFlags /* = 0 */) { - if (!m_pXFADoc || !m_pSDKDoc) - return; - - if (m_iDocType != DOCTYPE_DYNAMIC_XFA) - return; - - CPDF_Rect rcPage; - FXRect2PDFRect(rt, rcPage); - - CPDFXFA_Page* pPage = GetPage(pPageView); - - if (pPage == NULL) - return; - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (!pEnv) - return; - - pEnv->FFI_Invalidate((FPDF_PAGE)pPage, rcPage.left, rcPage.bottom, - rcPage.right, rcPage.top); -} - -void CPDFXFA_Document::InvalidateRect(IXFA_Widget* hWidget, - FX_DWORD dwFlags /* = 0 */) { - if (!hWidget) - return; - - if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView) - return; - - if (m_iDocType != DOCTYPE_DYNAMIC_XFA) - return; - - IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); - if (!pWidgetHandler) - return; - - IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget); - if (!pPageView) - return; - - CFX_RectF rect; - pWidgetHandler->GetRect(hWidget, rect); - InvalidateRect(pPageView, rect, dwFlags); -} - -void CPDFXFA_Document::DisplayCaret(IXFA_Widget* hWidget, - FX_BOOL bVisible, - const CFX_RectF* pRtAnchor) { - if (!hWidget || pRtAnchor == NULL) - return; - - if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView) - return; - - if (m_iDocType != DOCTYPE_DYNAMIC_XFA) - return; - - IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); - if (!pWidgetHandler) - return; - - IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget); - if (!pPageView) - return; - - CPDFXFA_Page* pPage = GetPage(pPageView); - - if (pPage == NULL) - return; - - CPDF_Rect rcCaret; - FXRect2PDFRect(*pRtAnchor, rcCaret); - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (!pEnv) - return; - - pEnv->FFI_DisplayCaret((FPDF_PAGE)pPage, bVisible, rcCaret.left, rcCaret.top, - rcCaret.right, rcCaret.bottom); -} - -FX_BOOL CPDFXFA_Document::GetPopupPos(IXFA_Widget* hWidget, - FX_FLOAT fMinPopup, - FX_FLOAT fMaxPopup, - const CFX_RectF& rtAnchor, - CFX_RectF& rtPopup) { - if (NULL == hWidget) { - return FALSE; - } - IXFA_PageView* pXFAPageView = - m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget); - if (NULL == pXFAPageView) { - return FALSE; - } - CPDFXFA_Page* pPage = GetPage(pXFAPageView); - if (pPage == NULL) - return FALSE; - - CXFA_WidgetAcc* pWidgetAcc = - m_pXFADocView->GetWidgetHandler()->GetDataAcc(hWidget); - - int nRotate = 0; -#ifdef PDF_ENABLE_XFA - nRotate = pWidgetAcc->GetRotate(); -#endif - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return FALSE; - FS_RECTF pageViewRect; - pEnv->FFI_GetPageViewRect(pPage, pageViewRect); - - CPDF_Rect rcAnchor; - - rcAnchor.left = rtAnchor.left; - rcAnchor.top = rtAnchor.bottom(); - rcAnchor.right = rtAnchor.right(); - rcAnchor.bottom = rtAnchor.top; - - int t1, t2, t; - FX_DWORD dwPos; - FX_FLOAT fPoupHeight; - switch (nRotate) { - case 90: { - t1 = (int)(pageViewRect.right - rcAnchor.right); - t2 = (int)(rcAnchor.left - pageViewRect.left); - if (rcAnchor.bottom < pageViewRect.bottom) { - rtPopup.left += rcAnchor.bottom - pageViewRect.bottom; - } - - break; - } - - case 180: { - t2 = (int)(pageViewRect.top - rcAnchor.top); - t1 = (int)(rcAnchor.bottom - pageViewRect.bottom); - if (rcAnchor.left < pageViewRect.left) { - rtPopup.left += rcAnchor.left - pageViewRect.left; - } - break; - } - case 270: { - t1 = (int)(rcAnchor.left - pageViewRect.left); - t2 = (int)(pageViewRect.right - rcAnchor.right); - - if (rcAnchor.top > pageViewRect.top) { - rtPopup.left -= rcAnchor.top - pageViewRect.top; - } - break; - } - case 0: - default: { - t1 = (int)(pageViewRect.top - rcAnchor.top); - t2 = (int)(rcAnchor.bottom - pageViewRect.bottom); - if (rcAnchor.right > pageViewRect.right) { - rtPopup.left -= rcAnchor.right - pageViewRect.right; - } - break; - } - } - - if (t1 <= 0 && t2 <= 0) { - return FALSE; - } - if (t1 <= 0) { - t = t2; - dwPos = 1; - } else if (t2 <= 0) { - t = t1; - dwPos = 0; - } else if (t1 > t2) { - t = t1; - dwPos = 0; - } else { - t = t2; - dwPos = 1; - } - if (t < fMinPopup) { - fPoupHeight = fMinPopup; - } else if (t > fMaxPopup) { - fPoupHeight = fMaxPopup; - } else { - fPoupHeight = (FX_FLOAT)t; - } - - switch (nRotate) { - case 0: - case 180: { - if (dwPos == 0) { - rtPopup.top = rtAnchor.height; - rtPopup.height = fPoupHeight; - } else { - rtPopup.top = -fPoupHeight; - rtPopup.height = fPoupHeight; - } - break; - } - case 90: - case 270: { - if (dwPos == 0) { - rtPopup.top = rtAnchor.width; - rtPopup.height = fPoupHeight; - } else { - rtPopup.top = -fPoupHeight; - rtPopup.height = fPoupHeight; - } - break; - } - default: - break; - } - - return TRUE; -} - -FX_BOOL CPDFXFA_Document::PopupMenu(IXFA_Widget* hWidget, - CFX_PointF ptPopup, - const CFX_RectF* pRectExclude) { - if (NULL == hWidget) { - return FALSE; - } - IXFA_PageView* pXFAPageView = - m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget); - if (pXFAPageView == NULL) - return FALSE; - CPDFXFA_Page* pPage = GetPage(pXFAPageView); - - if (pPage == NULL) - return FALSE; - - int menuFlag = 0; - - IXFA_MenuHandler* pXFAMenuHander = m_pApp->GetXFAApp()->GetMenuHandler(); - if (pXFAMenuHander->CanUndo(hWidget)) - menuFlag |= FXFA_MEMU_UNDO; - if (pXFAMenuHander->CanRedo(hWidget)) - menuFlag |= FXFA_MEMU_REDO; - if (pXFAMenuHander->CanPaste(hWidget)) - menuFlag |= FXFA_MEMU_PASTE; - if (pXFAMenuHander->CanCopy(hWidget)) - menuFlag |= FXFA_MEMU_COPY; - if (pXFAMenuHander->CanCut(hWidget)) - menuFlag |= FXFA_MEMU_CUT; - if (pXFAMenuHander->CanSelectAll(hWidget)) - menuFlag |= FXFA_MEMU_SELECTALL; - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return FALSE; - - return pEnv->FFI_PopupMenu(pPage, hWidget, menuFlag, ptPopup, NULL); -} - -void CPDFXFA_Document::PageViewEvent(IXFA_PageView* pPageView, - FX_DWORD dwFlags) { - if (!pPageView || (dwFlags != XFA_PAGEVIEWEVENT_PostAdded && - dwFlags != XFA_PAGEVIEWEVENT_PostRemoved)) { - return; - } - CPDFXFA_Page* pPage = nullptr; - if (dwFlags == XFA_PAGEVIEWEVENT_PostAdded) { - pPage = GetPage(pPageView->GetPageViewIndex()); - if (pPage) - pPage->SetXFAPageView(pPageView); - return; - } - pPage = GetPage(pPageView); - if (!pPage) - return; - pPage->SetXFAPageView(nullptr); - m_pSDKDoc->GetPageView(pPage)->ClearFXAnnots(); -} - -void CPDFXFA_Document::WidgetEvent(IXFA_Widget* hWidget, - CXFA_WidgetAcc* pWidgetData, - FX_DWORD dwEvent, - void* pParam, - void* pAdditional) { - if (m_iDocType != DOCTYPE_DYNAMIC_XFA || !hWidget) - return; - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (!pEnv) - return; - - IXFA_PageView* pPageView = - m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget); - if (pPageView == NULL) - return; - - CPDFXFA_Page* pXFAPage = GetPage(pPageView); - if (pXFAPage == NULL) - return; - - CPDFSDK_PageView* pSdkPageView = m_pSDKDoc->GetPageView(pXFAPage); - if (dwEvent == XFA_WIDGETEVENT_PostAdded) { - pSdkPageView->AddAnnot(hWidget); - - } else if (dwEvent == XFA_WIDGETEVENT_PreRemoved) { - CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget); - if (pAnnot) { - pSdkPageView->DeleteAnnot(pAnnot); - } - } -} - -int32_t CPDFXFA_Document::CountPages(IXFA_Doc* hDoc) { - if (hDoc == m_pXFADoc && m_pSDKDoc) { - return GetPageCount(); - } - return 0; -} -int32_t CPDFXFA_Document::GetCurrentPage(IXFA_Doc* hDoc) { - if (hDoc != m_pXFADoc || !m_pSDKDoc) - return -1; - if (m_iDocType != DOCTYPE_DYNAMIC_XFA) - return -1; - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return -1; - - return pEnv->FFI_GetCurrentPageIndex(this); -} -void CPDFXFA_Document::SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage) { - if (hDoc != m_pXFADoc || !m_pSDKDoc) - return; - if (m_iDocType != DOCTYPE_DYNAMIC_XFA) - return; - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return; - - pEnv->FFI_SetCurrentPage(this, iCurPage); -} -FX_BOOL CPDFXFA_Document::IsCalculationsEnabled(IXFA_Doc* hDoc) { - if (hDoc != m_pXFADoc || !m_pSDKDoc) - return FALSE; - if (m_pSDKDoc->GetInterForm()) - return m_pSDKDoc->GetInterForm()->IsXfaCalculateEnabled(); - - return FALSE; -} -void CPDFXFA_Document::SetCalculationsEnabled(IXFA_Doc* hDoc, - FX_BOOL bEnabled) { - if (hDoc != m_pXFADoc || !m_pSDKDoc) - return; - if (m_pSDKDoc->GetInterForm()) - m_pSDKDoc->GetInterForm()->XfaEnableCalculate(bEnabled); -} - -void CPDFXFA_Document::GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle) { - if (hDoc != m_pXFADoc) - return; - if (m_pPDFDoc == NULL) - return; - CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo(); - - if (pInfoDict == NULL) - return; - - CFX_ByteString csTitle = pInfoDict->GetString("Title"); - wsTitle = wsTitle.FromLocal(csTitle.GetBuffer(csTitle.GetLength())); - csTitle.ReleaseBuffer(csTitle.GetLength()); -} -void CPDFXFA_Document::SetTitle(IXFA_Doc* hDoc, - const CFX_WideStringC& wsTitle) { - if (hDoc != m_pXFADoc) - return; - if (m_pPDFDoc == NULL) - return; - CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo(); - - if (pInfoDict == NULL) - return; - pInfoDict->SetAt("Title", new CPDF_String(wsTitle)); -} -void CPDFXFA_Document::ExportData(IXFA_Doc* hDoc, - const CFX_WideStringC& wsFilePath, - FX_BOOL bXDP) { - if (hDoc != m_pXFADoc) - return; - if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA) - return; - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return; - int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML; - CFX_ByteString bs = CFX_WideString(wsFilePath).UTF16LE_Encode(); - - if (wsFilePath.IsEmpty()) { - if (!pEnv->GetFormFillInfo() || - pEnv->GetFormFillInfo()->m_pJsPlatform == NULL) - return; - CFX_WideString filepath = pEnv->JS_fieldBrowse(); - bs = filepath.UTF16LE_Encode(); - } - int len = bs.GetLength() / sizeof(unsigned short); - FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile( - bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML, - (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "wb"); - bs.ReleaseBuffer(len * sizeof(unsigned short)); - - if (pFileHandler == NULL) - return; - - CFPDF_FileStream fileWrite(pFileHandler); - - IXFA_DocHandler* pXFADocHander = m_pApp->GetXFAApp()->GetDocHandler(); - CFX_ByteString content; - if (fileType == FXFA_SAVEAS_XML) { - content = "\r\n"; - fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(), - content.GetLength()); - CFX_WideStringC data(L"data"); - if (pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), data, &fileWrite)) { - // TODO: Maybe report error. - } - } else if (fileType == FXFA_SAVEAS_XDP) { - if (m_pPDFDoc == NULL) - return; - CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot(); - if (pRoot == NULL) - return; - CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm"); - if (NULL == pAcroForm) - return; - CPDF_Object* pXFA = pAcroForm->GetElement("XFA"); - if (pXFA == NULL) - return; - if (!pXFA->IsArray()) - return; - CPDF_Array* pArray = pXFA->GetArray(); - if (NULL == pArray) - return; - int size = pArray->GetCount(); - for (int i = 1; i < size; i += 2) { - CPDF_Object* pPDFObj = pArray->GetElement(i); - CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1); - if (!pPrePDFObj->IsString()) - continue; - if (!pPDFObj->IsReference()) - continue; - CPDF_Object* pDirectObj = pPDFObj->GetDirect(); - if (!pDirectObj->IsStream()) - continue; - if (pPrePDFObj->GetString() == "form") { - CFX_WideStringC form(L"form"); - pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), form, &fileWrite); - } else if (pPrePDFObj->GetString() == "datasets") { - CFX_WideStringC datasets(L"datasets"); - pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), datasets, - &fileWrite); - } else { - if (i == size - 1) { - CFX_WideString wPath = CFX_WideString::FromUTF16LE( - (unsigned short*)(const FX_CHAR*)bs, - bs.GetLength() / sizeof(unsigned short)); - CFX_ByteString bPath = wPath.UTF8Encode(); - CFX_ByteString szFormat = - "\n"; - content.Format(szFormat, (char*)(const FX_CHAR*)bPath); - fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(), - content.GetLength()); - } - - CPDF_Stream* pStream = (CPDF_Stream*)pDirectObj; - CPDF_StreamAcc* pAcc = new CPDF_StreamAcc; - pAcc->LoadAllData(pStream); - fileWrite.WriteBlock(pAcc->GetData(), fileWrite.GetSize(), - pAcc->GetSize()); - delete pAcc; - } - } - } - if (!fileWrite.Flush()) { - // TODO: Report error. - } -} -void CPDFXFA_Document::ImportData(IXFA_Doc* hDoc, - const CFX_WideStringC& wsFilePath) { - // TODO... -} - -void CPDFXFA_Document::GotoURL(IXFA_Doc* hDoc, - const CFX_WideStringC& bsURL, - FX_BOOL bAppend) { - if (hDoc != m_pXFADoc) - return; - - if (m_iDocType != DOCTYPE_DYNAMIC_XFA) - return; - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return; - - CFX_WideStringC str(bsURL.GetPtr()); - - pEnv->FFI_GotoURL(this, str, bAppend); -} - -FX_BOOL CPDFXFA_Document::IsValidationsEnabled(IXFA_Doc* hDoc) { - if (hDoc != m_pXFADoc || !m_pSDKDoc) - return FALSE; - if (m_pSDKDoc->GetInterForm()) - return m_pSDKDoc->GetInterForm()->IsXfaValidationsEnabled(); - - return TRUE; -} -void CPDFXFA_Document::SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled) { - if (hDoc != m_pXFADoc || !m_pSDKDoc) - return; - if (m_pSDKDoc->GetInterForm()) - m_pSDKDoc->GetInterForm()->XfaSetValidationsEnabled(bEnabled); -} -void CPDFXFA_Document::SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget) { - if (hDoc != m_pXFADoc) - return; - - if (NULL == hWidget) { - m_pSDKDoc->SetFocusAnnot(NULL); - return; - } - - int pageViewCount = m_pSDKDoc->GetPageViewCount(); - for (int i = 0; i < pageViewCount; i++) { - CPDFSDK_PageView* pPageView = m_pSDKDoc->GetPageView(i); - if (pPageView == NULL) - continue; - CPDFSDK_Annot* pAnnot = pPageView->GetAnnotByXFAWidget(hWidget); - if (pAnnot) { - m_pSDKDoc->SetFocusAnnot(pAnnot); - break; - } - } -} -void CPDFXFA_Document::Print(IXFA_Doc* hDoc, - int32_t nStartPage, - int32_t nEndPage, - FX_DWORD dwOptions) { - if (hDoc != m_pXFADoc) - return; - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return; - - if (!pEnv->GetFormFillInfo() || - pEnv->GetFormFillInfo()->m_pJsPlatform == NULL) - return; - if (pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print == NULL) - return; - pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print( - pEnv->GetFormFillInfo()->m_pJsPlatform, - dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage, - dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage, - dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder, - dwOptions & XFA_PRINTOPT_PrintAnnot); -} - -void CPDFXFA_Document::GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL) { - if (hDoc != m_pXFADoc) - return; - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return; - - pEnv->FFI_GetURL(this, wsDocURL); -} - -FX_ARGB CPDFXFA_Document::GetHighlightColor(IXFA_Doc* hDoc) { - if (hDoc != m_pXFADoc) - return 0; - if (m_pSDKDoc) { - if (CPDFSDK_InterForm* pInterForm = m_pSDKDoc->GetInterForm()) { - FX_COLORREF color = pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA); - uint8_t alpha = pInterForm->GetHighlightAlpha(); - FX_ARGB argb = ArgbEncode((int)alpha, color); - return argb; - } - } - return 0; -} - -FX_BOOL CPDFXFA_Document::_NotifySubmit(FX_BOOL bPrevOrPost) { - if (bPrevOrPost) - return _OnBeforeNotifySumbit(); - - _OnAfterNotifySumbit(); - return TRUE; -} - -FX_BOOL CPDFXFA_Document::_OnBeforeNotifySumbit() { -#ifdef PDF_ENABLE_XFA - if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA) - return TRUE; - if (m_pXFADocView == NULL) - return TRUE; - IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); - if (pWidgetHandler == NULL) - return TRUE; - IXFA_WidgetAccIterator* pWidgetAccIterator = - m_pXFADocView->CreateWidgetAccIterator(); - if (pWidgetAccIterator) { - CXFA_EventParam Param; - Param.m_eType = XFA_EVENT_PreSubmit; - CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); - while (pWidgetAcc) { - pWidgetHandler->ProcessEvent(pWidgetAcc, &Param); - pWidgetAcc = pWidgetAccIterator->MoveToNext(); - } - pWidgetAccIterator->Release(); - } - pWidgetAccIterator = m_pXFADocView->CreateWidgetAccIterator(); - if (pWidgetAccIterator) { - CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); - pWidgetAcc = pWidgetAccIterator->MoveToNext(); - while (pWidgetAcc) { - int fRet = pWidgetAcc->ProcessValidate(-1); - if (fRet == XFA_EVENTERROR_Error) { - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return FALSE; - CFX_WideString ws; - ws.FromLocal(IDS_XFA_Validate_Input); - CFX_ByteString bs = ws.UTF16LE_Encode(); - int len = bs.GetLength() / sizeof(unsigned short); - pEnv->FFI_Alert( - (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), - (FPDF_WIDESTRING)L"", 0, 1); - bs.ReleaseBuffer(len * sizeof(unsigned short)); - pWidgetAccIterator->Release(); - return FALSE; - } - pWidgetAcc = pWidgetAccIterator->MoveToNext(); - } - pWidgetAccIterator->Release(); - m_pXFADocView->UpdateDocView(); - } -#endif - return TRUE; -} -void CPDFXFA_Document::_OnAfterNotifySumbit() { - if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA) - return; - if (m_pXFADocView == NULL) - return; - IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); - if (pWidgetHandler == NULL) - return; - IXFA_WidgetAccIterator* pWidgetAccIterator = - m_pXFADocView->CreateWidgetAccIterator(); - if (pWidgetAccIterator == NULL) - return; - CXFA_EventParam Param; - Param.m_eType = XFA_EVENT_PostSubmit; - - CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); - while (pWidgetAcc) { - pWidgetHandler->ProcessEvent(pWidgetAcc, &Param); - pWidgetAcc = pWidgetAccIterator->MoveToNext(); - } - pWidgetAccIterator->Release(); - m_pXFADocView->UpdateDocView(); -} - -FX_BOOL CPDFXFA_Document::SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) { - if (!_NotifySubmit(TRUE)) - return FALSE; - if (NULL == m_pXFADocView) - return FALSE; - m_pXFADocView->UpdateDocView(); - - FX_BOOL ret = _SubmitData(hDoc, submit); - _NotifySubmit(FALSE); - return ret; -} - -IFX_FileRead* CPDFXFA_Document::OpenLinkedFile(IXFA_Doc* hDoc, - const CFX_WideString& wsLink) { - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return FALSE; - CFX_ByteString bs = wsLink.UTF16LE_Encode(); - int len = bs.GetLength() / sizeof(unsigned short); - FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile( - 0, (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "rb"); - bs.ReleaseBuffer(len * sizeof(unsigned short)); - - if (pFileHandler == NULL) - return NULL; - return new CFPDF_FileStream(pFileHandler); -} -FX_BOOL CPDFXFA_Document::_ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler, - int fileType, - FPDF_DWORD encodeType, - FPDF_DWORD flag) { - if (NULL == m_pXFADocView) - return FALSE; - IXFA_DocHandler* pDocHandler = m_pApp->GetXFAApp()->GetDocHandler(); - CFX_ByteString content; - - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return FALSE; - - CFPDF_FileStream fileStream(pFileHandler); - - if (fileType == FXFA_SAVEAS_XML) { - CFX_WideString ws; - ws.FromLocal("data"); - CFX_ByteString content = "\r\n"; - fileStream.WriteBlock((const FX_CHAR*)content, 0, content.GetLength()); - pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream); - } else if (fileType == FXFA_SAVEAS_XDP) { - if (flag == 0) - flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS | - FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM; - if (m_pPDFDoc == NULL) { - fileStream.Flush(); - return FALSE; - } - CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot(); - if (pRoot == NULL) { - fileStream.Flush(); - return FALSE; - } - CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm"); - if (NULL == pAcroForm) { - fileStream.Flush(); - return FALSE; - } - CPDF_Object* pXFA = pAcroForm->GetElement("XFA"); - if (pXFA == NULL) { - fileStream.Flush(); - return FALSE; - } - if (!pXFA->IsArray()) { - fileStream.Flush(); - return FALSE; - } - CPDF_Array* pArray = pXFA->GetArray(); - if (NULL == pArray) { - fileStream.Flush(); - return FALSE; - } - int size = pArray->GetCount(); - for (int i = 1; i < size; i += 2) { - CPDF_Object* pPDFObj = pArray->GetElement(i); - CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1); - if (!pPrePDFObj->IsString()) - continue; - if (!pPDFObj->IsReference()) - continue; - CPDF_Object* pDirectObj = pPDFObj->GetDirect(); - if (!pDirectObj->IsStream()) - continue; - if (pPrePDFObj->GetString() == "config" && !(flag & FXFA_CONFIG)) - continue; - if (pPrePDFObj->GetString() == "template" && !(flag & FXFA_TEMPLATE)) - continue; - if (pPrePDFObj->GetString() == "localeSet" && !(flag & FXFA_LOCALESET)) - continue; - if (pPrePDFObj->GetString() == "datasets" && !(flag & FXFA_DATASETS)) - continue; - if (pPrePDFObj->GetString() == "xmpmeta" && !(flag & FXFA_XMPMETA)) - continue; - if (pPrePDFObj->GetString() == "xfdf" && !(flag & FXFA_XFDF)) - continue; - if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM)) - continue; - if (pPrePDFObj->GetString() == "form") { - CFX_WideString ws; - ws.FromLocal("form"); - pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream); - } else if (pPrePDFObj->GetString() == "datasets") { - CFX_WideString ws; - ws.FromLocal("datasets"); - pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream); - } else { - // PDF,creator. - // TODO: - } - } - } - return TRUE; -} - -void CPDFXFA_Document::_ClearChangeMark() { - if (m_pSDKDoc) - m_pSDKDoc->ClearChangeMark(); -} - -void CPDFXFA_Document::_ToXFAContentFlags(CFX_WideString csSrcContent, - FPDF_DWORD& flag) { - if (csSrcContent.Find(L" config ", 0) != -1) - flag |= FXFA_CONFIG; - if (csSrcContent.Find(L" template ", 0) != -1) - flag |= FXFA_TEMPLATE; - if (csSrcContent.Find(L" localeSet ", 0) != -1) - flag |= FXFA_LOCALESET; - if (csSrcContent.Find(L" datasets ", 0) != -1) - flag |= FXFA_DATASETS; - if (csSrcContent.Find(L" xmpmeta ", 0) != -1) - flag |= FXFA_XMPMETA; - if (csSrcContent.Find(L" xfdf ", 0) != -1) - flag |= FXFA_XFDF; - if (csSrcContent.Find(L" form ", 0) != -1) - flag |= FXFA_FORM; - if (flag == 0) - flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS | - FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM; -} -FX_BOOL CPDFXFA_Document::_MailToInfo(CFX_WideString& csURL, - CFX_WideString& csToAddress, - CFX_WideString& csCCAddress, - CFX_WideString& csBCCAddress, - CFX_WideString& csSubject, - CFX_WideString& csMsg) { - CFX_WideString srcURL = csURL; - srcURL.TrimLeft(); - if (0 != srcURL.Left(7).CompareNoCase(L"mailto:")) - return FALSE; - int pos = srcURL.Find(L'?', 0); - CFX_WideString tmp; - if (pos == -1) { - pos = srcURL.Find(L'@', 0); - if (pos == -1) - return FALSE; - else { - tmp = srcURL.Right(csURL.GetLength() - 7); - tmp.TrimLeft(); - tmp.TrimRight(); - } - } else { - tmp = srcURL.Left(pos); - tmp = tmp.Right(tmp.GetLength() - 7); - tmp.TrimLeft(); - tmp.TrimRight(); - } - - csToAddress = tmp; - - srcURL = srcURL.Right(srcURL.GetLength() - (pos + 1)); - while (!srcURL.IsEmpty()) { - srcURL.TrimLeft(); - srcURL.TrimRight(); - pos = srcURL.Find(L'&', 0); - if (pos == -1) - tmp = srcURL; - else - tmp = srcURL.Left(pos); - - tmp.TrimLeft(); - tmp.TrimRight(); - if (tmp.GetLength() >= 3 && 0 == tmp.Left(3).CompareNoCase(L"cc=")) { - tmp = tmp.Right(tmp.GetLength() - 3); - if (!csCCAddress.IsEmpty()) - csCCAddress += L';'; - csCCAddress += tmp; - - } else if (tmp.GetLength() >= 4 && - 0 == tmp.Left(4).CompareNoCase(L"bcc=")) { - tmp = tmp.Right(tmp.GetLength() - 4); - if (!csBCCAddress.IsEmpty()) - csBCCAddress += L';'; - csBCCAddress += tmp; - } else if (tmp.GetLength() >= 8 && - 0 == tmp.Left(8).CompareNoCase(L"subject=")) { - tmp = tmp.Right(tmp.GetLength() - 8); - csSubject += tmp; - } else if (tmp.GetLength() >= 5 && - 0 == tmp.Left(5).CompareNoCase(L"body=")) { - tmp = tmp.Right(tmp.GetLength() - 5); - csMsg += tmp; - } - if (pos == -1) - srcURL = L""; - else - srcURL = srcURL.Right(csURL.GetLength() - (pos + 1)); - } - csToAddress.Replace(L",", L";"); - csCCAddress.Replace(L",", L";"); - csBCCAddress.Replace(L",", L";"); - return TRUE; -} - -FX_BOOL CPDFXFA_Document::_SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) { -#ifdef PDF_ENABLE_XFA - CFX_WideStringC csURLC; - submit.GetSubmitTarget(csURLC); - CFX_WideString csURL = csURLC; - CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (pEnv == NULL) - return FALSE; - if (csURL.IsEmpty()) { - CFX_WideString ws; - ws.FromLocal("Submit cancelled."); - CFX_ByteString bs = ws.UTF16LE_Encode(); - int len = bs.GetLength() / sizeof(unsigned short); - pEnv->FFI_Alert((FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), - (FPDF_WIDESTRING)L"", 0, 4); - bs.ReleaseBuffer(len * sizeof(unsigned short)); - return FALSE; - } - - FPDF_BOOL bRet = TRUE; - FPDF_FILEHANDLER* pFileHandler = NULL; - int fileFlag = -1; - - if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xdp) { - CFX_WideStringC csContentC; - submit.GetSubmitXDPContent(csContentC); - CFX_WideString csContent; - csContent = csContentC.GetPtr(); - csContent.TrimLeft(); - csContent.TrimRight(); - CFX_WideString space; - space.FromLocal(" "); - csContent = space + csContent + space; - FPDF_DWORD flag = 0; - if (submit.IsSubmitEmbedPDF()) - flag |= FXFA_PDF; - _ToXFAContentFlags(csContent, flag); - pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XDP, NULL, "wb"); - fileFlag = FXFA_SAVEAS_XDP; - _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag); - } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xml) { - pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb"); - fileFlag = FXFA_SAVEAS_XML; - _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0); - } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Pdf) { - // csfilename = csDocName; - } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Formdata) { - return FALSE; - } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Urlencoded) { - pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb"); - fileFlag = FXFA_SAVEAS_XML; - _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0); - } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xfd) { - return FALSE; - } else { - return FALSE; - } - if (pFileHandler == NULL) - return FALSE; - if (0 == csURL.Left(7).CompareNoCase(L"mailto:")) { - CFX_WideString csToAddress; - CFX_WideString csCCAddress; - CFX_WideString csBCCAddress; - CFX_WideString csSubject; - CFX_WideString csMsg; - - bRet = _MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject, - csMsg); - if (FALSE == bRet) - return FALSE; - - CFX_ByteString bsTo = CFX_WideString(csToAddress).UTF16LE_Encode(); - CFX_ByteString bsCC = CFX_WideString(csCCAddress).UTF16LE_Encode(); - CFX_ByteString bsBcc = CFX_WideString(csBCCAddress).UTF16LE_Encode(); - CFX_ByteString bsSubject = CFX_WideString(csSubject).UTF16LE_Encode(); - CFX_ByteString bsMsg = CFX_WideString(csMsg).UTF16LE_Encode(); - - FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength()); - FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength()); - FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength()); - FPDF_WIDESTRING pSubject = - (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength()); - FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength()); - - pEnv->FFI_EmailTo(pFileHandler, pTo, pSubject, pCC, pBcc, pMsg); - bsTo.ReleaseBuffer(); - bsCC.ReleaseBuffer(); - bsBcc.ReleaseBuffer(); - bsSubject.ReleaseBuffer(); - bsMsg.ReleaseBuffer(); - } else { - // http¡¢ftp - CFX_WideString ws; - CFX_ByteString bs = csURL.UTF16LE_Encode(); - int len = bs.GetLength() / sizeof(unsigned short); - pEnv->FFI_UploadTo( - pFileHandler, fileFlag, - (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short))); - bs.ReleaseBuffer(len * sizeof(unsigned short)); - } - - return bRet; -#else - return TRUE; -#endif -} - -FX_BOOL CPDFXFA_Document::SetGlobalProperty(IXFA_Doc* hDoc, - const CFX_ByteStringC& szPropName, - FXJSE_HVALUE hValue) { - if (hDoc != m_pXFADoc) - return FALSE; - - if (m_pSDKDoc && m_pSDKDoc->GetEnv()->GetJSRuntime()) - return m_pSDKDoc->GetEnv()->GetJSRuntime()->SetHValueByName(szPropName, - hValue); - return FALSE; -} -FX_BOOL CPDFXFA_Document::GetPDFScriptObject(IXFA_Doc* hDoc, - const CFX_ByteStringC& utf8Name, - FXJSE_HVALUE hValue) { - if (hDoc != m_pXFADoc) - return FALSE; - - if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime()) - return FALSE; - - if (!m_pJSContext) { - m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc); - m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext(); - } - - return _GetHValueByName(utf8Name, hValue, - m_pSDKDoc->GetEnv()->GetJSRuntime()); -} -FX_BOOL CPDFXFA_Document::GetGlobalProperty(IXFA_Doc* hDoc, - const CFX_ByteStringC& szPropName, - FXJSE_HVALUE hValue) { - if (hDoc != m_pXFADoc) - return FALSE; - if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime()) - return FALSE; - - if (!m_pJSContext) { - m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc); - m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext(); - } - - return _GetHValueByName(szPropName, hValue, - m_pSDKDoc->GetEnv()->GetJSRuntime()); -} -FX_BOOL CPDFXFA_Document::_GetHValueByName(const CFX_ByteStringC& utf8Name, - FXJSE_HVALUE hValue, - IJS_Runtime* runTime) { - return runTime->GetHValueByName(utf8Name, hValue); -} +// 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 "fpdfsdk/include/fsdk_define.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" +#include "fpdfsdk/include/fsdk_mgr.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h" +#include "fpdfsdk/include/javascript/IJavaScript.h" +#include "public/fpdf_formfill.h" + +#define IDS_XFA_Validate_Input \ + "At least one required field was empty. Please fill in the required " \ + "fields\r\n(highlighted) before continuing." + +// submit +#define FXFA_CONFIG 0x00000001 +#define FXFA_TEMPLATE 0x00000010 +#define FXFA_LOCALESET 0x00000100 +#define FXFA_DATASETS 0x00001000 +#define FXFA_XMPMETA 0x00010000 +#define FXFA_XFDF 0x00100000 +#define FXFA_FORM 0x01000000 +#define FXFA_PDF 0x10000000 + +#ifndef _WIN32 +extern void SetLastError(int err); + +extern int GetLastError(); +#endif + +CPDFXFA_Document::CPDFXFA_Document(CPDF_Document* pPDFDoc, + CPDFXFA_App* pProvider) + : m_iDocType(DOCTYPE_PDF), + m_pPDFDoc(pPDFDoc), + m_pSDKDoc(nullptr), + m_pXFADoc(nullptr), + m_pXFADocView(nullptr), + m_pApp(pProvider), + m_pJSContext(nullptr) { +} + +CPDFXFA_Document::~CPDFXFA_Document() { + if (m_pJSContext && m_pSDKDoc && m_pSDKDoc->GetEnv()) + m_pSDKDoc->GetEnv()->GetJSRuntime()->ReleaseContext(m_pJSContext); + + delete m_pSDKDoc; + + if (m_pPDFDoc) { + CPDF_Parser* pParser = m_pPDFDoc->GetParser(); + if (pParser) + delete pParser; + else + delete m_pPDFDoc; + } + if (m_pXFADoc) { + IXFA_App* pApp = m_pApp->GetXFAApp(); + if (pApp) { + IXFA_DocHandler* pDocHandler = pApp->GetDocHandler(); + if (pDocHandler) { + CloseXFADoc(pDocHandler); + } + } + delete m_pXFADoc; + } +} + +FX_BOOL CPDFXFA_Document::LoadXFADoc() { + if (!m_pPDFDoc) + return FALSE; + + m_XFAPageList.RemoveAll(); + + IXFA_App* pApp = m_pApp->GetXFAApp(); + if (!pApp) + return FALSE; + + m_pXFADoc = pApp->CreateDoc(this, m_pPDFDoc); + if (!m_pXFADoc) { + SetLastError(FPDF_ERR_XFALOAD); + return FALSE; + } + + IXFA_DocHandler* pDocHandler = pApp->GetDocHandler(); + if (!pDocHandler) { + SetLastError(FPDF_ERR_XFALOAD); + return FALSE; + } + + pDocHandler->StartLoad(m_pXFADoc); + int iStatus = pDocHandler->DoLoad(m_pXFADoc, NULL); + if (iStatus != XFA_PARSESTATUS_Done) { + CloseXFADoc(pDocHandler); + SetLastError(FPDF_ERR_XFALOAD); + return FALSE; + } + pDocHandler->StopLoad(m_pXFADoc); + pDocHandler->SetJSERuntime(m_pXFADoc, m_pApp->GetJSERuntime()); + + if (pDocHandler->GetDocType(m_pXFADoc) == XFA_DOCTYPE_Dynamic) + m_iDocType = DOCTYPE_DYNAMIC_XFA; + else + m_iDocType = DOCTYPE_STATIC_XFA; + + m_pXFADocView = pDocHandler->CreateDocView(m_pXFADoc, XFA_DOCVIEW_View); + if (m_pXFADocView->StartLayout() < 0) { + CloseXFADoc(pDocHandler); + SetLastError(FPDF_ERR_XFALAYOUT); + return FALSE; + } + + m_pXFADocView->DoLayout(NULL); + m_pXFADocView->StopLayout(); + return TRUE; +} + +int CPDFXFA_Document::GetPageCount() { + if (!m_pPDFDoc && !m_pXFADoc) + return 0; + + switch (m_iDocType) { + case DOCTYPE_PDF: + case DOCTYPE_STATIC_XFA: + if (m_pPDFDoc) + return m_pPDFDoc->GetPageCount(); + case DOCTYPE_DYNAMIC_XFA: + if (m_pXFADoc) + return m_pXFADocView->CountPageViews(); + default: + return 0; + } + + return 0; +} + +CPDFXFA_Page* CPDFXFA_Document::GetPage(int page_index) { + if (page_index < 0) + return nullptr; + CPDFXFA_Page* pPage = nullptr; + int nCount = m_XFAPageList.GetSize(); + if (nCount > 0 && page_index < nCount) { + pPage = m_XFAPageList.GetAt(page_index); + if (pPage) + pPage->AddRef(); + } else { + m_XFAPageList.SetSize(GetPageCount()); + } + if (pPage) + return pPage; + pPage = new CPDFXFA_Page(this, page_index); + if (!pPage->LoadPage()) { + delete pPage; + return nullptr; + } + m_XFAPageList.SetAt(page_index, pPage); + return pPage; +} + +CPDFXFA_Page* CPDFXFA_Document::GetPage(IXFA_PageView* pPage) { + if (!pPage) + return NULL; + + if (!m_pXFADoc) + return NULL; + + if (m_iDocType != DOCTYPE_DYNAMIC_XFA) + return NULL; + + int nSize = m_XFAPageList.GetSize(); + for (int i = 0; i < nSize; i++) { + CPDFXFA_Page* pTempPage = m_XFAPageList.GetAt(i); + if (!pTempPage) + continue; + if (pTempPage->GetXFAPageView() && pTempPage->GetXFAPageView() == pPage) + return pTempPage; + } + + return NULL; +} + +void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) { + m_XFAPageList.SetAt(page->GetPageIndex(), NULL); +} + +CPDFSDK_Document* CPDFXFA_Document::GetSDKDocument( + CPDFDoc_Environment* pFormFillEnv) { + if (!m_pSDKDoc && pFormFillEnv) + m_pSDKDoc = new CPDFSDK_Document(this, pFormFillEnv); + return m_pSDKDoc; +} + +void CPDFXFA_Document::FXRect2PDFRect(const CFX_RectF& fxRectF, + CPDF_Rect& pdfRect) { + pdfRect.left = fxRectF.left; + pdfRect.top = fxRectF.bottom(); + pdfRect.right = fxRectF.right(); + pdfRect.bottom = fxRectF.top; +} + +void CPDFXFA_Document::SetChangeMark(IXFA_Doc* hDoc) { + if (hDoc == m_pXFADoc && m_pSDKDoc) { + m_pSDKDoc->SetChangeMark(); + } +} + +FX_BOOL CPDFXFA_Document::GetChangeMark(IXFA_Doc* hDoc) { + if (hDoc == m_pXFADoc && m_pSDKDoc) + return m_pSDKDoc->GetChangeMark(); + return FALSE; +} + +void CPDFXFA_Document::InvalidateRect(IXFA_PageView* pPageView, + const CFX_RectF& rt, + FX_DWORD dwFlags /* = 0 */) { + if (!m_pXFADoc || !m_pSDKDoc) + return; + + if (m_iDocType != DOCTYPE_DYNAMIC_XFA) + return; + + CPDF_Rect rcPage; + FXRect2PDFRect(rt, rcPage); + + CPDFXFA_Page* pPage = GetPage(pPageView); + + if (pPage == NULL) + return; + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (!pEnv) + return; + + pEnv->FFI_Invalidate((FPDF_PAGE)pPage, rcPage.left, rcPage.bottom, + rcPage.right, rcPage.top); +} + +void CPDFXFA_Document::InvalidateRect(IXFA_Widget* hWidget, + FX_DWORD dwFlags /* = 0 */) { + if (!hWidget) + return; + + if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView) + return; + + if (m_iDocType != DOCTYPE_DYNAMIC_XFA) + return; + + IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); + if (!pWidgetHandler) + return; + + IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget); + if (!pPageView) + return; + + CFX_RectF rect; + pWidgetHandler->GetRect(hWidget, rect); + InvalidateRect(pPageView, rect, dwFlags); +} + +void CPDFXFA_Document::DisplayCaret(IXFA_Widget* hWidget, + FX_BOOL bVisible, + const CFX_RectF* pRtAnchor) { + if (!hWidget || pRtAnchor == NULL) + return; + + if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView) + return; + + if (m_iDocType != DOCTYPE_DYNAMIC_XFA) + return; + + IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); + if (!pWidgetHandler) + return; + + IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget); + if (!pPageView) + return; + + CPDFXFA_Page* pPage = GetPage(pPageView); + + if (pPage == NULL) + return; + + CPDF_Rect rcCaret; + FXRect2PDFRect(*pRtAnchor, rcCaret); + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (!pEnv) + return; + + pEnv->FFI_DisplayCaret((FPDF_PAGE)pPage, bVisible, rcCaret.left, rcCaret.top, + rcCaret.right, rcCaret.bottom); +} + +FX_BOOL CPDFXFA_Document::GetPopupPos(IXFA_Widget* hWidget, + FX_FLOAT fMinPopup, + FX_FLOAT fMaxPopup, + const CFX_RectF& rtAnchor, + CFX_RectF& rtPopup) { + if (NULL == hWidget) { + return FALSE; + } + IXFA_PageView* pXFAPageView = + m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget); + if (NULL == pXFAPageView) { + return FALSE; + } + CPDFXFA_Page* pPage = GetPage(pXFAPageView); + if (pPage == NULL) + return FALSE; + + CXFA_WidgetAcc* pWidgetAcc = + m_pXFADocView->GetWidgetHandler()->GetDataAcc(hWidget); + + int nRotate = 0; +#ifdef PDF_ENABLE_XFA + nRotate = pWidgetAcc->GetRotate(); +#endif + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return FALSE; + FS_RECTF pageViewRect; + pEnv->FFI_GetPageViewRect(pPage, pageViewRect); + + CPDF_Rect rcAnchor; + + rcAnchor.left = rtAnchor.left; + rcAnchor.top = rtAnchor.bottom(); + rcAnchor.right = rtAnchor.right(); + rcAnchor.bottom = rtAnchor.top; + + int t1, t2, t; + FX_DWORD dwPos; + FX_FLOAT fPoupHeight; + switch (nRotate) { + case 90: { + t1 = (int)(pageViewRect.right - rcAnchor.right); + t2 = (int)(rcAnchor.left - pageViewRect.left); + if (rcAnchor.bottom < pageViewRect.bottom) { + rtPopup.left += rcAnchor.bottom - pageViewRect.bottom; + } + + break; + } + + case 180: { + t2 = (int)(pageViewRect.top - rcAnchor.top); + t1 = (int)(rcAnchor.bottom - pageViewRect.bottom); + if (rcAnchor.left < pageViewRect.left) { + rtPopup.left += rcAnchor.left - pageViewRect.left; + } + break; + } + case 270: { + t1 = (int)(rcAnchor.left - pageViewRect.left); + t2 = (int)(pageViewRect.right - rcAnchor.right); + + if (rcAnchor.top > pageViewRect.top) { + rtPopup.left -= rcAnchor.top - pageViewRect.top; + } + break; + } + case 0: + default: { + t1 = (int)(pageViewRect.top - rcAnchor.top); + t2 = (int)(rcAnchor.bottom - pageViewRect.bottom); + if (rcAnchor.right > pageViewRect.right) { + rtPopup.left -= rcAnchor.right - pageViewRect.right; + } + break; + } + } + + if (t1 <= 0 && t2 <= 0) { + return FALSE; + } + if (t1 <= 0) { + t = t2; + dwPos = 1; + } else if (t2 <= 0) { + t = t1; + dwPos = 0; + } else if (t1 > t2) { + t = t1; + dwPos = 0; + } else { + t = t2; + dwPos = 1; + } + if (t < fMinPopup) { + fPoupHeight = fMinPopup; + } else if (t > fMaxPopup) { + fPoupHeight = fMaxPopup; + } else { + fPoupHeight = (FX_FLOAT)t; + } + + switch (nRotate) { + case 0: + case 180: { + if (dwPos == 0) { + rtPopup.top = rtAnchor.height; + rtPopup.height = fPoupHeight; + } else { + rtPopup.top = -fPoupHeight; + rtPopup.height = fPoupHeight; + } + break; + } + case 90: + case 270: { + if (dwPos == 0) { + rtPopup.top = rtAnchor.width; + rtPopup.height = fPoupHeight; + } else { + rtPopup.top = -fPoupHeight; + rtPopup.height = fPoupHeight; + } + break; + } + default: + break; + } + + return TRUE; +} + +FX_BOOL CPDFXFA_Document::PopupMenu(IXFA_Widget* hWidget, + CFX_PointF ptPopup, + const CFX_RectF* pRectExclude) { + if (NULL == hWidget) { + return FALSE; + } + IXFA_PageView* pXFAPageView = + m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget); + if (pXFAPageView == NULL) + return FALSE; + CPDFXFA_Page* pPage = GetPage(pXFAPageView); + + if (pPage == NULL) + return FALSE; + + int menuFlag = 0; + + IXFA_MenuHandler* pXFAMenuHander = m_pApp->GetXFAApp()->GetMenuHandler(); + if (pXFAMenuHander->CanUndo(hWidget)) + menuFlag |= FXFA_MEMU_UNDO; + if (pXFAMenuHander->CanRedo(hWidget)) + menuFlag |= FXFA_MEMU_REDO; + if (pXFAMenuHander->CanPaste(hWidget)) + menuFlag |= FXFA_MEMU_PASTE; + if (pXFAMenuHander->CanCopy(hWidget)) + menuFlag |= FXFA_MEMU_COPY; + if (pXFAMenuHander->CanCut(hWidget)) + menuFlag |= FXFA_MEMU_CUT; + if (pXFAMenuHander->CanSelectAll(hWidget)) + menuFlag |= FXFA_MEMU_SELECTALL; + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return FALSE; + + return pEnv->FFI_PopupMenu(pPage, hWidget, menuFlag, ptPopup, NULL); +} + +void CPDFXFA_Document::PageViewEvent(IXFA_PageView* pPageView, + FX_DWORD dwFlags) { + if (!pPageView || (dwFlags != XFA_PAGEVIEWEVENT_PostAdded && + dwFlags != XFA_PAGEVIEWEVENT_PostRemoved)) { + return; + } + CPDFXFA_Page* pPage = nullptr; + if (dwFlags == XFA_PAGEVIEWEVENT_PostAdded) { + pPage = GetPage(pPageView->GetPageViewIndex()); + if (pPage) + pPage->SetXFAPageView(pPageView); + return; + } + pPage = GetPage(pPageView); + if (!pPage) + return; + pPage->SetXFAPageView(nullptr); + m_pSDKDoc->GetPageView(pPage)->ClearFXAnnots(); +} + +void CPDFXFA_Document::WidgetEvent(IXFA_Widget* hWidget, + CXFA_WidgetAcc* pWidgetData, + FX_DWORD dwEvent, + void* pParam, + void* pAdditional) { + if (m_iDocType != DOCTYPE_DYNAMIC_XFA || !hWidget) + return; + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (!pEnv) + return; + + IXFA_PageView* pPageView = + m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget); + if (pPageView == NULL) + return; + + CPDFXFA_Page* pXFAPage = GetPage(pPageView); + if (pXFAPage == NULL) + return; + + CPDFSDK_PageView* pSdkPageView = m_pSDKDoc->GetPageView(pXFAPage); + if (dwEvent == XFA_WIDGETEVENT_PostAdded) { + pSdkPageView->AddAnnot(hWidget); + + } else if (dwEvent == XFA_WIDGETEVENT_PreRemoved) { + CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget); + if (pAnnot) { + pSdkPageView->DeleteAnnot(pAnnot); + } + } +} + +int32_t CPDFXFA_Document::CountPages(IXFA_Doc* hDoc) { + if (hDoc == m_pXFADoc && m_pSDKDoc) { + return GetPageCount(); + } + return 0; +} +int32_t CPDFXFA_Document::GetCurrentPage(IXFA_Doc* hDoc) { + if (hDoc != m_pXFADoc || !m_pSDKDoc) + return -1; + if (m_iDocType != DOCTYPE_DYNAMIC_XFA) + return -1; + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return -1; + + return pEnv->FFI_GetCurrentPageIndex(this); +} +void CPDFXFA_Document::SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage) { + if (hDoc != m_pXFADoc || !m_pSDKDoc) + return; + if (m_iDocType != DOCTYPE_DYNAMIC_XFA) + return; + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return; + + pEnv->FFI_SetCurrentPage(this, iCurPage); +} +FX_BOOL CPDFXFA_Document::IsCalculationsEnabled(IXFA_Doc* hDoc) { + if (hDoc != m_pXFADoc || !m_pSDKDoc) + return FALSE; + if (m_pSDKDoc->GetInterForm()) + return m_pSDKDoc->GetInterForm()->IsXfaCalculateEnabled(); + + return FALSE; +} +void CPDFXFA_Document::SetCalculationsEnabled(IXFA_Doc* hDoc, + FX_BOOL bEnabled) { + if (hDoc != m_pXFADoc || !m_pSDKDoc) + return; + if (m_pSDKDoc->GetInterForm()) + m_pSDKDoc->GetInterForm()->XfaEnableCalculate(bEnabled); +} + +void CPDFXFA_Document::GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle) { + if (hDoc != m_pXFADoc) + return; + if (m_pPDFDoc == NULL) + return; + CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo(); + + if (pInfoDict == NULL) + return; + + CFX_ByteString csTitle = pInfoDict->GetString("Title"); + wsTitle = wsTitle.FromLocal(csTitle.GetBuffer(csTitle.GetLength())); + csTitle.ReleaseBuffer(csTitle.GetLength()); +} +void CPDFXFA_Document::SetTitle(IXFA_Doc* hDoc, + const CFX_WideStringC& wsTitle) { + if (hDoc != m_pXFADoc) + return; + if (m_pPDFDoc == NULL) + return; + CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo(); + + if (pInfoDict == NULL) + return; + pInfoDict->SetAt("Title", new CPDF_String(wsTitle)); +} +void CPDFXFA_Document::ExportData(IXFA_Doc* hDoc, + const CFX_WideStringC& wsFilePath, + FX_BOOL bXDP) { + if (hDoc != m_pXFADoc) + return; + if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA) + return; + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return; + int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML; + CFX_ByteString bs = CFX_WideString(wsFilePath).UTF16LE_Encode(); + + if (wsFilePath.IsEmpty()) { + if (!pEnv->GetFormFillInfo() || + pEnv->GetFormFillInfo()->m_pJsPlatform == NULL) + return; + CFX_WideString filepath = pEnv->JS_fieldBrowse(); + bs = filepath.UTF16LE_Encode(); + } + int len = bs.GetLength() / sizeof(unsigned short); + FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile( + bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML, + (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "wb"); + bs.ReleaseBuffer(len * sizeof(unsigned short)); + + if (pFileHandler == NULL) + return; + + CFPDF_FileStream fileWrite(pFileHandler); + + IXFA_DocHandler* pXFADocHander = m_pApp->GetXFAApp()->GetDocHandler(); + CFX_ByteString content; + if (fileType == FXFA_SAVEAS_XML) { + content = "\r\n"; + fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(), + content.GetLength()); + CFX_WideStringC data(L"data"); + if (pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), data, &fileWrite)) { + // TODO: Maybe report error. + } + } else if (fileType == FXFA_SAVEAS_XDP) { + if (m_pPDFDoc == NULL) + return; + CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot(); + if (pRoot == NULL) + return; + CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm"); + if (NULL == pAcroForm) + return; + CPDF_Object* pXFA = pAcroForm->GetElement("XFA"); + if (pXFA == NULL) + return; + if (!pXFA->IsArray()) + return; + CPDF_Array* pArray = pXFA->GetArray(); + if (NULL == pArray) + return; + int size = pArray->GetCount(); + for (int i = 1; i < size; i += 2) { + CPDF_Object* pPDFObj = pArray->GetElement(i); + CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1); + if (!pPrePDFObj->IsString()) + continue; + if (!pPDFObj->IsReference()) + continue; + CPDF_Object* pDirectObj = pPDFObj->GetDirect(); + if (!pDirectObj->IsStream()) + continue; + if (pPrePDFObj->GetString() == "form") { + CFX_WideStringC form(L"form"); + pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), form, &fileWrite); + } else if (pPrePDFObj->GetString() == "datasets") { + CFX_WideStringC datasets(L"datasets"); + pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), datasets, + &fileWrite); + } else { + if (i == size - 1) { + CFX_WideString wPath = CFX_WideString::FromUTF16LE( + (unsigned short*)(const FX_CHAR*)bs, + bs.GetLength() / sizeof(unsigned short)); + CFX_ByteString bPath = wPath.UTF8Encode(); + CFX_ByteString szFormat = + "\n"; + content.Format(szFormat, (char*)(const FX_CHAR*)bPath); + fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(), + content.GetLength()); + } + + CPDF_Stream* pStream = (CPDF_Stream*)pDirectObj; + CPDF_StreamAcc* pAcc = new CPDF_StreamAcc; + pAcc->LoadAllData(pStream); + fileWrite.WriteBlock(pAcc->GetData(), fileWrite.GetSize(), + pAcc->GetSize()); + delete pAcc; + } + } + } + if (!fileWrite.Flush()) { + // TODO: Report error. + } +} +void CPDFXFA_Document::ImportData(IXFA_Doc* hDoc, + const CFX_WideStringC& wsFilePath) { + // TODO... +} + +void CPDFXFA_Document::GotoURL(IXFA_Doc* hDoc, + const CFX_WideStringC& bsURL, + FX_BOOL bAppend) { + if (hDoc != m_pXFADoc) + return; + + if (m_iDocType != DOCTYPE_DYNAMIC_XFA) + return; + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return; + + CFX_WideStringC str(bsURL.GetPtr()); + + pEnv->FFI_GotoURL(this, str, bAppend); +} + +FX_BOOL CPDFXFA_Document::IsValidationsEnabled(IXFA_Doc* hDoc) { + if (hDoc != m_pXFADoc || !m_pSDKDoc) + return FALSE; + if (m_pSDKDoc->GetInterForm()) + return m_pSDKDoc->GetInterForm()->IsXfaValidationsEnabled(); + + return TRUE; +} +void CPDFXFA_Document::SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled) { + if (hDoc != m_pXFADoc || !m_pSDKDoc) + return; + if (m_pSDKDoc->GetInterForm()) + m_pSDKDoc->GetInterForm()->XfaSetValidationsEnabled(bEnabled); +} +void CPDFXFA_Document::SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget) { + if (hDoc != m_pXFADoc) + return; + + if (NULL == hWidget) { + m_pSDKDoc->SetFocusAnnot(NULL); + return; + } + + int pageViewCount = m_pSDKDoc->GetPageViewCount(); + for (int i = 0; i < pageViewCount; i++) { + CPDFSDK_PageView* pPageView = m_pSDKDoc->GetPageView(i); + if (pPageView == NULL) + continue; + CPDFSDK_Annot* pAnnot = pPageView->GetAnnotByXFAWidget(hWidget); + if (pAnnot) { + m_pSDKDoc->SetFocusAnnot(pAnnot); + break; + } + } +} +void CPDFXFA_Document::Print(IXFA_Doc* hDoc, + int32_t nStartPage, + int32_t nEndPage, + FX_DWORD dwOptions) { + if (hDoc != m_pXFADoc) + return; + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return; + + if (!pEnv->GetFormFillInfo() || + pEnv->GetFormFillInfo()->m_pJsPlatform == NULL) + return; + if (pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print == NULL) + return; + pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print( + pEnv->GetFormFillInfo()->m_pJsPlatform, + dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage, + dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage, + dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder, + dwOptions & XFA_PRINTOPT_PrintAnnot); +} + +void CPDFXFA_Document::GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL) { + if (hDoc != m_pXFADoc) + return; + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return; + + pEnv->FFI_GetURL(this, wsDocURL); +} + +FX_ARGB CPDFXFA_Document::GetHighlightColor(IXFA_Doc* hDoc) { + if (hDoc != m_pXFADoc) + return 0; + if (m_pSDKDoc) { + if (CPDFSDK_InterForm* pInterForm = m_pSDKDoc->GetInterForm()) { + FX_COLORREF color = pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA); + uint8_t alpha = pInterForm->GetHighlightAlpha(); + FX_ARGB argb = ArgbEncode((int)alpha, color); + return argb; + } + } + return 0; +} + +FX_BOOL CPDFXFA_Document::_NotifySubmit(FX_BOOL bPrevOrPost) { + if (bPrevOrPost) + return _OnBeforeNotifySumbit(); + + _OnAfterNotifySumbit(); + return TRUE; +} + +FX_BOOL CPDFXFA_Document::_OnBeforeNotifySumbit() { +#ifdef PDF_ENABLE_XFA + if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA) + return TRUE; + if (m_pXFADocView == NULL) + return TRUE; + IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); + if (pWidgetHandler == NULL) + return TRUE; + IXFA_WidgetAccIterator* pWidgetAccIterator = + m_pXFADocView->CreateWidgetAccIterator(); + if (pWidgetAccIterator) { + CXFA_EventParam Param; + Param.m_eType = XFA_EVENT_PreSubmit; + CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); + while (pWidgetAcc) { + pWidgetHandler->ProcessEvent(pWidgetAcc, &Param); + pWidgetAcc = pWidgetAccIterator->MoveToNext(); + } + pWidgetAccIterator->Release(); + } + pWidgetAccIterator = m_pXFADocView->CreateWidgetAccIterator(); + if (pWidgetAccIterator) { + CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); + pWidgetAcc = pWidgetAccIterator->MoveToNext(); + while (pWidgetAcc) { + int fRet = pWidgetAcc->ProcessValidate(-1); + if (fRet == XFA_EVENTERROR_Error) { + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return FALSE; + CFX_WideString ws; + ws.FromLocal(IDS_XFA_Validate_Input); + CFX_ByteString bs = ws.UTF16LE_Encode(); + int len = bs.GetLength() / sizeof(unsigned short); + pEnv->FFI_Alert( + (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), + (FPDF_WIDESTRING)L"", 0, 1); + bs.ReleaseBuffer(len * sizeof(unsigned short)); + pWidgetAccIterator->Release(); + return FALSE; + } + pWidgetAcc = pWidgetAccIterator->MoveToNext(); + } + pWidgetAccIterator->Release(); + m_pXFADocView->UpdateDocView(); + } +#endif + return TRUE; +} +void CPDFXFA_Document::_OnAfterNotifySumbit() { + if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA) + return; + if (m_pXFADocView == NULL) + return; + IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); + if (pWidgetHandler == NULL) + return; + IXFA_WidgetAccIterator* pWidgetAccIterator = + m_pXFADocView->CreateWidgetAccIterator(); + if (pWidgetAccIterator == NULL) + return; + CXFA_EventParam Param; + Param.m_eType = XFA_EVENT_PostSubmit; + + CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); + while (pWidgetAcc) { + pWidgetHandler->ProcessEvent(pWidgetAcc, &Param); + pWidgetAcc = pWidgetAccIterator->MoveToNext(); + } + pWidgetAccIterator->Release(); + m_pXFADocView->UpdateDocView(); +} + +FX_BOOL CPDFXFA_Document::SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) { + if (!_NotifySubmit(TRUE)) + return FALSE; + if (NULL == m_pXFADocView) + return FALSE; + m_pXFADocView->UpdateDocView(); + + FX_BOOL ret = _SubmitData(hDoc, submit); + _NotifySubmit(FALSE); + return ret; +} + +IFX_FileRead* CPDFXFA_Document::OpenLinkedFile(IXFA_Doc* hDoc, + const CFX_WideString& wsLink) { + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return FALSE; + CFX_ByteString bs = wsLink.UTF16LE_Encode(); + int len = bs.GetLength() / sizeof(unsigned short); + FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile( + 0, (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "rb"); + bs.ReleaseBuffer(len * sizeof(unsigned short)); + + if (pFileHandler == NULL) + return NULL; + return new CFPDF_FileStream(pFileHandler); +} +FX_BOOL CPDFXFA_Document::_ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler, + int fileType, + FPDF_DWORD encodeType, + FPDF_DWORD flag) { + if (NULL == m_pXFADocView) + return FALSE; + IXFA_DocHandler* pDocHandler = m_pApp->GetXFAApp()->GetDocHandler(); + CFX_ByteString content; + + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return FALSE; + + CFPDF_FileStream fileStream(pFileHandler); + + if (fileType == FXFA_SAVEAS_XML) { + CFX_WideString ws; + ws.FromLocal("data"); + CFX_ByteString content = "\r\n"; + fileStream.WriteBlock((const FX_CHAR*)content, 0, content.GetLength()); + pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream); + } else if (fileType == FXFA_SAVEAS_XDP) { + if (flag == 0) + flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS | + FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM; + if (m_pPDFDoc == NULL) { + fileStream.Flush(); + return FALSE; + } + CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot(); + if (pRoot == NULL) { + fileStream.Flush(); + return FALSE; + } + CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm"); + if (NULL == pAcroForm) { + fileStream.Flush(); + return FALSE; + } + CPDF_Object* pXFA = pAcroForm->GetElement("XFA"); + if (pXFA == NULL) { + fileStream.Flush(); + return FALSE; + } + if (!pXFA->IsArray()) { + fileStream.Flush(); + return FALSE; + } + CPDF_Array* pArray = pXFA->GetArray(); + if (NULL == pArray) { + fileStream.Flush(); + return FALSE; + } + int size = pArray->GetCount(); + for (int i = 1; i < size; i += 2) { + CPDF_Object* pPDFObj = pArray->GetElement(i); + CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1); + if (!pPrePDFObj->IsString()) + continue; + if (!pPDFObj->IsReference()) + continue; + CPDF_Object* pDirectObj = pPDFObj->GetDirect(); + if (!pDirectObj->IsStream()) + continue; + if (pPrePDFObj->GetString() == "config" && !(flag & FXFA_CONFIG)) + continue; + if (pPrePDFObj->GetString() == "template" && !(flag & FXFA_TEMPLATE)) + continue; + if (pPrePDFObj->GetString() == "localeSet" && !(flag & FXFA_LOCALESET)) + continue; + if (pPrePDFObj->GetString() == "datasets" && !(flag & FXFA_DATASETS)) + continue; + if (pPrePDFObj->GetString() == "xmpmeta" && !(flag & FXFA_XMPMETA)) + continue; + if (pPrePDFObj->GetString() == "xfdf" && !(flag & FXFA_XFDF)) + continue; + if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM)) + continue; + if (pPrePDFObj->GetString() == "form") { + CFX_WideString ws; + ws.FromLocal("form"); + pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream); + } else if (pPrePDFObj->GetString() == "datasets") { + CFX_WideString ws; + ws.FromLocal("datasets"); + pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream); + } else { + // PDF,creator. + // TODO: + } + } + } + return TRUE; +} + +void CPDFXFA_Document::_ClearChangeMark() { + if (m_pSDKDoc) + m_pSDKDoc->ClearChangeMark(); +} + +void CPDFXFA_Document::_ToXFAContentFlags(CFX_WideString csSrcContent, + FPDF_DWORD& flag) { + if (csSrcContent.Find(L" config ", 0) != -1) + flag |= FXFA_CONFIG; + if (csSrcContent.Find(L" template ", 0) != -1) + flag |= FXFA_TEMPLATE; + if (csSrcContent.Find(L" localeSet ", 0) != -1) + flag |= FXFA_LOCALESET; + if (csSrcContent.Find(L" datasets ", 0) != -1) + flag |= FXFA_DATASETS; + if (csSrcContent.Find(L" xmpmeta ", 0) != -1) + flag |= FXFA_XMPMETA; + if (csSrcContent.Find(L" xfdf ", 0) != -1) + flag |= FXFA_XFDF; + if (csSrcContent.Find(L" form ", 0) != -1) + flag |= FXFA_FORM; + if (flag == 0) + flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS | + FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM; +} +FX_BOOL CPDFXFA_Document::_MailToInfo(CFX_WideString& csURL, + CFX_WideString& csToAddress, + CFX_WideString& csCCAddress, + CFX_WideString& csBCCAddress, + CFX_WideString& csSubject, + CFX_WideString& csMsg) { + CFX_WideString srcURL = csURL; + srcURL.TrimLeft(); + if (0 != srcURL.Left(7).CompareNoCase(L"mailto:")) + return FALSE; + int pos = srcURL.Find(L'?', 0); + CFX_WideString tmp; + if (pos == -1) { + pos = srcURL.Find(L'@', 0); + if (pos == -1) + return FALSE; + else { + tmp = srcURL.Right(csURL.GetLength() - 7); + tmp.TrimLeft(); + tmp.TrimRight(); + } + } else { + tmp = srcURL.Left(pos); + tmp = tmp.Right(tmp.GetLength() - 7); + tmp.TrimLeft(); + tmp.TrimRight(); + } + + csToAddress = tmp; + + srcURL = srcURL.Right(srcURL.GetLength() - (pos + 1)); + while (!srcURL.IsEmpty()) { + srcURL.TrimLeft(); + srcURL.TrimRight(); + pos = srcURL.Find(L'&', 0); + if (pos == -1) + tmp = srcURL; + else + tmp = srcURL.Left(pos); + + tmp.TrimLeft(); + tmp.TrimRight(); + if (tmp.GetLength() >= 3 && 0 == tmp.Left(3).CompareNoCase(L"cc=")) { + tmp = tmp.Right(tmp.GetLength() - 3); + if (!csCCAddress.IsEmpty()) + csCCAddress += L';'; + csCCAddress += tmp; + + } else if (tmp.GetLength() >= 4 && + 0 == tmp.Left(4).CompareNoCase(L"bcc=")) { + tmp = tmp.Right(tmp.GetLength() - 4); + if (!csBCCAddress.IsEmpty()) + csBCCAddress += L';'; + csBCCAddress += tmp; + } else if (tmp.GetLength() >= 8 && + 0 == tmp.Left(8).CompareNoCase(L"subject=")) { + tmp = tmp.Right(tmp.GetLength() - 8); + csSubject += tmp; + } else if (tmp.GetLength() >= 5 && + 0 == tmp.Left(5).CompareNoCase(L"body=")) { + tmp = tmp.Right(tmp.GetLength() - 5); + csMsg += tmp; + } + if (pos == -1) + srcURL = L""; + else + srcURL = srcURL.Right(csURL.GetLength() - (pos + 1)); + } + csToAddress.Replace(L",", L";"); + csCCAddress.Replace(L",", L";"); + csBCCAddress.Replace(L",", L";"); + return TRUE; +} + +FX_BOOL CPDFXFA_Document::_SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) { +#ifdef PDF_ENABLE_XFA + CFX_WideStringC csURLC; + submit.GetSubmitTarget(csURLC); + CFX_WideString csURL = csURLC; + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + if (pEnv == NULL) + return FALSE; + if (csURL.IsEmpty()) { + CFX_WideString ws; + ws.FromLocal("Submit cancelled."); + CFX_ByteString bs = ws.UTF16LE_Encode(); + int len = bs.GetLength() / sizeof(unsigned short); + pEnv->FFI_Alert((FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), + (FPDF_WIDESTRING)L"", 0, 4); + bs.ReleaseBuffer(len * sizeof(unsigned short)); + return FALSE; + } + + FPDF_BOOL bRet = TRUE; + FPDF_FILEHANDLER* pFileHandler = NULL; + int fileFlag = -1; + + if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xdp) { + CFX_WideStringC csContentC; + submit.GetSubmitXDPContent(csContentC); + CFX_WideString csContent; + csContent = csContentC.GetPtr(); + csContent.TrimLeft(); + csContent.TrimRight(); + CFX_WideString space; + space.FromLocal(" "); + csContent = space + csContent + space; + FPDF_DWORD flag = 0; + if (submit.IsSubmitEmbedPDF()) + flag |= FXFA_PDF; + _ToXFAContentFlags(csContent, flag); + pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XDP, NULL, "wb"); + fileFlag = FXFA_SAVEAS_XDP; + _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag); + } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xml) { + pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb"); + fileFlag = FXFA_SAVEAS_XML; + _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0); + } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Pdf) { + // csfilename = csDocName; + } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Formdata) { + return FALSE; + } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Urlencoded) { + pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb"); + fileFlag = FXFA_SAVEAS_XML; + _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0); + } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xfd) { + return FALSE; + } else { + return FALSE; + } + if (pFileHandler == NULL) + return FALSE; + if (0 == csURL.Left(7).CompareNoCase(L"mailto:")) { + CFX_WideString csToAddress; + CFX_WideString csCCAddress; + CFX_WideString csBCCAddress; + CFX_WideString csSubject; + CFX_WideString csMsg; + + bRet = _MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject, + csMsg); + if (FALSE == bRet) + return FALSE; + + CFX_ByteString bsTo = CFX_WideString(csToAddress).UTF16LE_Encode(); + CFX_ByteString bsCC = CFX_WideString(csCCAddress).UTF16LE_Encode(); + CFX_ByteString bsBcc = CFX_WideString(csBCCAddress).UTF16LE_Encode(); + CFX_ByteString bsSubject = CFX_WideString(csSubject).UTF16LE_Encode(); + CFX_ByteString bsMsg = CFX_WideString(csMsg).UTF16LE_Encode(); + + FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength()); + FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength()); + FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength()); + FPDF_WIDESTRING pSubject = + (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength()); + FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength()); + + pEnv->FFI_EmailTo(pFileHandler, pTo, pSubject, pCC, pBcc, pMsg); + bsTo.ReleaseBuffer(); + bsCC.ReleaseBuffer(); + bsBcc.ReleaseBuffer(); + bsSubject.ReleaseBuffer(); + bsMsg.ReleaseBuffer(); + } else { + // http¡¢ftp + CFX_WideString ws; + CFX_ByteString bs = csURL.UTF16LE_Encode(); + int len = bs.GetLength() / sizeof(unsigned short); + pEnv->FFI_UploadTo( + pFileHandler, fileFlag, + (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short))); + bs.ReleaseBuffer(len * sizeof(unsigned short)); + } + + return bRet; +#else + return TRUE; +#endif +} + +FX_BOOL CPDFXFA_Document::SetGlobalProperty(IXFA_Doc* hDoc, + const CFX_ByteStringC& szPropName, + FXJSE_HVALUE hValue) { + if (hDoc != m_pXFADoc) + return FALSE; + + if (m_pSDKDoc && m_pSDKDoc->GetEnv()->GetJSRuntime()) + return m_pSDKDoc->GetEnv()->GetJSRuntime()->SetHValueByName(szPropName, + hValue); + return FALSE; +} +FX_BOOL CPDFXFA_Document::GetPDFScriptObject(IXFA_Doc* hDoc, + const CFX_ByteStringC& utf8Name, + FXJSE_HVALUE hValue) { + if (hDoc != m_pXFADoc) + return FALSE; + + if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime()) + return FALSE; + + if (!m_pJSContext) { + m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc); + m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext(); + } + + return _GetHValueByName(utf8Name, hValue, + m_pSDKDoc->GetEnv()->GetJSRuntime()); +} +FX_BOOL CPDFXFA_Document::GetGlobalProperty(IXFA_Doc* hDoc, + const CFX_ByteStringC& szPropName, + FXJSE_HVALUE hValue) { + if (hDoc != m_pXFADoc) + return FALSE; + if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime()) + return FALSE; + + if (!m_pJSContext) { + m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc); + m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext(); + } + + return _GetHValueByName(szPropName, hValue, + m_pSDKDoc->GetEnv()->GetJSRuntime()); +} +FX_BOOL CPDFXFA_Document::_GetHValueByName(const CFX_ByteStringC& utf8Name, + FXJSE_HVALUE hValue, + IJS_Runtime* runTime) { + return runTime->GetHValueByName(utf8Name, hValue); +} diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp index edd25c7612..24c1ed156d 100644 --- a/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp +++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp @@ -1,255 +1,255 @@ -// 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 "fpdfsdk/include/fsdk_define.h" -#include "fpdfsdk/include/fsdk_mgr.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h" - -CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index) - : m_pPDFPage(NULL), - m_pXFAPageView(NULL), - m_iPageIndex(page_index), - m_pDocument(pDoc), - m_iRef(1) {} - -CPDFXFA_Page::~CPDFXFA_Page() { - if (m_pPDFPage) - delete m_pPDFPage; - m_pPDFPage = NULL; - m_pXFAPageView = NULL; -} - -void CPDFXFA_Page::Release() { - m_iRef--; - if (m_iRef > 0) - return; - - if (m_pDocument) - m_pDocument->RemovePage(this); - - delete this; -} - -FX_BOOL CPDFXFA_Page::LoadPDFPage() { - if (!m_pDocument) - return FALSE; - CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc(); - if (pPDFDoc) { - CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex); - if (pDict == NULL) - return FALSE; - if (m_pPDFPage) { - if (m_pPDFPage->m_pFormDict == pDict) - return TRUE; - - delete m_pPDFPage; - m_pPDFPage = NULL; - } - - m_pPDFPage = new CPDF_Page; - m_pPDFPage->Load(pPDFDoc, pDict); - m_pPDFPage->ParseContent(nullptr); - return TRUE; - } - - return FALSE; -} - -FX_BOOL CPDFXFA_Page::LoadXFAPageView() { - if (!m_pDocument) - return FALSE; - IXFA_Doc* pXFADoc = m_pDocument->GetXFADoc(); - if (!pXFADoc) - return FALSE; - - IXFA_DocView* pXFADocView = m_pDocument->GetXFADocView(); - if (!pXFADocView) - return FALSE; - - IXFA_PageView* pPageView = pXFADocView->GetPageView(m_iPageIndex); - if (!pPageView) - return FALSE; - - if (m_pXFAPageView == pPageView) - return TRUE; - - m_pXFAPageView = pPageView; - (void)m_pXFAPageView->LoadPageView(nullptr); - return TRUE; -} - -FX_BOOL CPDFXFA_Page::LoadPage() { - if (!m_pDocument || m_iPageIndex < 0) - return FALSE; - - int iDocType = m_pDocument->GetDocType(); - switch (iDocType) { - case DOCTYPE_PDF: - case DOCTYPE_STATIC_XFA: { - return LoadPDFPage(); - } - case DOCTYPE_DYNAMIC_XFA: { - return LoadXFAPageView(); - } - default: - return FALSE; - } - - return FALSE; -} - -FX_BOOL CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) { - if (!m_pDocument || m_iPageIndex < 0 || !pageDict) - return FALSE; - - if (m_pPDFPage) - delete m_pPDFPage; - - m_pPDFPage = new CPDF_Page(); - m_pPDFPage->Load(m_pDocument->GetPDFDoc(), pageDict); - m_pPDFPage->ParseContent(nullptr); - - return TRUE; -} - -FX_FLOAT CPDFXFA_Page::GetPageWidth() { - ASSERT(m_pDocument != NULL); - - if (!m_pPDFPage && !m_pXFAPageView) - return 0.0f; - - int nDocType = m_pDocument->GetDocType(); - switch (nDocType) { - case DOCTYPE_DYNAMIC_XFA: { - if (m_pXFAPageView) { - CFX_RectF rect; - m_pXFAPageView->GetPageViewRect(rect); - return rect.width; - } - } break; - case DOCTYPE_STATIC_XFA: - case DOCTYPE_PDF: { - if (m_pPDFPage) - return m_pPDFPage->GetPageWidth(); - } break; - default: - return 0.0f; - } - - return 0.0f; -} - -FX_FLOAT CPDFXFA_Page::GetPageHeight() { - ASSERT(m_pDocument != NULL); - - if (!m_pPDFPage && !m_pXFAPageView) - return 0.0f; - - int nDocType = m_pDocument->GetDocType(); - switch (nDocType) { - case DOCTYPE_PDF: - case DOCTYPE_STATIC_XFA: { - if (m_pPDFPage) - return m_pPDFPage->GetPageHeight(); - } break; - case DOCTYPE_DYNAMIC_XFA: { - if (m_pXFAPageView) { - CFX_RectF rect; - m_pXFAPageView->GetPageViewRect(rect); - return rect.height; - } - } break; - default: - return 0.0f; - } - - return 0.0f; -} - -void CPDFXFA_Page::DeviceToPage(int start_x, - int start_y, - int size_x, - int size_y, - int rotate, - int device_x, - int device_y, - double* page_x, - double* page_y) { - ASSERT(m_pDocument != NULL); - - if (!m_pPDFPage && !m_pXFAPageView) - return; - - CFX_Matrix page2device; - CFX_Matrix device2page; - FX_FLOAT page_x_f, page_y_f; - - GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); - - device2page.SetReverse(page2device); - device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, - page_y_f); - - *page_x = (page_x_f); - *page_y = (page_y_f); -} - -void CPDFXFA_Page::PageToDevice(int start_x, - int start_y, - int size_x, - int size_y, - int rotate, - double page_x, - double page_y, - int* device_x, - int* device_y) { - if (!m_pPDFPage && !m_pXFAPageView) - return; - - CFX_Matrix page2device; - FX_FLOAT device_x_f, device_y_f; - - GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); - - page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, - device_y_f); - - *device_x = FXSYS_round(device_x_f); - *device_y = FXSYS_round(device_y_f); -} - -void CPDFXFA_Page::GetDisplayMatrix(CFX_Matrix& matrix, - int xPos, - int yPos, - int xSize, - int ySize, - int iRotate) const { - ASSERT(m_pDocument != NULL); - - if (!m_pPDFPage && !m_pXFAPageView) - return; - - int nDocType = m_pDocument->GetDocType(); - switch (nDocType) { - case DOCTYPE_DYNAMIC_XFA: { - if (m_pXFAPageView) { - CFX_Rect rect; - rect.Set(xPos, yPos, xSize, ySize); - m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate); - } - } break; - case DOCTYPE_PDF: - case DOCTYPE_STATIC_XFA: { - if (m_pPDFPage) { - m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate); - } - } break; - default: - return; - } -} +// 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 "fpdfsdk/include/fsdk_define.h" +#include "fpdfsdk/include/fsdk_mgr.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h" + +CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index) + : m_pPDFPage(NULL), + m_pXFAPageView(NULL), + m_iPageIndex(page_index), + m_pDocument(pDoc), + m_iRef(1) {} + +CPDFXFA_Page::~CPDFXFA_Page() { + if (m_pPDFPage) + delete m_pPDFPage; + m_pPDFPage = NULL; + m_pXFAPageView = NULL; +} + +void CPDFXFA_Page::Release() { + m_iRef--; + if (m_iRef > 0) + return; + + if (m_pDocument) + m_pDocument->RemovePage(this); + + delete this; +} + +FX_BOOL CPDFXFA_Page::LoadPDFPage() { + if (!m_pDocument) + return FALSE; + CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc(); + if (pPDFDoc) { + CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex); + if (pDict == NULL) + return FALSE; + if (m_pPDFPage) { + if (m_pPDFPage->m_pFormDict == pDict) + return TRUE; + + delete m_pPDFPage; + m_pPDFPage = NULL; + } + + m_pPDFPage = new CPDF_Page; + m_pPDFPage->Load(pPDFDoc, pDict); + m_pPDFPage->ParseContent(nullptr); + return TRUE; + } + + return FALSE; +} + +FX_BOOL CPDFXFA_Page::LoadXFAPageView() { + if (!m_pDocument) + return FALSE; + IXFA_Doc* pXFADoc = m_pDocument->GetXFADoc(); + if (!pXFADoc) + return FALSE; + + IXFA_DocView* pXFADocView = m_pDocument->GetXFADocView(); + if (!pXFADocView) + return FALSE; + + IXFA_PageView* pPageView = pXFADocView->GetPageView(m_iPageIndex); + if (!pPageView) + return FALSE; + + if (m_pXFAPageView == pPageView) + return TRUE; + + m_pXFAPageView = pPageView; + (void)m_pXFAPageView->LoadPageView(nullptr); + return TRUE; +} + +FX_BOOL CPDFXFA_Page::LoadPage() { + if (!m_pDocument || m_iPageIndex < 0) + return FALSE; + + int iDocType = m_pDocument->GetDocType(); + switch (iDocType) { + case DOCTYPE_PDF: + case DOCTYPE_STATIC_XFA: { + return LoadPDFPage(); + } + case DOCTYPE_DYNAMIC_XFA: { + return LoadXFAPageView(); + } + default: + return FALSE; + } + + return FALSE; +} + +FX_BOOL CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) { + if (!m_pDocument || m_iPageIndex < 0 || !pageDict) + return FALSE; + + if (m_pPDFPage) + delete m_pPDFPage; + + m_pPDFPage = new CPDF_Page(); + m_pPDFPage->Load(m_pDocument->GetPDFDoc(), pageDict); + m_pPDFPage->ParseContent(nullptr); + + return TRUE; +} + +FX_FLOAT CPDFXFA_Page::GetPageWidth() { + ASSERT(m_pDocument != NULL); + + if (!m_pPDFPage && !m_pXFAPageView) + return 0.0f; + + int nDocType = m_pDocument->GetDocType(); + switch (nDocType) { + case DOCTYPE_DYNAMIC_XFA: { + if (m_pXFAPageView) { + CFX_RectF rect; + m_pXFAPageView->GetPageViewRect(rect); + return rect.width; + } + } break; + case DOCTYPE_STATIC_XFA: + case DOCTYPE_PDF: { + if (m_pPDFPage) + return m_pPDFPage->GetPageWidth(); + } break; + default: + return 0.0f; + } + + return 0.0f; +} + +FX_FLOAT CPDFXFA_Page::GetPageHeight() { + ASSERT(m_pDocument != NULL); + + if (!m_pPDFPage && !m_pXFAPageView) + return 0.0f; + + int nDocType = m_pDocument->GetDocType(); + switch (nDocType) { + case DOCTYPE_PDF: + case DOCTYPE_STATIC_XFA: { + if (m_pPDFPage) + return m_pPDFPage->GetPageHeight(); + } break; + case DOCTYPE_DYNAMIC_XFA: { + if (m_pXFAPageView) { + CFX_RectF rect; + m_pXFAPageView->GetPageViewRect(rect); + return rect.height; + } + } break; + default: + return 0.0f; + } + + return 0.0f; +} + +void CPDFXFA_Page::DeviceToPage(int start_x, + int start_y, + int size_x, + int size_y, + int rotate, + int device_x, + int device_y, + double* page_x, + double* page_y) { + ASSERT(m_pDocument != NULL); + + if (!m_pPDFPage && !m_pXFAPageView) + return; + + CFX_Matrix page2device; + CFX_Matrix device2page; + FX_FLOAT page_x_f, page_y_f; + + GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); + + device2page.SetReverse(page2device); + device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, + page_y_f); + + *page_x = (page_x_f); + *page_y = (page_y_f); +} + +void CPDFXFA_Page::PageToDevice(int start_x, + int start_y, + int size_x, + int size_y, + int rotate, + double page_x, + double page_y, + int* device_x, + int* device_y) { + if (!m_pPDFPage && !m_pXFAPageView) + return; + + CFX_Matrix page2device; + FX_FLOAT device_x_f, device_y_f; + + GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); + + page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, + device_y_f); + + *device_x = FXSYS_round(device_x_f); + *device_y = FXSYS_round(device_y_f); +} + +void CPDFXFA_Page::GetDisplayMatrix(CFX_Matrix& matrix, + int xPos, + int yPos, + int xSize, + int ySize, + int iRotate) const { + ASSERT(m_pDocument != NULL); + + if (!m_pPDFPage && !m_pXFAPageView) + return; + + int nDocType = m_pDocument->GetDocType(); + switch (nDocType) { + case DOCTYPE_DYNAMIC_XFA: { + if (m_pXFAPageView) { + CFX_Rect rect; + rect.Set(xPos, yPos, xSize, ySize); + m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate); + } + } break; + case DOCTYPE_PDF: + case DOCTYPE_STATIC_XFA: { + if (m_pPDFPage) { + m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate); + } + } break; + default: + return; + } +} diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp index dc1cf9b516..5f8a9f01c5 100644 --- a/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp +++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp @@ -1,65 +1,65 @@ -// 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 "fpdfsdk/include/fsdk_define.h" -#include "fpdfsdk/include/fsdk_mgr.h" -#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" - -CFX_PtrArray CXFA_FWLAdapterTimerMgr::ms_timerArray; - -FWL_ERR CXFA_FWLAdapterTimerMgr::Start(IFWL_Timer* pTimer, - FX_DWORD dwElapse, - FWL_HTIMER& hTimer, - FX_BOOL bImmediately /* = TRUE */) { - if (m_pEnv) { - uint32_t uIDEvent = m_pEnv->FFI_SetTimer(dwElapse, TimerProc); - CFWL_TimerInfo* pInfo = new CFWL_TimerInfo; - pInfo->uIDEvent = uIDEvent; - pInfo->pTimer = pTimer; - ms_timerArray.Add(pInfo); - - hTimer = (FWL_HTIMER)pInfo; - return FWL_ERR_Succeeded; - } - - return FWL_ERR_Indefinite; -} - -FWL_ERR CXFA_FWLAdapterTimerMgr::Stop(FWL_HTIMER hTimer) { - if (!hTimer) - return FWL_ERR_Indefinite; - - if (m_pEnv) { - CFWL_TimerInfo* pInfo = (CFWL_TimerInfo*)hTimer; - - m_pEnv->FFI_KillTimer(pInfo->uIDEvent); - - int32_t index = ms_timerArray.Find(pInfo); - if (index >= 0) { - ms_timerArray.RemoveAt(index); - delete pInfo; - } - return FWL_ERR_Succeeded; - } - - return FWL_ERR_Indefinite; -} - -void CXFA_FWLAdapterTimerMgr::TimerProc(int32_t idEvent) { - CFWL_TimerInfo* pInfo = NULL; - int32_t iCount = CXFA_FWLAdapterTimerMgr::ms_timerArray.GetSize(); - for (int32_t i = 0; i < iCount; i++) { - CFWL_TimerInfo* pTemp = - (CFWL_TimerInfo*)CXFA_FWLAdapterTimerMgr::ms_timerArray.GetAt(i); - if (pTemp->uIDEvent == idEvent) { - pInfo = pTemp; - break; - } - } - if (pInfo) { - pInfo->pTimer->Run((FWL_HTIMER)pInfo); - } -} +// 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 "fpdfsdk/include/fsdk_define.h" +#include "fpdfsdk/include/fsdk_mgr.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" + +CFX_PtrArray CXFA_FWLAdapterTimerMgr::ms_timerArray; + +FWL_ERR CXFA_FWLAdapterTimerMgr::Start(IFWL_Timer* pTimer, + FX_DWORD dwElapse, + FWL_HTIMER& hTimer, + FX_BOOL bImmediately /* = TRUE */) { + if (m_pEnv) { + uint32_t uIDEvent = m_pEnv->FFI_SetTimer(dwElapse, TimerProc); + CFWL_TimerInfo* pInfo = new CFWL_TimerInfo; + pInfo->uIDEvent = uIDEvent; + pInfo->pTimer = pTimer; + ms_timerArray.Add(pInfo); + + hTimer = (FWL_HTIMER)pInfo; + return FWL_ERR_Succeeded; + } + + return FWL_ERR_Indefinite; +} + +FWL_ERR CXFA_FWLAdapterTimerMgr::Stop(FWL_HTIMER hTimer) { + if (!hTimer) + return FWL_ERR_Indefinite; + + if (m_pEnv) { + CFWL_TimerInfo* pInfo = (CFWL_TimerInfo*)hTimer; + + m_pEnv->FFI_KillTimer(pInfo->uIDEvent); + + int32_t index = ms_timerArray.Find(pInfo); + if (index >= 0) { + ms_timerArray.RemoveAt(index); + delete pInfo; + } + return FWL_ERR_Succeeded; + } + + return FWL_ERR_Indefinite; +} + +void CXFA_FWLAdapterTimerMgr::TimerProc(int32_t idEvent) { + CFWL_TimerInfo* pInfo = NULL; + int32_t iCount = CXFA_FWLAdapterTimerMgr::ms_timerArray.GetSize(); + for (int32_t i = 0; i < iCount; i++) { + CFWL_TimerInfo* pTemp = + (CFWL_TimerInfo*)CXFA_FWLAdapterTimerMgr::ms_timerArray.GetAt(i); + if (pTemp->uIDEvent == idEvent) { + pInfo = pTemp; + break; + } + } + if (pInfo) { + pInfo->pTimer->Run((FWL_HTIMER)pInfo); + } +} -- cgit v1.2.3