summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp320
-rw-r--r--core/src/fxcodec/codec/fx_codec_bmp.cpp254
-rw-r--r--core/src/fxcodec/codec/fx_codec_gif.cpp378
-rw-r--r--core/src/fxcodec/codec/fx_codec_png.cpp512
-rw-r--r--core/src/fxcodec/codec/fx_codec_progress.cpp4708
-rw-r--r--core/src/fxcodec/codec/fx_codec_progress.h446
-rw-r--r--core/src/fxcodec/codec/fx_codec_tiff.cpp1088
-rw-r--r--core/src/fxcodec/lbmp/fx_bmp.cpp1950
-rw-r--r--core/src/fxcodec/lbmp/fx_bmp.h310
-rw-r--r--core/src/fxcodec/lgif/fx_gif.cpp2852
-rw-r--r--core/src/fxcodec/lgif/fx_gif.h664
11 files changed, 6741 insertions, 6741 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 <memory>
-#include <vector>
-
-#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<uint8_t*>(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<CPDF_Object, ReleaseDeleter<CPDF_Object>>;
-
- // m_ObjHolder needs to be declared first and destructed last since it also
- // refers to some objects in m_DirectObjs.
- std::unique_ptr<CPDF_IndirectObjectHolder> m_ObjHolder;
- std::vector<ScopedObj> m_DirectObjs;
- std::vector<ScopedObj> 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 <memory>
+#include <vector>
+
+#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<uint8_t*>(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<CPDF_Object, ReleaseDeleter<CPDF_Object>>;
+
+ // m_ObjHolder needs to be declared first and destructed last since it also
+ // refers to some objects in m_DirectObjs.
+ std::unique_ptr<CPDF_IndirectObjectHolder> m_ObjHolder;
+ std::vector<ScopedObj> m_DirectObjs;
+ std::vector<ScopedObj> 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 <algorithm>
-
-#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 <algorithm>
+
+#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 <class T>
-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<FX_WORD>(tif_ctx, TIFFTAG_ORIENTATION, pAttribute);
- if (Tiff_Exif_GetInfo<FX_FLOAT>(tif_ctx, TIFFTAG_XRESOLUTION, pAttribute)) {
- void* val = pAttribute->m_Exif[TIFFTAG_XRESOLUTION];
- FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(val) : 0;
- pAttribute->m_nXDPI = (int32_t)(fDpi + 0.5f);
- }
- if (Tiff_Exif_GetInfo<FX_FLOAT>(tif_ctx, TIFFTAG_YRESOLUTION, pAttribute)) {
- void* val = pAttribute->m_Exif[TIFFTAG_YRESOLUTION];
- FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(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 <class T>
+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<FX_WORD>(tif_ctx, TIFFTAG_ORIENTATION, pAttribute);
+ if (Tiff_Exif_GetInfo<FX_FLOAT>(tif_ctx, TIFFTAG_XRESOLUTION, pAttribute)) {
+ void* val = pAttribute->m_Exif[TIFFTAG_XRESOLUTION];
+ FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(val) : 0;
+ pAttribute->m_nXDPI = (int32_t)(fDpi + 0.5f);
+ }
+ if (Tiff_Exif_GetInfo<FX_FLOAT>(tif_ctx, TIFFTAG_YRESOLUTION, pAttribute)) {
+ void* val = pAttribute->m_Exif[TIFFTAG_YRESOLUTION];
+ FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(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 <algorithm>
-
-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 <algorithm>
+
+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 <setjmp.h>
-
-#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 <setjmp.h>
+
+#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<GifImage*>;
-#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<GifPlainText*>;
-#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<uint8_t*> 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<GifImage*>;
+#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<GifPlainText*>;
+#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<uint8_t*> 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 <setjmp.h>
-
-#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<GifImage*>* 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<GifPlainText*>* 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 <setjmp.h>
+
+#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<GifImage*>* 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<GifPlainText*>* 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; \
+ }