XFA: Fix DOS newlines, final round.

TBR=tsepez@chromium.org

Review URL: https://codereview.chromium.org/1641963002 .
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 10cfecf..3965399 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 08b2f48..2396f36 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 45aeb09..d61ccc6 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 9e08473..32b0d3d 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 383e3ed..5dbc19b 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 cee8b39..2da92c9 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 d158c00..cfdc5fe 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 0047758..388daa4 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 d1232f1..06bfe1e 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 b07ebb3..c00b7a7 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 8b2acc8..3b4ec0f 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;                             \
+  }
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h
index b25a903..dd65042 100644
--- a/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h
+++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h
@@ -1,97 +1,97 @@
-// Copyright 2014 PDFium Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-

-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

-

-#ifndef FPDFXFA_APP_H_

-#define FPDFXFA_APP_H_

-

-#include "xfa/include/fxfa/fxfa.h"

-

-class IFXJS_Runtime;

-

-class CPDFXFA_App : public IXFA_AppProvider {

- public:

-  static CPDFXFA_App* GetInstance();

-  static void ReleaseInstance();

-

-  CPDFXFA_App();

-  ~CPDFXFA_App() override;

-

-  FX_BOOL Initialize();

-  IXFA_App* GetXFAApp() { return m_pXFAApp; }

-

-  FX_BOOL AddFormFillEnv(CPDFDoc_Environment* pEnv);

-  FX_BOOL RemoveFormFillEnv(CPDFDoc_Environment* pEnv);

-

-  FX_BOOL IsJavaScriptInitialized() const { return m_bJavaScriptInitialized; }

-  void SetJavaScriptInitialized(FX_BOOL bInitialized) {

-    m_bJavaScriptInitialized = bInitialized;

-  }

-

-  FXJSE_HRUNTIME GetJSERuntime() const { return m_hJSERuntime; }

-

-  // IFXA_AppProvider:

-  void GetAppType(CFX_WideString& wsAppType) override;

-  void SetAppType(const CFX_WideStringC& wsAppType) override;

-

-  void GetLanguage(CFX_WideString& wsLanguage) override;

-  void GetPlatform(CFX_WideString& wsPlatform) override;

-  void GetVariation(CFX_WideString& wsVariation) override;

-  void GetVersion(CFX_WideString& wsVersion) override;

-  void GetFoxitVersion(CFX_WideString& wsFoxitVersion) override {

-    wsFoxitVersion = L"7.0";

-  }

-

-  void GetAppName(CFX_WideString& wsName) override;

-  void GetFoxitAppName(CFX_WideString& wsFoxitName) override {

-    wsFoxitName = L"Foxit";

-  }

-

-  void Beep(FX_DWORD dwType) override;

-  int32_t MsgBox(const CFX_WideStringC& wsMessage,

-                 const CFX_WideStringC& wsTitle,

-                 FX_DWORD dwIconType,

-                 FX_DWORD dwButtonType) override;

-  void Response(CFX_WideString& wsAnswer,

-                const CFX_WideStringC& wsQuestion,

-                const CFX_WideStringC& wsTitle,

-                const CFX_WideStringC& wsDefaultAnswer,

-                FX_BOOL bMark) override;

-

-  int32_t GetDocumentCountInBatch() override;

-  int32_t GetCurDocumentInBatch() override;

-

-  IFX_FileRead* DownloadURL(const CFX_WideStringC& wsURL) override;

-  FX_BOOL PostRequestURL(const CFX_WideStringC& wsURL,

-                         const CFX_WideStringC& wsData,

-                         const CFX_WideStringC& wsContentType,

-                         const CFX_WideStringC& wsEncode,

-                         const CFX_WideStringC& wsHeader,

-                         CFX_WideString& wsResponse) override;

-  FX_BOOL PutRequestURL(const CFX_WideStringC& wsURL,

-                        const CFX_WideStringC& wsData,

-                        const CFX_WideStringC& wsEncode) override;

-

-  void LoadString(int32_t iStringID, CFX_WideString& wsString) override;

-  FX_BOOL ShowFileDialog(const CFX_WideStringC& wsTitle,

-                         const CFX_WideStringC& wsFilter,

-                         CFX_WideStringArray& wsPathArr,

-                         FX_BOOL bOpen) override;

-  IFWL_AdapterTimerMgr* GetTimerMgr() override;

-

-  CFX_ArrayTemplate<CPDFDoc_Environment*> m_pEnvList;

-

- protected:

-  static CPDFXFA_App* g_pApp;

-

-  FX_BOOL m_bJavaScriptInitialized;

-  IXFA_App* m_pXFAApp;

-  IXFA_FontMgr* m_pFontMgr;

-  FXJSE_HRUNTIME m_hJSERuntime;

-  IFXJS_Runtime* m_pJSRuntime;

-  CFX_WideString m_csAppType;

-};

-

-#endif  // FPDFXFA_APP_H_

+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFXFA_APP_H_
+#define FPDFXFA_APP_H_
+
+#include "xfa/include/fxfa/fxfa.h"
+
+class IFXJS_Runtime;
+
+class CPDFXFA_App : public IXFA_AppProvider {
+ public:
+  static CPDFXFA_App* GetInstance();
+  static void ReleaseInstance();
+
+  CPDFXFA_App();
+  ~CPDFXFA_App() override;
+
+  FX_BOOL Initialize();
+  IXFA_App* GetXFAApp() { return m_pXFAApp; }
+
+  FX_BOOL AddFormFillEnv(CPDFDoc_Environment* pEnv);
+  FX_BOOL RemoveFormFillEnv(CPDFDoc_Environment* pEnv);
+
+  FX_BOOL IsJavaScriptInitialized() const { return m_bJavaScriptInitialized; }
+  void SetJavaScriptInitialized(FX_BOOL bInitialized) {
+    m_bJavaScriptInitialized = bInitialized;
+  }
+
+  FXJSE_HRUNTIME GetJSERuntime() const { return m_hJSERuntime; }
+
+  // IFXA_AppProvider:
+  void GetAppType(CFX_WideString& wsAppType) override;
+  void SetAppType(const CFX_WideStringC& wsAppType) override;
+
+  void GetLanguage(CFX_WideString& wsLanguage) override;
+  void GetPlatform(CFX_WideString& wsPlatform) override;
+  void GetVariation(CFX_WideString& wsVariation) override;
+  void GetVersion(CFX_WideString& wsVersion) override;
+  void GetFoxitVersion(CFX_WideString& wsFoxitVersion) override {
+    wsFoxitVersion = L"7.0";
+  }
+
+  void GetAppName(CFX_WideString& wsName) override;
+  void GetFoxitAppName(CFX_WideString& wsFoxitName) override {
+    wsFoxitName = L"Foxit";
+  }
+
+  void Beep(FX_DWORD dwType) override;
+  int32_t MsgBox(const CFX_WideStringC& wsMessage,
+                 const CFX_WideStringC& wsTitle,
+                 FX_DWORD dwIconType,
+                 FX_DWORD dwButtonType) override;
+  void Response(CFX_WideString& wsAnswer,
+                const CFX_WideStringC& wsQuestion,
+                const CFX_WideStringC& wsTitle,
+                const CFX_WideStringC& wsDefaultAnswer,
+                FX_BOOL bMark) override;
+
+  int32_t GetDocumentCountInBatch() override;
+  int32_t GetCurDocumentInBatch() override;
+
+  IFX_FileRead* DownloadURL(const CFX_WideStringC& wsURL) override;
+  FX_BOOL PostRequestURL(const CFX_WideStringC& wsURL,
+                         const CFX_WideStringC& wsData,
+                         const CFX_WideStringC& wsContentType,
+                         const CFX_WideStringC& wsEncode,
+                         const CFX_WideStringC& wsHeader,
+                         CFX_WideString& wsResponse) override;
+  FX_BOOL PutRequestURL(const CFX_WideStringC& wsURL,
+                        const CFX_WideStringC& wsData,
+                        const CFX_WideStringC& wsEncode) override;
+
+  void LoadString(int32_t iStringID, CFX_WideString& wsString) override;
+  FX_BOOL ShowFileDialog(const CFX_WideStringC& wsTitle,
+                         const CFX_WideStringC& wsFilter,
+                         CFX_WideStringArray& wsPathArr,
+                         FX_BOOL bOpen) override;
+  IFWL_AdapterTimerMgr* GetTimerMgr() override;
+
+  CFX_ArrayTemplate<CPDFDoc_Environment*> m_pEnvList;
+
+ protected:
+  static CPDFXFA_App* g_pApp;
+
+  FX_BOOL m_bJavaScriptInitialized;
+  IXFA_App* m_pXFAApp;
+  IXFA_FontMgr* m_pFontMgr;
+  FXJSE_HRUNTIME m_hJSERuntime;
+  IFXJS_Runtime* m_pJSRuntime;
+  CFX_WideString m_csAppType;
+};
+
+#endif  // FPDFXFA_APP_H_
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h
index 14b07c3..64b3875 100644
--- a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h
+++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h
@@ -1,228 +1,228 @@
-// Copyright 2014 PDFium Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-

-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

-

-#ifndef FPDFXFA_DOC_H_

-#define FPDFXFA_DOC_H_

-

-#include "public/fpdfview.h"

-#include "xfa/include/fxfa/fxfa.h"

-

-class CPDFXFA_App;

-class CPDFXFA_Document;

-class CPDFXFA_Page;

-class CPDFSDK_Document;

-class CPDFDoc_Environment;

-class IJS_Runtime;

-class IJS_Context;

-class IXFA_DocHandler;

-

-class CPDFXFA_Document : public IXFA_DocProvider {

- public:

-  CPDFXFA_Document(CPDF_Document* pPDFDoc, CPDFXFA_App* pProvider);

-  ~CPDFXFA_Document();

-

-  FX_BOOL LoadXFADoc();

-  CPDFXFA_App* GetApp() { return m_pApp; }

-  CPDF_Document* GetPDFDoc() { return m_pPDFDoc; }

-  IXFA_Doc* GetXFADoc() { return m_pXFADoc; }

-  IXFA_DocView* GetXFADocView() { return m_pXFADocView; }

-

-  int GetPageCount();

-  CPDFXFA_Page* GetPage(int page_index);

-  CPDFXFA_Page* GetPage(IXFA_PageView* pPage);

-  void RemovePage(CPDFXFA_Page* page);

-  int GetDocType() { return m_iDocType; }

-

-  CPDFSDK_Document* GetSDKDocument(CPDFDoc_Environment* pFormFillEnv);

-

-  void FXRect2PDFRect(const CFX_RectF& fxRectF, CPDF_Rect& pdfRect);

-

-  virtual void SetChangeMark(IXFA_Doc* hDoc);

-  virtual FX_BOOL GetChangeMark(IXFA_Doc* hDoc);

-  // used in dynamic xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.

-  virtual void InvalidateRect(IXFA_PageView* pPageView,

-                              const CFX_RectF& rt,

-                              FX_DWORD dwFlags = 0);

-  // used in static xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.

-  virtual void InvalidateRect(IXFA_Widget* hWidget, FX_DWORD dwFlags = 0);

-  // show or hide caret

-  virtual void DisplayCaret(IXFA_Widget* hWidget,

-                            FX_BOOL bVisible,

-                            const CFX_RectF* pRtAnchor);

-  // dwPos: (0:bottom 1:top)

-  virtual FX_BOOL GetPopupPos(IXFA_Widget* hWidget,

-                              FX_FLOAT fMinPopup,

-                              FX_FLOAT fMaxPopup,

-                              const CFX_RectF& rtAnchor,

-                              CFX_RectF& rtPopup);

-  virtual FX_BOOL PopupMenu(IXFA_Widget* hWidget,

-                            CFX_PointF ptPopup,

-                            const CFX_RectF* pRectExclude = NULL);

-

-  // dwFlags XFA_PAGEVIEWEVENT_Added, XFA_PAGEVIEWEVENT_Removing

-  virtual void PageViewEvent(IXFA_PageView* pPageView, FX_DWORD dwFlags);

-  // dwEvent refer to XFA_WIDGETEVENT_XXX

-  virtual void WidgetEvent(IXFA_Widget* hWidget,

-                           CXFA_WidgetAcc* pWidgetData,

-                           FX_DWORD dwEvent,

-                           void* pParam = NULL,

-                           void* pAdditional = NULL);

-

-  // return true if render it.

-  virtual FX_BOOL RenderCustomWidget(IXFA_Widget* hWidget,

-                                     CFX_Graphics* pGS,

-                                     CFX_Matrix* pMatrix,

-                                     const CFX_RectF& rtUI) {

-    return FALSE;

-  }

-

-  // host method

-  virtual int32_t CountPages(IXFA_Doc* hDoc);

-  virtual int32_t GetCurrentPage(IXFA_Doc* hDoc);

-  virtual void SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage);

-  virtual FX_BOOL IsCalculationsEnabled(IXFA_Doc* hDoc);

-  virtual void SetCalculationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled);

-  virtual void GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle);

-  virtual void SetTitle(IXFA_Doc* hDoc, const CFX_WideStringC& wsTitle);

-  virtual void ExportData(IXFA_Doc* hDoc,

-                          const CFX_WideStringC& wsFilePath,

-                          FX_BOOL bXDP = TRUE);

-  virtual void ImportData(IXFA_Doc* hDoc, const CFX_WideStringC& wsFilePath);

-  virtual void GotoURL(IXFA_Doc* hDoc,

-                       const CFX_WideStringC& bsURL,

-                       FX_BOOL bAppend = TRUE);

-  virtual FX_BOOL IsValidationsEnabled(IXFA_Doc* hDoc);

-  virtual void SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled);

-  virtual void SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget);

-  virtual void Print(IXFA_Doc* hDoc,

-                     int32_t nStartPage,

-                     int32_t nEndPage,

-                     FX_DWORD dwOptions);

-

-  // LayoutPseudo method

-  virtual int32_t AbsPageCountInBatch(IXFA_Doc* hDoc) { return 0; }

-  virtual int32_t AbsPageInBatch(IXFA_Doc* hDoc, IXFA_Widget* hWidget) {

-    return 0;

-  }

-  virtual int32_t SheetCountInBatch(IXFA_Doc* hDoc) { return 0; }

-  virtual int32_t SheetInBatch(IXFA_Doc* hDoc, IXFA_Widget* hWidget) {

-    return 0;

-  }

-

-  // SignaturePseudoModel method

-  // TODO:

-  virtual int32_t Verify(

-      IXFA_Doc* hDoc,

-      CXFA_Node* pSigNode,

-      FX_BOOL

-          bUsed = TRUE /*, SecurityHandler* pHandler, SignatureInfo &info*/) {

-    return 0;

-  }

-  virtual FX_BOOL Sign(

-      IXFA_Doc* hDoc,

-      CXFA_NodeList* pNodeList,

-      const CFX_WideStringC& wsExpression,

-      const CFX_WideStringC& wsXMLIdent,

-      const CFX_WideStringC& wsValue = FX_WSTRC(L"open"),

-      FX_BOOL

-          bUsed = TRUE /*, SecurityHandler* pHandler = NULL, SignatureInfo &info*/) {

-    return 0;

-  }

-  virtual CXFA_NodeList* Enumerate(IXFA_Doc* hDoc) { return 0; }

-  virtual FX_BOOL Clear(IXFA_Doc* hDoc,

-                        CXFA_Node* pSigNode,

-                        FX_BOOL bCleared = TRUE) {

-    return 0;

-  }

-

-  // Get document path

-  virtual void GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL);

-  virtual FX_ARGB GetHighlightColor(IXFA_Doc* hDoc);

-

-  /**

-   *Submit data to email, http, ftp.

-   * @param[in] hDoc The document handler.

-   * @param[in] eFormat Determines the format in which the data will be

-   *submitted. XFA_ATTRIBUTEENUM_Xdp, XFA_ATTRIBUTEENUM_Xml...

-   * @param[in] wsTarget The URL to which the data will be submitted.

-   * @param[in] eEncoding The encoding of text content.

-   * @param[in] pXDPContent Controls what subset of the data is submitted, used

-   *only when the format property is xdp.

-   * @param[in] bEmbedPDF, specifies whether PDF is embedded in the submitted

-   *content or not.

-   */

-  virtual FX_BOOL SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit);

-

-  virtual FX_BOOL CheckWord(IXFA_Doc* hDoc, const CFX_ByteStringC& sWord) {

-    return FALSE;

-  }

-  virtual FX_BOOL GetSuggestWords(IXFA_Doc* hDoc,

-                                  const CFX_ByteStringC& sWord,

-                                  CFX_ByteStringArray& sSuggest) {

-    return FALSE;

-  }

-

-  // Get PDF javascript object, set the object to hValue.

-  virtual FX_BOOL GetPDFScriptObject(IXFA_Doc* hDoc,

-                                     const CFX_ByteStringC& utf8Name,

-                                     FXJSE_HVALUE hValue);

-

-  virtual FX_BOOL GetGlobalProperty(IXFA_Doc* hDoc,

-                                    const CFX_ByteStringC& szPropName,

-                                    FXJSE_HVALUE hValue);

-  virtual FX_BOOL SetGlobalProperty(IXFA_Doc* hDoc,

-                                    const CFX_ByteStringC& szPropName,

-                                    FXJSE_HVALUE hValue);

-  virtual CPDF_Document* OpenPDF(IXFA_Doc* hDoc,

-                                 IFX_FileRead* pFile,

-                                 FX_BOOL bTakeOverFile) {

-    return NULL;

-  }

-

-  virtual IFX_FileRead* OpenLinkedFile(IXFA_Doc* hDoc,

-                                       const CFX_WideString& wsLink);

-

-  FX_BOOL _GetHValueByName(const CFX_ByteStringC& utf8Name,

-                           FXJSE_HVALUE hValue,

-                           IJS_Runtime* runTime);

-  FX_BOOL _OnBeforeNotifySumbit();

-  void _OnAfterNotifySumbit();

-  FX_BOOL _NotifySubmit(FX_BOOL bPrevOrPost);

-  FX_BOOL _SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit);

-  FX_BOOL _MailToInfo(CFX_WideString& csURL,

-                      CFX_WideString& csToAddress,

-                      CFX_WideString& csCCAddress,

-                      CFX_WideString& csBCCAddress,

-                      CFX_WideString& csSubject,

-                      CFX_WideString& csMsg);

-  FX_BOOL _ExportSubmitFile(FPDF_FILEHANDLER* ppFileHandler,

-                            int fileType,

-                            FPDF_DWORD encodeType,

-                            FPDF_DWORD flag = 0x01111111);

-  void _ToXFAContentFlags(CFX_WideString csSrcContent, FPDF_DWORD& flag);

-  void _ClearChangeMark();

-

- private:

-  void CloseXFADoc(IXFA_DocHandler* pDoc) {

-    if (pDoc) {

-      pDoc->CloseDoc(m_pXFADoc);

-      pDoc->ReleaseDoc(m_pXFADoc);

-      m_pXFADoc = NULL;

-      m_pXFADocView = NULL;

-    }

-  }

-

-  int m_iDocType;

-  CPDF_Document* m_pPDFDoc;

-  CPDFSDK_Document* m_pSDKDoc;

-  IXFA_Doc* m_pXFADoc;

-  IXFA_DocView* m_pXFADocView;

-  CPDFXFA_App* m_pApp;

-  IJS_Context* m_pJSContext;

-  CFX_ArrayTemplate<CPDFXFA_Page*> m_XFAPageList;

-};

-

-#endif  // FPDFXFA_DOC_H_

+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFXFA_DOC_H_
+#define FPDFXFA_DOC_H_
+
+#include "public/fpdfview.h"
+#include "xfa/include/fxfa/fxfa.h"
+
+class CPDFXFA_App;
+class CPDFXFA_Document;
+class CPDFXFA_Page;
+class CPDFSDK_Document;
+class CPDFDoc_Environment;
+class IJS_Runtime;
+class IJS_Context;
+class IXFA_DocHandler;
+
+class CPDFXFA_Document : public IXFA_DocProvider {
+ public:
+  CPDFXFA_Document(CPDF_Document* pPDFDoc, CPDFXFA_App* pProvider);
+  ~CPDFXFA_Document();
+
+  FX_BOOL LoadXFADoc();
+  CPDFXFA_App* GetApp() { return m_pApp; }
+  CPDF_Document* GetPDFDoc() { return m_pPDFDoc; }
+  IXFA_Doc* GetXFADoc() { return m_pXFADoc; }
+  IXFA_DocView* GetXFADocView() { return m_pXFADocView; }
+
+  int GetPageCount();
+  CPDFXFA_Page* GetPage(int page_index);
+  CPDFXFA_Page* GetPage(IXFA_PageView* pPage);
+  void RemovePage(CPDFXFA_Page* page);
+  int GetDocType() { return m_iDocType; }
+
+  CPDFSDK_Document* GetSDKDocument(CPDFDoc_Environment* pFormFillEnv);
+
+  void FXRect2PDFRect(const CFX_RectF& fxRectF, CPDF_Rect& pdfRect);
+
+  virtual void SetChangeMark(IXFA_Doc* hDoc);
+  virtual FX_BOOL GetChangeMark(IXFA_Doc* hDoc);
+  // used in dynamic xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.
+  virtual void InvalidateRect(IXFA_PageView* pPageView,
+                              const CFX_RectF& rt,
+                              FX_DWORD dwFlags = 0);
+  // used in static xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.
+  virtual void InvalidateRect(IXFA_Widget* hWidget, FX_DWORD dwFlags = 0);
+  // show or hide caret
+  virtual void DisplayCaret(IXFA_Widget* hWidget,
+                            FX_BOOL bVisible,
+                            const CFX_RectF* pRtAnchor);
+  // dwPos: (0:bottom 1:top)
+  virtual FX_BOOL GetPopupPos(IXFA_Widget* hWidget,
+                              FX_FLOAT fMinPopup,
+                              FX_FLOAT fMaxPopup,
+                              const CFX_RectF& rtAnchor,
+                              CFX_RectF& rtPopup);
+  virtual FX_BOOL PopupMenu(IXFA_Widget* hWidget,
+                            CFX_PointF ptPopup,
+                            const CFX_RectF* pRectExclude = NULL);
+
+  // dwFlags XFA_PAGEVIEWEVENT_Added, XFA_PAGEVIEWEVENT_Removing
+  virtual void PageViewEvent(IXFA_PageView* pPageView, FX_DWORD dwFlags);
+  // dwEvent refer to XFA_WIDGETEVENT_XXX
+  virtual void WidgetEvent(IXFA_Widget* hWidget,
+                           CXFA_WidgetAcc* pWidgetData,
+                           FX_DWORD dwEvent,
+                           void* pParam = NULL,
+                           void* pAdditional = NULL);
+
+  // return true if render it.
+  virtual FX_BOOL RenderCustomWidget(IXFA_Widget* hWidget,
+                                     CFX_Graphics* pGS,
+                                     CFX_Matrix* pMatrix,
+                                     const CFX_RectF& rtUI) {
+    return FALSE;
+  }
+
+  // host method
+  virtual int32_t CountPages(IXFA_Doc* hDoc);
+  virtual int32_t GetCurrentPage(IXFA_Doc* hDoc);
+  virtual void SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage);
+  virtual FX_BOOL IsCalculationsEnabled(IXFA_Doc* hDoc);
+  virtual void SetCalculationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled);
+  virtual void GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle);
+  virtual void SetTitle(IXFA_Doc* hDoc, const CFX_WideStringC& wsTitle);
+  virtual void ExportData(IXFA_Doc* hDoc,
+                          const CFX_WideStringC& wsFilePath,
+                          FX_BOOL bXDP = TRUE);
+  virtual void ImportData(IXFA_Doc* hDoc, const CFX_WideStringC& wsFilePath);
+  virtual void GotoURL(IXFA_Doc* hDoc,
+                       const CFX_WideStringC& bsURL,
+                       FX_BOOL bAppend = TRUE);
+  virtual FX_BOOL IsValidationsEnabled(IXFA_Doc* hDoc);
+  virtual void SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled);
+  virtual void SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget);
+  virtual void Print(IXFA_Doc* hDoc,
+                     int32_t nStartPage,
+                     int32_t nEndPage,
+                     FX_DWORD dwOptions);
+
+  // LayoutPseudo method
+  virtual int32_t AbsPageCountInBatch(IXFA_Doc* hDoc) { return 0; }
+  virtual int32_t AbsPageInBatch(IXFA_Doc* hDoc, IXFA_Widget* hWidget) {
+    return 0;
+  }
+  virtual int32_t SheetCountInBatch(IXFA_Doc* hDoc) { return 0; }
+  virtual int32_t SheetInBatch(IXFA_Doc* hDoc, IXFA_Widget* hWidget) {
+    return 0;
+  }
+
+  // SignaturePseudoModel method
+  // TODO:
+  virtual int32_t Verify(
+      IXFA_Doc* hDoc,
+      CXFA_Node* pSigNode,
+      FX_BOOL
+          bUsed = TRUE /*, SecurityHandler* pHandler, SignatureInfo &info*/) {
+    return 0;
+  }
+  virtual FX_BOOL Sign(
+      IXFA_Doc* hDoc,
+      CXFA_NodeList* pNodeList,
+      const CFX_WideStringC& wsExpression,
+      const CFX_WideStringC& wsXMLIdent,
+      const CFX_WideStringC& wsValue = FX_WSTRC(L"open"),
+      FX_BOOL
+          bUsed = TRUE /*, SecurityHandler* pHandler = NULL, SignatureInfo &info*/) {
+    return 0;
+  }
+  virtual CXFA_NodeList* Enumerate(IXFA_Doc* hDoc) { return 0; }
+  virtual FX_BOOL Clear(IXFA_Doc* hDoc,
+                        CXFA_Node* pSigNode,
+                        FX_BOOL bCleared = TRUE) {
+    return 0;
+  }
+
+  // Get document path
+  virtual void GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL);
+  virtual FX_ARGB GetHighlightColor(IXFA_Doc* hDoc);
+
+  /**
+   *Submit data to email, http, ftp.
+   * @param[in] hDoc The document handler.
+   * @param[in] eFormat Determines the format in which the data will be
+   *submitted. XFA_ATTRIBUTEENUM_Xdp, XFA_ATTRIBUTEENUM_Xml...
+   * @param[in] wsTarget The URL to which the data will be submitted.
+   * @param[in] eEncoding The encoding of text content.
+   * @param[in] pXDPContent Controls what subset of the data is submitted, used
+   *only when the format property is xdp.
+   * @param[in] bEmbedPDF, specifies whether PDF is embedded in the submitted
+   *content or not.
+   */
+  virtual FX_BOOL SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit);
+
+  virtual FX_BOOL CheckWord(IXFA_Doc* hDoc, const CFX_ByteStringC& sWord) {
+    return FALSE;
+  }
+  virtual FX_BOOL GetSuggestWords(IXFA_Doc* hDoc,
+                                  const CFX_ByteStringC& sWord,
+                                  CFX_ByteStringArray& sSuggest) {
+    return FALSE;
+  }
+
+  // Get PDF javascript object, set the object to hValue.
+  virtual FX_BOOL GetPDFScriptObject(IXFA_Doc* hDoc,
+                                     const CFX_ByteStringC& utf8Name,
+                                     FXJSE_HVALUE hValue);
+
+  virtual FX_BOOL GetGlobalProperty(IXFA_Doc* hDoc,
+                                    const CFX_ByteStringC& szPropName,
+                                    FXJSE_HVALUE hValue);
+  virtual FX_BOOL SetGlobalProperty(IXFA_Doc* hDoc,
+                                    const CFX_ByteStringC& szPropName,
+                                    FXJSE_HVALUE hValue);
+  virtual CPDF_Document* OpenPDF(IXFA_Doc* hDoc,
+                                 IFX_FileRead* pFile,
+                                 FX_BOOL bTakeOverFile) {
+    return NULL;
+  }
+
+  virtual IFX_FileRead* OpenLinkedFile(IXFA_Doc* hDoc,
+                                       const CFX_WideString& wsLink);
+
+  FX_BOOL _GetHValueByName(const CFX_ByteStringC& utf8Name,
+                           FXJSE_HVALUE hValue,
+                           IJS_Runtime* runTime);
+  FX_BOOL _OnBeforeNotifySumbit();
+  void _OnAfterNotifySumbit();
+  FX_BOOL _NotifySubmit(FX_BOOL bPrevOrPost);
+  FX_BOOL _SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit);
+  FX_BOOL _MailToInfo(CFX_WideString& csURL,
+                      CFX_WideString& csToAddress,
+                      CFX_WideString& csCCAddress,
+                      CFX_WideString& csBCCAddress,
+                      CFX_WideString& csSubject,
+                      CFX_WideString& csMsg);
+  FX_BOOL _ExportSubmitFile(FPDF_FILEHANDLER* ppFileHandler,
+                            int fileType,
+                            FPDF_DWORD encodeType,
+                            FPDF_DWORD flag = 0x01111111);
+  void _ToXFAContentFlags(CFX_WideString csSrcContent, FPDF_DWORD& flag);
+  void _ClearChangeMark();
+
+ private:
+  void CloseXFADoc(IXFA_DocHandler* pDoc) {
+    if (pDoc) {
+      pDoc->CloseDoc(m_pXFADoc);
+      pDoc->ReleaseDoc(m_pXFADoc);
+      m_pXFADoc = NULL;
+      m_pXFADocView = NULL;
+    }
+  }
+
+  int m_iDocType;
+  CPDF_Document* m_pPDFDoc;
+  CPDFSDK_Document* m_pSDKDoc;
+  IXFA_Doc* m_pXFADoc;
+  IXFA_DocView* m_pXFADocView;
+  CPDFXFA_App* m_pApp;
+  IJS_Context* m_pJSContext;
+  CFX_ArrayTemplate<CPDFXFA_Page*> m_XFAPageList;
+};
+
+#endif  // FPDFXFA_DOC_H_
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h
index db47784..814599c 100644
--- a/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h
+++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h
@@ -1,66 +1,66 @@
-// Copyright 2014 PDFium Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-

-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

-

-#ifndef _FPDFXFA_PAGEVIEW_H_

-#define _FPDFXFA_PAGEVIEW_H_

-

-class CPDFXFA_Page {

- public:

-  CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index);

-  ~CPDFXFA_Page();

-

-  void Release();

-  void AddRef() { m_iRef++; }

-  FX_BOOL LoadPage();

-  FX_BOOL LoadPDFPage(CPDF_Dictionary* pageDict);

-  CPDFXFA_Document* GetDocument() { return m_pDocument; }

-  int GetPageIndex() { return m_iPageIndex; }

-  CPDF_Page* GetPDFPage() { return m_pPDFPage; }

-  IXFA_PageView* GetXFAPageView() { return m_pXFAPageView; }

-  void SetXFAPageView(IXFA_PageView* pPageView) { m_pXFAPageView = pPageView; }

-

-  FX_FLOAT GetPageWidth();

-  FX_FLOAT GetPageHeight();

-

-  void DeviceToPage(int start_x,

-                    int start_y,

-                    int size_x,

-                    int size_y,

-                    int rotate,

-                    int device_x,

-                    int device_y,

-                    double* page_x,

-                    double* page_y);

-  void PageToDevice(int start_x,

-                    int start_y,

-                    int size_x,

-                    int size_y,

-                    int rotate,

-                    double page_x,

-                    double page_y,

-                    int* device_x,

-                    int* device_y);

-

-  void GetDisplayMatrix(CFX_Matrix& matrix,

-                        int xPos,

-                        int yPos,

-                        int xSize,

-                        int ySize,

-                        int iRotate) const;

-

- protected:

-  FX_BOOL LoadPDFPage();

-  FX_BOOL LoadXFAPageView();

-

- private:

-  CPDF_Page* m_pPDFPage;

-  IXFA_PageView* m_pXFAPageView;

-  int m_iPageIndex;

-  CPDFXFA_Document* m_pDocument;

-  int m_iRef;

-};

-

-#endif

+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FPDFXFA_PAGEVIEW_H_
+#define _FPDFXFA_PAGEVIEW_H_
+
+class CPDFXFA_Page {
+ public:
+  CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index);
+  ~CPDFXFA_Page();
+
+  void Release();
+  void AddRef() { m_iRef++; }
+  FX_BOOL LoadPage();
+  FX_BOOL LoadPDFPage(CPDF_Dictionary* pageDict);
+  CPDFXFA_Document* GetDocument() { return m_pDocument; }
+  int GetPageIndex() { return m_iPageIndex; }
+  CPDF_Page* GetPDFPage() { return m_pPDFPage; }
+  IXFA_PageView* GetXFAPageView() { return m_pXFAPageView; }
+  void SetXFAPageView(IXFA_PageView* pPageView) { m_pXFAPageView = pPageView; }
+
+  FX_FLOAT GetPageWidth();
+  FX_FLOAT GetPageHeight();
+
+  void DeviceToPage(int start_x,
+                    int start_y,
+                    int size_x,
+                    int size_y,
+                    int rotate,
+                    int device_x,
+                    int device_y,
+                    double* page_x,
+                    double* page_y);
+  void PageToDevice(int start_x,
+                    int start_y,
+                    int size_x,
+                    int size_y,
+                    int rotate,
+                    double page_x,
+                    double page_y,
+                    int* device_x,
+                    int* device_y);
+
+  void GetDisplayMatrix(CFX_Matrix& matrix,
+                        int xPos,
+                        int yPos,
+                        int xSize,
+                        int ySize,
+                        int iRotate) const;
+
+ protected:
+  FX_BOOL LoadPDFPage();
+  FX_BOOL LoadXFAPageView();
+
+ private:
+  CPDF_Page* m_pPDFPage;
+  IXFA_PageView* m_pXFAPageView;
+  int m_iPageIndex;
+  CPDFXFA_Document* m_pDocument;
+  int m_iRef;
+};
+
+#endif
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h
index a64d030..ca675bf 100644
--- a/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h
+++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h
@@ -1,40 +1,40 @@
-// Copyright 2014 PDFium Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-

-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

-

-#ifndef FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_

-#define FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_

-

-#include "xfa/include/fwl/adapter/fwl_adaptertimermgr.h"

-

-#define JS_STR_VIEWERTYPE_STANDARD L"Exchange"

-#define JS_STR_LANGUANGE L"ENU"

-#define JS_STR_VIEWERVARIATION L"Full"

-#define JS_STR_VIEWERVERSION_XFA L"11"

-

-class CXFA_FWLAdapterTimerMgr : public IFWL_AdapterTimerMgr {

- public:

-  CXFA_FWLAdapterTimerMgr(CPDFDoc_Environment* pEnv) : m_pEnv(pEnv) {}

-  virtual FWL_ERR Start(IFWL_Timer* pTimer,

-                        FX_DWORD dwElapse,

-                        FWL_HTIMER& hTimer,

-                        FX_BOOL bImmediately = TRUE);

-  virtual FWL_ERR Stop(FWL_HTIMER hTimer);

-

- protected:

-  static void TimerProc(int32_t idEvent);

-

-  static CFX_PtrArray ms_timerArray;

-  CPDFDoc_Environment* m_pEnv;

-};

-

-class CFWL_TimerInfo {

- public:

-  CFWL_TimerInfo() : pTimer(nullptr) {}

-  uint32_t uIDEvent;

-  IFWL_Timer* pTimer;

-};

-

-#endif  // FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_

+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_
+#define FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_
+
+#include "xfa/include/fwl/adapter/fwl_adaptertimermgr.h"
+
+#define JS_STR_VIEWERTYPE_STANDARD L"Exchange"
+#define JS_STR_LANGUANGE L"ENU"
+#define JS_STR_VIEWERVARIATION L"Full"
+#define JS_STR_VIEWERVERSION_XFA L"11"
+
+class CXFA_FWLAdapterTimerMgr : public IFWL_AdapterTimerMgr {
+ public:
+  CXFA_FWLAdapterTimerMgr(CPDFDoc_Environment* pEnv) : m_pEnv(pEnv) {}
+  virtual FWL_ERR Start(IFWL_Timer* pTimer,
+                        FX_DWORD dwElapse,
+                        FWL_HTIMER& hTimer,
+                        FX_BOOL bImmediately = TRUE);
+  virtual FWL_ERR Stop(FWL_HTIMER hTimer);
+
+ protected:
+  static void TimerProc(int32_t idEvent);
+
+  static CFX_PtrArray ms_timerArray;
+  CPDFDoc_Environment* m_pEnv;
+};
+
+class CFWL_TimerInfo {
+ public:
+  CFWL_TimerInfo() : pTimer(nullptr) {}
+  uint32_t uIDEvent;
+  IFWL_Timer* pTimer;
+};
+
+#endif  // FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_
diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp
index 853eb30..44e9c72 100644
--- a/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp
+++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp
@@ -1,537 +1,537 @@
-// Copyright 2014 PDFium Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-

-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

-

-#include "fpdfsdk/include/fsdk_define.h"

-#include "fpdfsdk/include/fsdk_mgr.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"

-#include "fpdfsdk/include/javascript/IJavaScript.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"

-#include "public/fpdf_formfill.h"

-

-CPDFXFA_App* CPDFXFA_App::g_pApp = NULL;

-

-CPDFXFA_App* CPDFXFA_App::GetInstance() {

-  if (!g_pApp) {

-    g_pApp = new CPDFXFA_App();

-  }

-  return g_pApp;

-}

-

-void CPDFXFA_App::ReleaseInstance() {

-  delete g_pApp;

-  g_pApp = NULL;

-}

-

-CPDFXFA_App::CPDFXFA_App()

-    : m_bJavaScriptInitialized(FALSE),

-      m_pXFAApp(NULL),

-      m_pFontMgr(NULL),

-      m_hJSERuntime(NULL),

-      m_csAppType(JS_STR_VIEWERTYPE_STANDARD) {

-  m_pEnvList.RemoveAll();

-}

-

-CPDFXFA_App::~CPDFXFA_App() {

-  delete m_pFontMgr;

-  m_pFontMgr = NULL;

-

-  delete m_pXFAApp;

-  m_pXFAApp = NULL;

-

-#ifdef PDF_ENABLE_XFA

-  FXJSE_Runtime_Release(m_hJSERuntime);

-  m_hJSERuntime = NULL;

-

-  FXJSE_Finalize();

-  BC_Library_Destory();

-#endif

-}

-

-FX_BOOL CPDFXFA_App::Initialize() {

-#ifdef PDF_ENABLE_XFA

-  BC_Library_Init();

-  FXJSE_Initialize();

-

-  m_hJSERuntime = FXJSE_Runtime_Create();

-  if (!m_hJSERuntime)

-    return FALSE;

-

-  m_pXFAApp = IXFA_App::Create(this);

-  if (!m_pXFAApp)

-    return FALSE;

-

-  m_pFontMgr = IXFA_FontMgr::CreateDefault();

-  if (!m_pFontMgr)

-    return FALSE;

-

-  m_pXFAApp->SetDefaultFontMgr(m_pFontMgr);

-#endif

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_App::AddFormFillEnv(CPDFDoc_Environment* pEnv) {

-  if (!pEnv)

-    return FALSE;

-

-  m_pEnvList.Add(pEnv);

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_App::RemoveFormFillEnv(CPDFDoc_Environment* pEnv) {

-  if (!pEnv)

-    return FALSE;

-

-  int nFind = m_pEnvList.Find(pEnv);

-  if (nFind != -1) {

-    m_pEnvList.RemoveAt(nFind);

-    return TRUE;

-  }

-

-  return FALSE;

-}

-

-void CPDFXFA_App::GetAppType(CFX_WideString& wsAppType) {

-  wsAppType = m_csAppType;

-}

-

-void CPDFXFA_App::GetAppName(CFX_WideString& wsName) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    wsName = pEnv->FFI_GetAppName();

-  }

-}

-

-void CPDFXFA_App::SetAppType(const CFX_WideStringC& wsAppType) {

-  m_csAppType = wsAppType;

-}

-

-void CPDFXFA_App::GetLanguage(CFX_WideString& wsLanguage) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    wsLanguage = pEnv->FFI_GetLanguage();

-  }

-}

-

-void CPDFXFA_App::GetPlatform(CFX_WideString& wsPlatform) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    wsPlatform = pEnv->FFI_GetPlatform();

-  }

-}

-

-void CPDFXFA_App::GetVariation(CFX_WideString& wsVariation) {

-  wsVariation = JS_STR_VIEWERVARIATION;

-}

-

-void CPDFXFA_App::GetVersion(CFX_WideString& wsVersion) {

-  wsVersion = JS_STR_VIEWERVERSION_XFA;

-}

-

-void CPDFXFA_App::Beep(FX_DWORD dwType) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    pEnv->JS_appBeep(dwType);

-  }

-}

-

-int32_t CPDFXFA_App::MsgBox(const CFX_WideStringC& wsMessage,

-                            const CFX_WideStringC& wsTitle,

-                            FX_DWORD dwIconType,

-                            FX_DWORD dwButtonType) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (!pEnv)

-    return -1;

-

-  FX_DWORD iconType = 0;

-  int iButtonType = 0;

-  switch (dwIconType) {

-    case XFA_MBICON_Error:

-      iconType |= 0;

-      break;

-    case XFA_MBICON_Warning:

-      iconType |= 1;

-      break;

-    case XFA_MBICON_Question:

-      iconType |= 2;

-      break;

-    case XFA_MBICON_Status:

-      iconType |= 3;

-      break;

-  }

-  switch (dwButtonType) {

-    case XFA_MB_OK:

-      iButtonType |= 0;

-      break;

-    case XFA_MB_OKCancel:

-      iButtonType |= 1;

-      break;

-    case XFA_MB_YesNo:

-      iButtonType |= 2;

-      break;

-    case XFA_MB_YesNoCancel:

-      iButtonType |= 3;

-      break;

-  }

-  int32_t iRet = pEnv->JS_appAlert(wsMessage.GetPtr(), wsTitle.GetPtr(),

-                                   iButtonType, iconType);

-  switch (iRet) {

-    case 1:

-      return XFA_IDOK;

-    case 2:

-      return XFA_IDCancel;

-    case 3:

-      return XFA_IDNo;

-    case 4:

-      return XFA_IDYes;

-  }

-  return XFA_IDYes;

-}

-

-void CPDFXFA_App::Response(CFX_WideString& wsAnswer,

-                           const CFX_WideStringC& wsQuestion,

-                           const CFX_WideStringC& wsTitle,

-                           const CFX_WideStringC& wsDefaultAnswer,

-                           FX_BOOL bMark) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    int nLength = 2048;

-    char* pBuff = new char[nLength];

-    nLength = pEnv->JS_appResponse(wsQuestion.GetPtr(), wsTitle.GetPtr(),

-                                   wsDefaultAnswer.GetPtr(), NULL, bMark, pBuff,

-                                   nLength);

-    if (nLength > 0) {

-      nLength = nLength > 2046 ? 2046 : nLength;

-      pBuff[nLength] = 0;

-      pBuff[nLength + 1] = 0;

-      wsAnswer = CFX_WideString::FromUTF16LE(

-          reinterpret_cast<const unsigned short*>(pBuff),

-          nLength / sizeof(unsigned short));

-    }

-    delete[] pBuff;

-  }

-}

-

-int32_t CPDFXFA_App::GetCurDocumentInBatch() {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    return pEnv->FFI_GetCurDocument();

-  }

-  return 0;

-}

-

-int32_t CPDFXFA_App::GetDocumentCountInBatch() {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    return pEnv->FFI_GetDocumentCount();

-  }

-

-  return 0;

-}

-

-IFX_FileRead* CPDFXFA_App::DownloadURL(const CFX_WideStringC& wsURL) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    return pEnv->FFI_DownloadFromURL(wsURL.GetPtr());

-  }

-  return NULL;

-}

-

-FX_BOOL CPDFXFA_App::PostRequestURL(const CFX_WideStringC& wsURL,

-                                    const CFX_WideStringC& wsData,

-                                    const CFX_WideStringC& wsContentType,

-                                    const CFX_WideStringC& wsEncode,

-                                    const CFX_WideStringC& wsHeader,

-                                    CFX_WideString& wsResponse) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    wsResponse = pEnv->FFI_PostRequestURL(wsURL.GetPtr(), wsData.GetPtr(),

-                                          wsContentType.GetPtr(),

-                                          wsEncode.GetPtr(), wsHeader.GetPtr());

-    return TRUE;

-  }

-  return FALSE;

-}

-

-FX_BOOL CPDFXFA_App::PutRequestURL(const CFX_WideStringC& wsURL,

-                                   const CFX_WideStringC& wsData,

-                                   const CFX_WideStringC& wsEncode) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    return pEnv->FFI_PutRequestURL(wsURL.GetPtr(), wsData.GetPtr(),

-                                   wsEncode.GetPtr());

-  }

-  return FALSE;

-}

-

-void CPDFXFA_App::LoadString(int32_t iStringID, CFX_WideString& wsString) {

-  switch (iStringID) {

-    case XFA_IDS_ValidateFailed:

-      wsString = L"%s validate failed";

-      return;

-    case XFA_IDS_CalcOverride:

-      wsString = L"Calculate Override";

-      return;

-    case XFA_IDS_ModifyField:

-      wsString = L"Are you sure you want to modify this field?";

-      return;

-    case XFA_IDS_NotModifyField:

-      wsString = L"You are not allowed to modify this field.";

-      return;

-    case XFA_IDS_AppName:

-      wsString = L"Foxit";

-      return;

-    case XFA_IDS_ImageFilter:

-      wsString =

-          L"Image "

-          L"Files(*.bmp;*.jpg;*.png;*.gif;*.tif)|*.bmp;*.jpg;*.png;*.gif;*.tif|"

-          L"All Files(*.*)|*.*||";

-      return;

-    case XFA_IDS_UNKNOW_CATCHED:

-      wsString = L"unknown error is catched!";

-      return;

-    case XFA_IDS_Unable_TO_SET:

-      wsString = L"Unable to set ";

-      return;

-    case XFA_IDS_VALUE_EXCALMATORY:

-      wsString = L" value!";

-      return;

-    case XFA_IDS_INVALID_ENUM_VALUE:

-      wsString = L"Invalid enumerated value: ";

-      return;

-    case XFA_IDS_UNSUPPORT_METHOD:

-      wsString = L"unsupport %s method.";

-      return;

-    case XFA_IDS_UNSUPPORT_PROP:

-      wsString = L"unsupport %s property.";

-      return;

-    case XFA_IDS_INVAlID_PROP_SET:

-      wsString = L"Invalid property set operation;";

-      return;

-    case XFA_IDS_NOT_DEFAUL_VALUE:

-      wsString = L" doesn't have a default property";

-      return;

-    case XFA_IDS_UNABLE_SET_LANGUAGE:

-      wsString = L"Unable to set language value!";

-      return;

-    case XFA_IDS_UNABLE_SET_NUMPAGES:

-      wsString = L"Unable to set numPages value!";

-      return;

-    case XFA_IDS_UNABLE_SET_PLATFORM:

-      wsString = L"Unable to set platform value!";

-      return;

-    case XFA_IDS_UNABLE_SET_VALIDATIONENABLE:

-      wsString = L"Unable to set validationsEnabled value!";

-      return;

-    case XFA_IDS_UNABLE_SET_VARIATION:

-      wsString = L"Unable to set variation value!";

-      return;

-    case XFA_IDS_UNABLE_SET_VERSION:

-      wsString = L"Unable to set version value!";

-      return;

-    case XFA_IDS_UNABLE_SET_READY:

-      wsString = L"Unable to set ready value!";

-      return;

-    case XFA_IDS_NUMBER_OF_OCCUR:

-      wsString =

-          L"The element [%s] has violated its allowable number of occurrences";

-      return;

-    case XFA_IDS_UNABLE_SET_CLASS_NAME:

-      wsString = L"Unable to set className value!";

-      return;

-    case XFA_IDS_UNABLE_SET_LENGTH_VALUE:

-      wsString = L"Unable to set length value!";

-      return;

-    case XFA_IDS_UNSUPPORT_CHAR:

-      wsString = L"unsupported char '%c'";

-      return;

-    case XFA_IDS_BAD_SUFFIX:

-      wsString = L"bad suffix on number";

-      return;

-    case XFA_IDS_EXPECTED_IDENT:

-      wsString = L"expected identifier instead of '%s'";

-      return;

-    case XFA_IDS_EXPECTED_STRING:

-      wsString = L"expected '%s' instead of '%s'";

-      return;

-    case XFA_IDS_INVALIDATE_CHAR:

-      wsString = L"invalidate char '%c'";

-      return;

-    case XFA_IDS_REDEFINITION:

-      wsString = L"'%s' redefinition ";

-      return;

-    case XFA_IDS_INVALIDATE_TOKEN:

-      wsString = L"invalidate token '%s'";

-      return;

-    case XFA_IDS_INVALIDATE_EXPRESSION:

-      wsString = L"invalidate expression '%s'";

-      return;

-    case XFA_IDS_UNDEFINE_IDENTIFIER:

-      wsString = L"undefined identifier '%s'";

-      return;

-    case XFA_IDS_INVALIDATE_LEFTVALUE:

-      wsString = L"invalidate left-value '%s'";

-      return;

-    case XFA_IDS_COMPILER_ERROR:

-      wsString = L"compiler error";

-      return;

-    case XFA_IDS_CANNOT_MODIFY_VALUE:

-      wsString = L"can't modify the '%s' value";

-      return;

-    case XFA_IDS_ERROR_PARAMETERS:

-      wsString = L"function '%s' has not %d parameters";

-      return;

-    case XFA_IDS_EXPECT_ENDIF:

-      wsString = L"expected 'endif' instead of '%s'";

-      return;

-    case XFA_IDS_UNEXPECTED_EXPRESSION:

-      wsString = L"unexpected expression '%s'";

-      return;

-    case XFA_IDS_CONDITION_IS_NULL:

-      wsString = L"condition is null";

-      return;

-    case XFA_IDS_ILLEGALBREAK:

-      wsString = L"illegal break";

-      return;

-    case XFA_IDS_ILLEGALCONTINUE:

-      wsString = L"illegal continue";

-      return;

-    case XFA_IDS_EXPECTED_OPERATOR:

-      wsString = L"expected operator '%s' instead of '%s'";

-      return;

-    case XFA_IDS_DIVIDE_ZERO:

-      wsString = L"divide by zero";

-      return;

-    case XFA_IDS_CANNOT_COVERT_OBJECT:

-      wsString = L"%s.%s can not covert to object";

-      return;

-    case XFA_IDS_NOT_FOUND_CONTAINER:

-      wsString = L"can not found container '%s'";

-      return;

-    case XFA_IDS_NOT_FOUND_PROPERTY:

-      wsString = L"can not found property '%s'";

-      return;

-    case XFA_IDS_NOT_FOUND_METHOD:

-      wsString = L"can not found method '%s'";

-      return;

-    case XFA_IDS_NOT_FOUND_CONST:

-      wsString = L"can not found const '%s'";

-      return;

-    case XFA_IDS_NOT_ASSIGN_OBJECT:

-      wsString = L"can not direct assign value to object";

-      return;

-    case XFA_IDS_IVALIDATE_INSTRUCTION:

-      wsString = L"invalidate instruction";

-      return;

-    case XFA_IDS_EXPECT_NUMBER:

-      wsString = L"expected number instead of '%s'";

-      return;

-    case XFA_IDS_VALIDATE_OUT_ARRAY:

-      wsString = L"validate access index '%s' out of array";

-      return;

-    case XFA_IDS_CANNOT_ASSIGN_IDENT:

-      wsString = L"can not assign to %s";

-      return;

-    case XFA_IDS_NOT_FOUNT_FUNCTION:

-      wsString = L"can not found '%s' function";

-      return;

-    case XFA_IDS_NOT_ARRAY:

-      wsString = L"'%s' doesn't an array";

-      return;

-    case XFA_IDS_OUT_ARRAY:

-      wsString = L"out of range of '%s' array";

-      return;

-    case XFA_IDS_NOT_SUPPORT_CALC:

-      wsString = L"'%s' operator can not support array calculate";

-      return;

-    case XFA_IDS_ARGUMENT_NOT_ARRAY:

-      wsString = L"'%s' function's %d argument can not be array";

-      return;

-    case XFA_IDS_ARGUMENT_EXPECT_CONTAINER:

-      wsString = L"'%s' argument expected a container";

-      return;

-    case XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT:

-      wsString =

-          L"an attempt was made to reference property '%s' of a non-object in "

-          L"SOM expression %s";

-      return;

-    case XFA_IDS_FUNCTION_IS_BUILDIN:

-      wsString = L"function '%s' is buildin";

-      return;

-    case XFA_IDS_ERROR_MSG:

-      wsString = L"%s : %s";

-      return;

-    case XFA_IDS_INDEX_OUT_OF_BOUNDS:

-      wsString = L"Index value is out of bounds";

-      return;

-    case XFA_IDS_INCORRECT_NUMBER_OF_METHOD:

-      wsString = L"Incorrect number of parameters calling method '%s'";

-      return;

-    case XFA_IDS_ARGUMENT_MISMATCH:

-      wsString = L"Argument mismatch in property or function argument";

-      return;

-    case XFA_IDS_INVALID_ENUMERATE:

-      wsString = L"Invalid enumerated value: %s";

-      return;

-    case XFA_IDS_INVALID_APPEND:

-      wsString =

-          L"Invalid append operation: %s cannot have a child element of %s";

-      return;

-    case XFA_IDS_SOM_EXPECTED_LIST:

-      wsString =

-          L"SOM expression returned list when single result was expected";

-      return;

-    case XFA_IDS_NOT_HAVE_PROPERTY:

-      wsString = L"'%s' doesn't have property '%s'";

-      return;

-    case XFA_IDS_INVALID_NODE_TYPE:

-      wsString = L"Invalid node type : '%s'";

-      return;

-    case XFA_IDS_VIOLATE_BOUNDARY:

-      wsString =

-          L"The element [%s] has violated its allowable number of occurrences";

-      return;

-    case XFA_IDS_SERVER_DENY:

-      wsString = L"Server does not permit";

-      return;

-    case XFA_IDS_ValidateLimit:

-      wsString = FX_WSTRC(

-          L"Message limit exceeded. Remaining %d validation errors not "

-          L"reported.");

-      return;

-    case XFA_IDS_ValidateNullWarning:

-      wsString = FX_WSTRC(

-          L"%s cannot be left blank. To ignore validations for %s, click "

-          L"Ignore.");

-      return;

-    case XFA_IDS_ValidateNullError:

-      wsString = FX_WSTRC(L"%s cannot be left blank.");

-      return;

-    case XFA_IDS_ValidateWarning:

-      wsString = FX_WSTRC(

-          L"The value you entered for %s is invalid. To ignore validations for "

-          L"%s, click Ignore.");

-      return;

-    case XFA_IDS_ValidateError:

-      wsString = FX_WSTRC(L"The value you entered for %s is invalid.");

-      return;

-  }

-}

-

-FX_BOOL CPDFXFA_App::ShowFileDialog(const CFX_WideStringC& wsTitle,

-                                    const CFX_WideStringC& wsFilter,

-                                    CFX_WideStringArray& wsPathArr,

-                                    FX_BOOL bOpen) {

-  return FALSE;

-}

-

-IFWL_AdapterTimerMgr* CPDFXFA_App::GetTimerMgr() {

-  CXFA_FWLAdapterTimerMgr* pAdapter = NULL;

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv)

-    pAdapter = new CXFA_FWLAdapterTimerMgr(pEnv);

-  return pAdapter;

-}

+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/include/fsdk_define.h"
+#include "fpdfsdk/include/fsdk_mgr.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
+#include "fpdfsdk/include/javascript/IJavaScript.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
+#include "public/fpdf_formfill.h"
+
+CPDFXFA_App* CPDFXFA_App::g_pApp = NULL;
+
+CPDFXFA_App* CPDFXFA_App::GetInstance() {
+  if (!g_pApp) {
+    g_pApp = new CPDFXFA_App();
+  }
+  return g_pApp;
+}
+
+void CPDFXFA_App::ReleaseInstance() {
+  delete g_pApp;
+  g_pApp = NULL;
+}
+
+CPDFXFA_App::CPDFXFA_App()
+    : m_bJavaScriptInitialized(FALSE),
+      m_pXFAApp(NULL),
+      m_pFontMgr(NULL),
+      m_hJSERuntime(NULL),
+      m_csAppType(JS_STR_VIEWERTYPE_STANDARD) {
+  m_pEnvList.RemoveAll();
+}
+
+CPDFXFA_App::~CPDFXFA_App() {
+  delete m_pFontMgr;
+  m_pFontMgr = NULL;
+
+  delete m_pXFAApp;
+  m_pXFAApp = NULL;
+
+#ifdef PDF_ENABLE_XFA
+  FXJSE_Runtime_Release(m_hJSERuntime);
+  m_hJSERuntime = NULL;
+
+  FXJSE_Finalize();
+  BC_Library_Destory();
+#endif
+}
+
+FX_BOOL CPDFXFA_App::Initialize() {
+#ifdef PDF_ENABLE_XFA
+  BC_Library_Init();
+  FXJSE_Initialize();
+
+  m_hJSERuntime = FXJSE_Runtime_Create();
+  if (!m_hJSERuntime)
+    return FALSE;
+
+  m_pXFAApp = IXFA_App::Create(this);
+  if (!m_pXFAApp)
+    return FALSE;
+
+  m_pFontMgr = IXFA_FontMgr::CreateDefault();
+  if (!m_pFontMgr)
+    return FALSE;
+
+  m_pXFAApp->SetDefaultFontMgr(m_pFontMgr);
+#endif
+  return TRUE;
+}
+
+FX_BOOL CPDFXFA_App::AddFormFillEnv(CPDFDoc_Environment* pEnv) {
+  if (!pEnv)
+    return FALSE;
+
+  m_pEnvList.Add(pEnv);
+  return TRUE;
+}
+
+FX_BOOL CPDFXFA_App::RemoveFormFillEnv(CPDFDoc_Environment* pEnv) {
+  if (!pEnv)
+    return FALSE;
+
+  int nFind = m_pEnvList.Find(pEnv);
+  if (nFind != -1) {
+    m_pEnvList.RemoveAt(nFind);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+void CPDFXFA_App::GetAppType(CFX_WideString& wsAppType) {
+  wsAppType = m_csAppType;
+}
+
+void CPDFXFA_App::GetAppName(CFX_WideString& wsName) {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv) {
+    wsName = pEnv->FFI_GetAppName();
+  }
+}
+
+void CPDFXFA_App::SetAppType(const CFX_WideStringC& wsAppType) {
+  m_csAppType = wsAppType;
+}
+
+void CPDFXFA_App::GetLanguage(CFX_WideString& wsLanguage) {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv) {
+    wsLanguage = pEnv->FFI_GetLanguage();
+  }
+}
+
+void CPDFXFA_App::GetPlatform(CFX_WideString& wsPlatform) {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv) {
+    wsPlatform = pEnv->FFI_GetPlatform();
+  }
+}
+
+void CPDFXFA_App::GetVariation(CFX_WideString& wsVariation) {
+  wsVariation = JS_STR_VIEWERVARIATION;
+}
+
+void CPDFXFA_App::GetVersion(CFX_WideString& wsVersion) {
+  wsVersion = JS_STR_VIEWERVERSION_XFA;
+}
+
+void CPDFXFA_App::Beep(FX_DWORD dwType) {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv) {
+    pEnv->JS_appBeep(dwType);
+  }
+}
+
+int32_t CPDFXFA_App::MsgBox(const CFX_WideStringC& wsMessage,
+                            const CFX_WideStringC& wsTitle,
+                            FX_DWORD dwIconType,
+                            FX_DWORD dwButtonType) {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (!pEnv)
+    return -1;
+
+  FX_DWORD iconType = 0;
+  int iButtonType = 0;
+  switch (dwIconType) {
+    case XFA_MBICON_Error:
+      iconType |= 0;
+      break;
+    case XFA_MBICON_Warning:
+      iconType |= 1;
+      break;
+    case XFA_MBICON_Question:
+      iconType |= 2;
+      break;
+    case XFA_MBICON_Status:
+      iconType |= 3;
+      break;
+  }
+  switch (dwButtonType) {
+    case XFA_MB_OK:
+      iButtonType |= 0;
+      break;
+    case XFA_MB_OKCancel:
+      iButtonType |= 1;
+      break;
+    case XFA_MB_YesNo:
+      iButtonType |= 2;
+      break;
+    case XFA_MB_YesNoCancel:
+      iButtonType |= 3;
+      break;
+  }
+  int32_t iRet = pEnv->JS_appAlert(wsMessage.GetPtr(), wsTitle.GetPtr(),
+                                   iButtonType, iconType);
+  switch (iRet) {
+    case 1:
+      return XFA_IDOK;
+    case 2:
+      return XFA_IDCancel;
+    case 3:
+      return XFA_IDNo;
+    case 4:
+      return XFA_IDYes;
+  }
+  return XFA_IDYes;
+}
+
+void CPDFXFA_App::Response(CFX_WideString& wsAnswer,
+                           const CFX_WideStringC& wsQuestion,
+                           const CFX_WideStringC& wsTitle,
+                           const CFX_WideStringC& wsDefaultAnswer,
+                           FX_BOOL bMark) {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv) {
+    int nLength = 2048;
+    char* pBuff = new char[nLength];
+    nLength = pEnv->JS_appResponse(wsQuestion.GetPtr(), wsTitle.GetPtr(),
+                                   wsDefaultAnswer.GetPtr(), NULL, bMark, pBuff,
+                                   nLength);
+    if (nLength > 0) {
+      nLength = nLength > 2046 ? 2046 : nLength;
+      pBuff[nLength] = 0;
+      pBuff[nLength + 1] = 0;
+      wsAnswer = CFX_WideString::FromUTF16LE(
+          reinterpret_cast<const unsigned short*>(pBuff),
+          nLength / sizeof(unsigned short));
+    }
+    delete[] pBuff;
+  }
+}
+
+int32_t CPDFXFA_App::GetCurDocumentInBatch() {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv) {
+    return pEnv->FFI_GetCurDocument();
+  }
+  return 0;
+}
+
+int32_t CPDFXFA_App::GetDocumentCountInBatch() {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv) {
+    return pEnv->FFI_GetDocumentCount();
+  }
+
+  return 0;
+}
+
+IFX_FileRead* CPDFXFA_App::DownloadURL(const CFX_WideStringC& wsURL) {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv) {
+    return pEnv->FFI_DownloadFromURL(wsURL.GetPtr());
+  }
+  return NULL;
+}
+
+FX_BOOL CPDFXFA_App::PostRequestURL(const CFX_WideStringC& wsURL,
+                                    const CFX_WideStringC& wsData,
+                                    const CFX_WideStringC& wsContentType,
+                                    const CFX_WideStringC& wsEncode,
+                                    const CFX_WideStringC& wsHeader,
+                                    CFX_WideString& wsResponse) {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv) {
+    wsResponse = pEnv->FFI_PostRequestURL(wsURL.GetPtr(), wsData.GetPtr(),
+                                          wsContentType.GetPtr(),
+                                          wsEncode.GetPtr(), wsHeader.GetPtr());
+    return TRUE;
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDFXFA_App::PutRequestURL(const CFX_WideStringC& wsURL,
+                                   const CFX_WideStringC& wsData,
+                                   const CFX_WideStringC& wsEncode) {
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv) {
+    return pEnv->FFI_PutRequestURL(wsURL.GetPtr(), wsData.GetPtr(),
+                                   wsEncode.GetPtr());
+  }
+  return FALSE;
+}
+
+void CPDFXFA_App::LoadString(int32_t iStringID, CFX_WideString& wsString) {
+  switch (iStringID) {
+    case XFA_IDS_ValidateFailed:
+      wsString = L"%s validate failed";
+      return;
+    case XFA_IDS_CalcOverride:
+      wsString = L"Calculate Override";
+      return;
+    case XFA_IDS_ModifyField:
+      wsString = L"Are you sure you want to modify this field?";
+      return;
+    case XFA_IDS_NotModifyField:
+      wsString = L"You are not allowed to modify this field.";
+      return;
+    case XFA_IDS_AppName:
+      wsString = L"Foxit";
+      return;
+    case XFA_IDS_ImageFilter:
+      wsString =
+          L"Image "
+          L"Files(*.bmp;*.jpg;*.png;*.gif;*.tif)|*.bmp;*.jpg;*.png;*.gif;*.tif|"
+          L"All Files(*.*)|*.*||";
+      return;
+    case XFA_IDS_UNKNOW_CATCHED:
+      wsString = L"unknown error is catched!";
+      return;
+    case XFA_IDS_Unable_TO_SET:
+      wsString = L"Unable to set ";
+      return;
+    case XFA_IDS_VALUE_EXCALMATORY:
+      wsString = L" value!";
+      return;
+    case XFA_IDS_INVALID_ENUM_VALUE:
+      wsString = L"Invalid enumerated value: ";
+      return;
+    case XFA_IDS_UNSUPPORT_METHOD:
+      wsString = L"unsupport %s method.";
+      return;
+    case XFA_IDS_UNSUPPORT_PROP:
+      wsString = L"unsupport %s property.";
+      return;
+    case XFA_IDS_INVAlID_PROP_SET:
+      wsString = L"Invalid property set operation;";
+      return;
+    case XFA_IDS_NOT_DEFAUL_VALUE:
+      wsString = L" doesn't have a default property";
+      return;
+    case XFA_IDS_UNABLE_SET_LANGUAGE:
+      wsString = L"Unable to set language value!";
+      return;
+    case XFA_IDS_UNABLE_SET_NUMPAGES:
+      wsString = L"Unable to set numPages value!";
+      return;
+    case XFA_IDS_UNABLE_SET_PLATFORM:
+      wsString = L"Unable to set platform value!";
+      return;
+    case XFA_IDS_UNABLE_SET_VALIDATIONENABLE:
+      wsString = L"Unable to set validationsEnabled value!";
+      return;
+    case XFA_IDS_UNABLE_SET_VARIATION:
+      wsString = L"Unable to set variation value!";
+      return;
+    case XFA_IDS_UNABLE_SET_VERSION:
+      wsString = L"Unable to set version value!";
+      return;
+    case XFA_IDS_UNABLE_SET_READY:
+      wsString = L"Unable to set ready value!";
+      return;
+    case XFA_IDS_NUMBER_OF_OCCUR:
+      wsString =
+          L"The element [%s] has violated its allowable number of occurrences";
+      return;
+    case XFA_IDS_UNABLE_SET_CLASS_NAME:
+      wsString = L"Unable to set className value!";
+      return;
+    case XFA_IDS_UNABLE_SET_LENGTH_VALUE:
+      wsString = L"Unable to set length value!";
+      return;
+    case XFA_IDS_UNSUPPORT_CHAR:
+      wsString = L"unsupported char '%c'";
+      return;
+    case XFA_IDS_BAD_SUFFIX:
+      wsString = L"bad suffix on number";
+      return;
+    case XFA_IDS_EXPECTED_IDENT:
+      wsString = L"expected identifier instead of '%s'";
+      return;
+    case XFA_IDS_EXPECTED_STRING:
+      wsString = L"expected '%s' instead of '%s'";
+      return;
+    case XFA_IDS_INVALIDATE_CHAR:
+      wsString = L"invalidate char '%c'";
+      return;
+    case XFA_IDS_REDEFINITION:
+      wsString = L"'%s' redefinition ";
+      return;
+    case XFA_IDS_INVALIDATE_TOKEN:
+      wsString = L"invalidate token '%s'";
+      return;
+    case XFA_IDS_INVALIDATE_EXPRESSION:
+      wsString = L"invalidate expression '%s'";
+      return;
+    case XFA_IDS_UNDEFINE_IDENTIFIER:
+      wsString = L"undefined identifier '%s'";
+      return;
+    case XFA_IDS_INVALIDATE_LEFTVALUE:
+      wsString = L"invalidate left-value '%s'";
+      return;
+    case XFA_IDS_COMPILER_ERROR:
+      wsString = L"compiler error";
+      return;
+    case XFA_IDS_CANNOT_MODIFY_VALUE:
+      wsString = L"can't modify the '%s' value";
+      return;
+    case XFA_IDS_ERROR_PARAMETERS:
+      wsString = L"function '%s' has not %d parameters";
+      return;
+    case XFA_IDS_EXPECT_ENDIF:
+      wsString = L"expected 'endif' instead of '%s'";
+      return;
+    case XFA_IDS_UNEXPECTED_EXPRESSION:
+      wsString = L"unexpected expression '%s'";
+      return;
+    case XFA_IDS_CONDITION_IS_NULL:
+      wsString = L"condition is null";
+      return;
+    case XFA_IDS_ILLEGALBREAK:
+      wsString = L"illegal break";
+      return;
+    case XFA_IDS_ILLEGALCONTINUE:
+      wsString = L"illegal continue";
+      return;
+    case XFA_IDS_EXPECTED_OPERATOR:
+      wsString = L"expected operator '%s' instead of '%s'";
+      return;
+    case XFA_IDS_DIVIDE_ZERO:
+      wsString = L"divide by zero";
+      return;
+    case XFA_IDS_CANNOT_COVERT_OBJECT:
+      wsString = L"%s.%s can not covert to object";
+      return;
+    case XFA_IDS_NOT_FOUND_CONTAINER:
+      wsString = L"can not found container '%s'";
+      return;
+    case XFA_IDS_NOT_FOUND_PROPERTY:
+      wsString = L"can not found property '%s'";
+      return;
+    case XFA_IDS_NOT_FOUND_METHOD:
+      wsString = L"can not found method '%s'";
+      return;
+    case XFA_IDS_NOT_FOUND_CONST:
+      wsString = L"can not found const '%s'";
+      return;
+    case XFA_IDS_NOT_ASSIGN_OBJECT:
+      wsString = L"can not direct assign value to object";
+      return;
+    case XFA_IDS_IVALIDATE_INSTRUCTION:
+      wsString = L"invalidate instruction";
+      return;
+    case XFA_IDS_EXPECT_NUMBER:
+      wsString = L"expected number instead of '%s'";
+      return;
+    case XFA_IDS_VALIDATE_OUT_ARRAY:
+      wsString = L"validate access index '%s' out of array";
+      return;
+    case XFA_IDS_CANNOT_ASSIGN_IDENT:
+      wsString = L"can not assign to %s";
+      return;
+    case XFA_IDS_NOT_FOUNT_FUNCTION:
+      wsString = L"can not found '%s' function";
+      return;
+    case XFA_IDS_NOT_ARRAY:
+      wsString = L"'%s' doesn't an array";
+      return;
+    case XFA_IDS_OUT_ARRAY:
+      wsString = L"out of range of '%s' array";
+      return;
+    case XFA_IDS_NOT_SUPPORT_CALC:
+      wsString = L"'%s' operator can not support array calculate";
+      return;
+    case XFA_IDS_ARGUMENT_NOT_ARRAY:
+      wsString = L"'%s' function's %d argument can not be array";
+      return;
+    case XFA_IDS_ARGUMENT_EXPECT_CONTAINER:
+      wsString = L"'%s' argument expected a container";
+      return;
+    case XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT:
+      wsString =
+          L"an attempt was made to reference property '%s' of a non-object in "
+          L"SOM expression %s";
+      return;
+    case XFA_IDS_FUNCTION_IS_BUILDIN:
+      wsString = L"function '%s' is buildin";
+      return;
+    case XFA_IDS_ERROR_MSG:
+      wsString = L"%s : %s";
+      return;
+    case XFA_IDS_INDEX_OUT_OF_BOUNDS:
+      wsString = L"Index value is out of bounds";
+      return;
+    case XFA_IDS_INCORRECT_NUMBER_OF_METHOD:
+      wsString = L"Incorrect number of parameters calling method '%s'";
+      return;
+    case XFA_IDS_ARGUMENT_MISMATCH:
+      wsString = L"Argument mismatch in property or function argument";
+      return;
+    case XFA_IDS_INVALID_ENUMERATE:
+      wsString = L"Invalid enumerated value: %s";
+      return;
+    case XFA_IDS_INVALID_APPEND:
+      wsString =
+          L"Invalid append operation: %s cannot have a child element of %s";
+      return;
+    case XFA_IDS_SOM_EXPECTED_LIST:
+      wsString =
+          L"SOM expression returned list when single result was expected";
+      return;
+    case XFA_IDS_NOT_HAVE_PROPERTY:
+      wsString = L"'%s' doesn't have property '%s'";
+      return;
+    case XFA_IDS_INVALID_NODE_TYPE:
+      wsString = L"Invalid node type : '%s'";
+      return;
+    case XFA_IDS_VIOLATE_BOUNDARY:
+      wsString =
+          L"The element [%s] has violated its allowable number of occurrences";
+      return;
+    case XFA_IDS_SERVER_DENY:
+      wsString = L"Server does not permit";
+      return;
+    case XFA_IDS_ValidateLimit:
+      wsString = FX_WSTRC(
+          L"Message limit exceeded. Remaining %d validation errors not "
+          L"reported.");
+      return;
+    case XFA_IDS_ValidateNullWarning:
+      wsString = FX_WSTRC(
+          L"%s cannot be left blank. To ignore validations for %s, click "
+          L"Ignore.");
+      return;
+    case XFA_IDS_ValidateNullError:
+      wsString = FX_WSTRC(L"%s cannot be left blank.");
+      return;
+    case XFA_IDS_ValidateWarning:
+      wsString = FX_WSTRC(
+          L"The value you entered for %s is invalid. To ignore validations for "
+          L"%s, click Ignore.");
+      return;
+    case XFA_IDS_ValidateError:
+      wsString = FX_WSTRC(L"The value you entered for %s is invalid.");
+      return;
+  }
+}
+
+FX_BOOL CPDFXFA_App::ShowFileDialog(const CFX_WideStringC& wsTitle,
+                                    const CFX_WideStringC& wsFilter,
+                                    CFX_WideStringArray& wsPathArr,
+                                    FX_BOOL bOpen) {
+  return FALSE;
+}
+
+IFWL_AdapterTimerMgr* CPDFXFA_App::GetTimerMgr() {
+  CXFA_FWLAdapterTimerMgr* pAdapter = NULL;
+  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+  if (pEnv)
+    pAdapter = new CXFA_FWLAdapterTimerMgr(pEnv);
+  return pAdapter;
+}
diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp
index 09c444e..254dc7d 100644
--- a/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp
+++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp
@@ -1,1265 +1,1265 @@
-// Copyright 2014 PDFium Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-

-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

-

-#include "fpdfsdk/include/fsdk_define.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"

-#include "fpdfsdk/include/fsdk_mgr.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"

-#include "fpdfsdk/include/javascript/IJavaScript.h"

-#include "public/fpdf_formfill.h"

-

-#define IDS_XFA_Validate_Input                                          \

-  "At least one required field was empty. Please fill in the required " \

-  "fields\r\n(highlighted) before continuing."

-

-// submit

-#define FXFA_CONFIG 0x00000001

-#define FXFA_TEMPLATE 0x00000010

-#define FXFA_LOCALESET 0x00000100

-#define FXFA_DATASETS 0x00001000

-#define FXFA_XMPMETA 0x00010000

-#define FXFA_XFDF 0x00100000

-#define FXFA_FORM 0x01000000

-#define FXFA_PDF 0x10000000

-

-#ifndef _WIN32

-extern void SetLastError(int err);

-

-extern int GetLastError();

-#endif

-

-CPDFXFA_Document::CPDFXFA_Document(CPDF_Document* pPDFDoc,

-                                   CPDFXFA_App* pProvider)

-    : m_iDocType(DOCTYPE_PDF),

-      m_pPDFDoc(pPDFDoc),

-      m_pSDKDoc(nullptr),

-      m_pXFADoc(nullptr),

-      m_pXFADocView(nullptr),

-      m_pApp(pProvider),

-      m_pJSContext(nullptr) {

-}

-

-CPDFXFA_Document::~CPDFXFA_Document() {

-  if (m_pJSContext && m_pSDKDoc && m_pSDKDoc->GetEnv())

-    m_pSDKDoc->GetEnv()->GetJSRuntime()->ReleaseContext(m_pJSContext);

-

-  delete m_pSDKDoc;

-

-  if (m_pPDFDoc) {

-    CPDF_Parser* pParser = m_pPDFDoc->GetParser();

-    if (pParser)

-      delete pParser;

-    else

-      delete m_pPDFDoc;

-  }

-  if (m_pXFADoc) {

-    IXFA_App* pApp = m_pApp->GetXFAApp();

-    if (pApp) {

-      IXFA_DocHandler* pDocHandler = pApp->GetDocHandler();

-      if (pDocHandler) {

-        CloseXFADoc(pDocHandler);

-      }

-    }

-    delete m_pXFADoc;

-  }

-}

-

-FX_BOOL CPDFXFA_Document::LoadXFADoc() {

-  if (!m_pPDFDoc)

-    return FALSE;

-

-  m_XFAPageList.RemoveAll();

-

-  IXFA_App* pApp = m_pApp->GetXFAApp();

-  if (!pApp)

-    return FALSE;

-

-  m_pXFADoc = pApp->CreateDoc(this, m_pPDFDoc);

-  if (!m_pXFADoc) {

-    SetLastError(FPDF_ERR_XFALOAD);

-    return FALSE;

-  }

-

-  IXFA_DocHandler* pDocHandler = pApp->GetDocHandler();

-  if (!pDocHandler) {

-    SetLastError(FPDF_ERR_XFALOAD);

-    return FALSE;

-  }

-

-  pDocHandler->StartLoad(m_pXFADoc);

-  int iStatus = pDocHandler->DoLoad(m_pXFADoc, NULL);

-  if (iStatus != XFA_PARSESTATUS_Done) {

-    CloseXFADoc(pDocHandler);

-    SetLastError(FPDF_ERR_XFALOAD);

-    return FALSE;

-  }

-  pDocHandler->StopLoad(m_pXFADoc);

-  pDocHandler->SetJSERuntime(m_pXFADoc, m_pApp->GetJSERuntime());

-

-  if (pDocHandler->GetDocType(m_pXFADoc) == XFA_DOCTYPE_Dynamic)

-    m_iDocType = DOCTYPE_DYNAMIC_XFA;

-  else

-    m_iDocType = DOCTYPE_STATIC_XFA;

-

-  m_pXFADocView = pDocHandler->CreateDocView(m_pXFADoc, XFA_DOCVIEW_View);

-  if (m_pXFADocView->StartLayout() < 0) {

-    CloseXFADoc(pDocHandler);

-    SetLastError(FPDF_ERR_XFALAYOUT);

-    return FALSE;

-  }

-

-  m_pXFADocView->DoLayout(NULL);

-  m_pXFADocView->StopLayout();

-  return TRUE;

-}

-

-int CPDFXFA_Document::GetPageCount() {

-  if (!m_pPDFDoc && !m_pXFADoc)

-    return 0;

-

-  switch (m_iDocType) {

-    case DOCTYPE_PDF:

-    case DOCTYPE_STATIC_XFA:

-      if (m_pPDFDoc)

-        return m_pPDFDoc->GetPageCount();

-    case DOCTYPE_DYNAMIC_XFA:

-      if (m_pXFADoc)

-        return m_pXFADocView->CountPageViews();

-    default:

-      return 0;

-  }

-

-  return 0;

-}

-

-CPDFXFA_Page* CPDFXFA_Document::GetPage(int page_index) {

-  if (page_index < 0)

-    return nullptr;

-  CPDFXFA_Page* pPage = nullptr;

-  int nCount = m_XFAPageList.GetSize();

-  if (nCount > 0 && page_index < nCount) {

-    pPage = m_XFAPageList.GetAt(page_index);

-    if (pPage)

-      pPage->AddRef();

-  } else {

-    m_XFAPageList.SetSize(GetPageCount());

-  }

-  if (pPage)

-    return pPage;

-  pPage = new CPDFXFA_Page(this, page_index);

-  if (!pPage->LoadPage()) {

-    delete pPage;

-    return nullptr;

-  }

-  m_XFAPageList.SetAt(page_index, pPage);

-  return pPage;

-}

-

-CPDFXFA_Page* CPDFXFA_Document::GetPage(IXFA_PageView* pPage) {

-  if (!pPage)

-    return NULL;

-

-  if (!m_pXFADoc)

-    return NULL;

-

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return NULL;

-

-  int nSize = m_XFAPageList.GetSize();

-  for (int i = 0; i < nSize; i++) {

-    CPDFXFA_Page* pTempPage = m_XFAPageList.GetAt(i);

-    if (!pTempPage)

-      continue;

-    if (pTempPage->GetXFAPageView() && pTempPage->GetXFAPageView() == pPage)

-      return pTempPage;

-  }

-

-  return NULL;

-}

-

-void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) {

-  m_XFAPageList.SetAt(page->GetPageIndex(), NULL);

-}

-

-CPDFSDK_Document* CPDFXFA_Document::GetSDKDocument(

-    CPDFDoc_Environment* pFormFillEnv) {

-  if (!m_pSDKDoc && pFormFillEnv)

-    m_pSDKDoc = new CPDFSDK_Document(this, pFormFillEnv);

-  return m_pSDKDoc;

-}

-

-void CPDFXFA_Document::FXRect2PDFRect(const CFX_RectF& fxRectF,

-                                      CPDF_Rect& pdfRect) {

-  pdfRect.left = fxRectF.left;

-  pdfRect.top = fxRectF.bottom();

-  pdfRect.right = fxRectF.right();

-  pdfRect.bottom = fxRectF.top;

-}

-

-void CPDFXFA_Document::SetChangeMark(IXFA_Doc* hDoc) {

-  if (hDoc == m_pXFADoc && m_pSDKDoc) {

-    m_pSDKDoc->SetChangeMark();

-  }

-}

-

-FX_BOOL CPDFXFA_Document::GetChangeMark(IXFA_Doc* hDoc) {

-  if (hDoc == m_pXFADoc && m_pSDKDoc)

-    return m_pSDKDoc->GetChangeMark();

-  return FALSE;

-}

-

-void CPDFXFA_Document::InvalidateRect(IXFA_PageView* pPageView,

-                                      const CFX_RectF& rt,

-                                      FX_DWORD dwFlags /* = 0 */) {

-  if (!m_pXFADoc || !m_pSDKDoc)

-    return;

-

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return;

-

-  CPDF_Rect rcPage;

-  FXRect2PDFRect(rt, rcPage);

-

-  CPDFXFA_Page* pPage = GetPage(pPageView);

-

-  if (pPage == NULL)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (!pEnv)

-    return;

-

-  pEnv->FFI_Invalidate((FPDF_PAGE)pPage, rcPage.left, rcPage.bottom,

-                       rcPage.right, rcPage.top);

-}

-

-void CPDFXFA_Document::InvalidateRect(IXFA_Widget* hWidget,

-                                      FX_DWORD dwFlags /* = 0 */) {

-  if (!hWidget)

-    return;

-

-  if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView)

-    return;

-

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return;

-

-  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();

-  if (!pWidgetHandler)

-    return;

-

-  IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget);

-  if (!pPageView)

-    return;

-

-  CFX_RectF rect;

-  pWidgetHandler->GetRect(hWidget, rect);

-  InvalidateRect(pPageView, rect, dwFlags);

-}

-

-void CPDFXFA_Document::DisplayCaret(IXFA_Widget* hWidget,

-                                    FX_BOOL bVisible,

-                                    const CFX_RectF* pRtAnchor) {

-  if (!hWidget || pRtAnchor == NULL)

-    return;

-

-  if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView)

-    return;

-

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return;

-

-  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();

-  if (!pWidgetHandler)

-    return;

-

-  IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget);

-  if (!pPageView)

-    return;

-

-  CPDFXFA_Page* pPage = GetPage(pPageView);

-

-  if (pPage == NULL)

-    return;

-

-  CPDF_Rect rcCaret;

-  FXRect2PDFRect(*pRtAnchor, rcCaret);

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (!pEnv)

-    return;

-

-  pEnv->FFI_DisplayCaret((FPDF_PAGE)pPage, bVisible, rcCaret.left, rcCaret.top,

-                         rcCaret.right, rcCaret.bottom);

-}

-

-FX_BOOL CPDFXFA_Document::GetPopupPos(IXFA_Widget* hWidget,

-                                      FX_FLOAT fMinPopup,

-                                      FX_FLOAT fMaxPopup,

-                                      const CFX_RectF& rtAnchor,

-                                      CFX_RectF& rtPopup) {

-  if (NULL == hWidget) {

-    return FALSE;

-  }

-  IXFA_PageView* pXFAPageView =

-      m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);

-  if (NULL == pXFAPageView) {

-    return FALSE;

-  }

-  CPDFXFA_Page* pPage = GetPage(pXFAPageView);

-  if (pPage == NULL)

-    return FALSE;

-

-  CXFA_WidgetAcc* pWidgetAcc =

-      m_pXFADocView->GetWidgetHandler()->GetDataAcc(hWidget);

-

-  int nRotate = 0;

-#ifdef PDF_ENABLE_XFA

-  nRotate = pWidgetAcc->GetRotate();

-#endif

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return FALSE;

-  FS_RECTF pageViewRect;

-  pEnv->FFI_GetPageViewRect(pPage, pageViewRect);

-

-  CPDF_Rect rcAnchor;

-

-  rcAnchor.left = rtAnchor.left;

-  rcAnchor.top = rtAnchor.bottom();

-  rcAnchor.right = rtAnchor.right();

-  rcAnchor.bottom = rtAnchor.top;

-

-  int t1, t2, t;

-  FX_DWORD dwPos;

-  FX_FLOAT fPoupHeight;

-  switch (nRotate) {

-    case 90: {

-      t1 = (int)(pageViewRect.right - rcAnchor.right);

-      t2 = (int)(rcAnchor.left - pageViewRect.left);

-      if (rcAnchor.bottom < pageViewRect.bottom) {

-        rtPopup.left += rcAnchor.bottom - pageViewRect.bottom;

-      }

-

-      break;

-    }

-

-    case 180: {

-      t2 = (int)(pageViewRect.top - rcAnchor.top);

-      t1 = (int)(rcAnchor.bottom - pageViewRect.bottom);

-      if (rcAnchor.left < pageViewRect.left) {

-        rtPopup.left += rcAnchor.left - pageViewRect.left;

-      }

-      break;

-    }

-    case 270: {

-      t1 = (int)(rcAnchor.left - pageViewRect.left);

-      t2 = (int)(pageViewRect.right - rcAnchor.right);

-

-      if (rcAnchor.top > pageViewRect.top) {

-        rtPopup.left -= rcAnchor.top - pageViewRect.top;

-      }

-      break;

-    }

-    case 0:

-    default: {

-      t1 = (int)(pageViewRect.top - rcAnchor.top);

-      t2 = (int)(rcAnchor.bottom - pageViewRect.bottom);

-      if (rcAnchor.right > pageViewRect.right) {

-        rtPopup.left -= rcAnchor.right - pageViewRect.right;

-      }

-      break;

-    }

-  }

-

-  if (t1 <= 0 && t2 <= 0) {

-    return FALSE;

-  }

-  if (t1 <= 0) {

-    t = t2;

-    dwPos = 1;

-  } else if (t2 <= 0) {

-    t = t1;

-    dwPos = 0;

-  } else if (t1 > t2) {

-    t = t1;

-    dwPos = 0;

-  } else {

-    t = t2;

-    dwPos = 1;

-  }

-  if (t < fMinPopup) {

-    fPoupHeight = fMinPopup;

-  } else if (t > fMaxPopup) {

-    fPoupHeight = fMaxPopup;

-  } else {

-    fPoupHeight = (FX_FLOAT)t;

-  }

-

-  switch (nRotate) {

-    case 0:

-    case 180: {

-      if (dwPos == 0) {

-        rtPopup.top = rtAnchor.height;

-        rtPopup.height = fPoupHeight;

-      } else {

-        rtPopup.top = -fPoupHeight;

-        rtPopup.height = fPoupHeight;

-      }

-      break;

-    }

-    case 90:

-    case 270: {

-      if (dwPos == 0) {

-        rtPopup.top = rtAnchor.width;

-        rtPopup.height = fPoupHeight;

-      } else {

-        rtPopup.top = -fPoupHeight;

-        rtPopup.height = fPoupHeight;

-      }

-      break;

-    }

-    default:

-      break;

-  }

-

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_Document::PopupMenu(IXFA_Widget* hWidget,

-                                    CFX_PointF ptPopup,

-                                    const CFX_RectF* pRectExclude) {

-  if (NULL == hWidget) {

-    return FALSE;

-  }

-  IXFA_PageView* pXFAPageView =

-      m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);

-  if (pXFAPageView == NULL)

-    return FALSE;

-  CPDFXFA_Page* pPage = GetPage(pXFAPageView);

-

-  if (pPage == NULL)

-    return FALSE;

-

-  int menuFlag = 0;

-

-  IXFA_MenuHandler* pXFAMenuHander = m_pApp->GetXFAApp()->GetMenuHandler();

-  if (pXFAMenuHander->CanUndo(hWidget))

-    menuFlag |= FXFA_MEMU_UNDO;

-  if (pXFAMenuHander->CanRedo(hWidget))

-    menuFlag |= FXFA_MEMU_REDO;

-  if (pXFAMenuHander->CanPaste(hWidget))

-    menuFlag |= FXFA_MEMU_PASTE;

-  if (pXFAMenuHander->CanCopy(hWidget))

-    menuFlag |= FXFA_MEMU_COPY;

-  if (pXFAMenuHander->CanCut(hWidget))

-    menuFlag |= FXFA_MEMU_CUT;

-  if (pXFAMenuHander->CanSelectAll(hWidget))

-    menuFlag |= FXFA_MEMU_SELECTALL;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return FALSE;

-

-  return pEnv->FFI_PopupMenu(pPage, hWidget, menuFlag, ptPopup, NULL);

-}

-

-void CPDFXFA_Document::PageViewEvent(IXFA_PageView* pPageView,

-                                     FX_DWORD dwFlags) {

-  if (!pPageView || (dwFlags != XFA_PAGEVIEWEVENT_PostAdded &&

-                     dwFlags != XFA_PAGEVIEWEVENT_PostRemoved)) {

-    return;

-  }

-  CPDFXFA_Page* pPage = nullptr;

-  if (dwFlags == XFA_PAGEVIEWEVENT_PostAdded) {

-    pPage = GetPage(pPageView->GetPageViewIndex());

-    if (pPage)

-      pPage->SetXFAPageView(pPageView);

-    return;

-  }

-  pPage = GetPage(pPageView);

-  if (!pPage)

-    return;

-  pPage->SetXFAPageView(nullptr);

-  m_pSDKDoc->GetPageView(pPage)->ClearFXAnnots();

-}

-

-void CPDFXFA_Document::WidgetEvent(IXFA_Widget* hWidget,

-                                   CXFA_WidgetAcc* pWidgetData,

-                                   FX_DWORD dwEvent,

-                                   void* pParam,

-                                   void* pAdditional) {

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA || !hWidget)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (!pEnv)

-    return;

-

-  IXFA_PageView* pPageView =

-      m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);

-  if (pPageView == NULL)

-    return;

-

-  CPDFXFA_Page* pXFAPage = GetPage(pPageView);

-  if (pXFAPage == NULL)

-    return;

-

-  CPDFSDK_PageView* pSdkPageView = m_pSDKDoc->GetPageView(pXFAPage);

-  if (dwEvent == XFA_WIDGETEVENT_PostAdded) {

-    pSdkPageView->AddAnnot(hWidget);

-

-  } else if (dwEvent == XFA_WIDGETEVENT_PreRemoved) {

-    CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget);

-    if (pAnnot) {

-      pSdkPageView->DeleteAnnot(pAnnot);

-    }

-  }

-}

-

-int32_t CPDFXFA_Document::CountPages(IXFA_Doc* hDoc) {

-  if (hDoc == m_pXFADoc && m_pSDKDoc) {

-    return GetPageCount();

-  }

-  return 0;

-}

-int32_t CPDFXFA_Document::GetCurrentPage(IXFA_Doc* hDoc) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return -1;

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return -1;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return -1;

-

-  return pEnv->FFI_GetCurrentPageIndex(this);

-}

-void CPDFXFA_Document::SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return;

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-

-  pEnv->FFI_SetCurrentPage(this, iCurPage);

-}

-FX_BOOL CPDFXFA_Document::IsCalculationsEnabled(IXFA_Doc* hDoc) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return FALSE;

-  if (m_pSDKDoc->GetInterForm())

-    return m_pSDKDoc->GetInterForm()->IsXfaCalculateEnabled();

-

-  return FALSE;

-}

-void CPDFXFA_Document::SetCalculationsEnabled(IXFA_Doc* hDoc,

-                                              FX_BOOL bEnabled) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return;

-  if (m_pSDKDoc->GetInterForm())

-    m_pSDKDoc->GetInterForm()->XfaEnableCalculate(bEnabled);

-}

-

-void CPDFXFA_Document::GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle) {

-  if (hDoc != m_pXFADoc)

-    return;

-  if (m_pPDFDoc == NULL)

-    return;

-  CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo();

-

-  if (pInfoDict == NULL)

-    return;

-

-  CFX_ByteString csTitle = pInfoDict->GetString("Title");

-  wsTitle = wsTitle.FromLocal(csTitle.GetBuffer(csTitle.GetLength()));

-  csTitle.ReleaseBuffer(csTitle.GetLength());

-}

-void CPDFXFA_Document::SetTitle(IXFA_Doc* hDoc,

-                                const CFX_WideStringC& wsTitle) {

-  if (hDoc != m_pXFADoc)

-    return;

-  if (m_pPDFDoc == NULL)

-    return;

-  CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo();

-

-  if (pInfoDict == NULL)

-    return;

-  pInfoDict->SetAt("Title", new CPDF_String(wsTitle));

-}

-void CPDFXFA_Document::ExportData(IXFA_Doc* hDoc,

-                                  const CFX_WideStringC& wsFilePath,

-                                  FX_BOOL bXDP) {

-  if (hDoc != m_pXFADoc)

-    return;

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)

-    return;

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-  int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML;

-  CFX_ByteString bs = CFX_WideString(wsFilePath).UTF16LE_Encode();

-

-  if (wsFilePath.IsEmpty()) {

-    if (!pEnv->GetFormFillInfo() ||

-        pEnv->GetFormFillInfo()->m_pJsPlatform == NULL)

-      return;

-    CFX_WideString filepath = pEnv->JS_fieldBrowse();

-    bs = filepath.UTF16LE_Encode();

-  }

-  int len = bs.GetLength() / sizeof(unsigned short);

-  FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile(

-      bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML,

-      (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "wb");

-  bs.ReleaseBuffer(len * sizeof(unsigned short));

-

-  if (pFileHandler == NULL)

-    return;

-

-  CFPDF_FileStream fileWrite(pFileHandler);

-

-  IXFA_DocHandler* pXFADocHander = m_pApp->GetXFAApp()->GetDocHandler();

-  CFX_ByteString content;

-  if (fileType == FXFA_SAVEAS_XML) {

-    content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";

-    fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(),

-                         content.GetLength());

-    CFX_WideStringC data(L"data");

-    if (pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), data, &fileWrite)) {

-      // TODO: Maybe report error.

-    }

-  } else if (fileType == FXFA_SAVEAS_XDP) {

-    if (m_pPDFDoc == NULL)

-      return;

-    CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();

-    if (pRoot == NULL)

-      return;

-    CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");

-    if (NULL == pAcroForm)

-      return;

-    CPDF_Object* pXFA = pAcroForm->GetElement("XFA");

-    if (pXFA == NULL)

-      return;

-    if (!pXFA->IsArray())

-      return;

-    CPDF_Array* pArray = pXFA->GetArray();

-    if (NULL == pArray)

-      return;

-    int size = pArray->GetCount();

-    for (int i = 1; i < size; i += 2) {

-      CPDF_Object* pPDFObj = pArray->GetElement(i);

-      CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1);

-      if (!pPrePDFObj->IsString())

-        continue;

-      if (!pPDFObj->IsReference())

-        continue;

-      CPDF_Object* pDirectObj = pPDFObj->GetDirect();

-      if (!pDirectObj->IsStream())

-        continue;

-      if (pPrePDFObj->GetString() == "form") {

-        CFX_WideStringC form(L"form");

-        pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), form, &fileWrite);

-      } else if (pPrePDFObj->GetString() == "datasets") {

-        CFX_WideStringC datasets(L"datasets");

-        pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), datasets,

-                                   &fileWrite);

-      } else {

-        if (i == size - 1) {

-          CFX_WideString wPath = CFX_WideString::FromUTF16LE(

-              (unsigned short*)(const FX_CHAR*)bs,

-              bs.GetLength() / sizeof(unsigned short));

-          CFX_ByteString bPath = wPath.UTF8Encode();

-          CFX_ByteString szFormat =

-              "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";

-          content.Format(szFormat, (char*)(const FX_CHAR*)bPath);

-          fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(),

-                               content.GetLength());

-        }

-

-        CPDF_Stream* pStream = (CPDF_Stream*)pDirectObj;

-        CPDF_StreamAcc* pAcc = new CPDF_StreamAcc;

-        pAcc->LoadAllData(pStream);

-        fileWrite.WriteBlock(pAcc->GetData(), fileWrite.GetSize(),

-                             pAcc->GetSize());

-        delete pAcc;

-      }

-    }

-  }

-  if (!fileWrite.Flush()) {

-    // TODO: Report error.

-  }

-}

-void CPDFXFA_Document::ImportData(IXFA_Doc* hDoc,

-                                  const CFX_WideStringC& wsFilePath) {

-  // TODO...

-}

-

-void CPDFXFA_Document::GotoURL(IXFA_Doc* hDoc,

-                               const CFX_WideStringC& bsURL,

-                               FX_BOOL bAppend) {

-  if (hDoc != m_pXFADoc)

-    return;

-

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-

-  CFX_WideStringC str(bsURL.GetPtr());

-

-  pEnv->FFI_GotoURL(this, str, bAppend);

-}

-

-FX_BOOL CPDFXFA_Document::IsValidationsEnabled(IXFA_Doc* hDoc) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return FALSE;

-  if (m_pSDKDoc->GetInterForm())

-    return m_pSDKDoc->GetInterForm()->IsXfaValidationsEnabled();

-

-  return TRUE;

-}

-void CPDFXFA_Document::SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return;

-  if (m_pSDKDoc->GetInterForm())

-    m_pSDKDoc->GetInterForm()->XfaSetValidationsEnabled(bEnabled);

-}

-void CPDFXFA_Document::SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget) {

-  if (hDoc != m_pXFADoc)

-    return;

-

-  if (NULL == hWidget) {

-    m_pSDKDoc->SetFocusAnnot(NULL);

-    return;

-  }

-

-  int pageViewCount = m_pSDKDoc->GetPageViewCount();

-  for (int i = 0; i < pageViewCount; i++) {

-    CPDFSDK_PageView* pPageView = m_pSDKDoc->GetPageView(i);

-    if (pPageView == NULL)

-      continue;

-    CPDFSDK_Annot* pAnnot = pPageView->GetAnnotByXFAWidget(hWidget);

-    if (pAnnot) {

-      m_pSDKDoc->SetFocusAnnot(pAnnot);

-      break;

-    }

-  }

-}

-void CPDFXFA_Document::Print(IXFA_Doc* hDoc,

-                             int32_t nStartPage,

-                             int32_t nEndPage,

-                             FX_DWORD dwOptions) {

-  if (hDoc != m_pXFADoc)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-

-  if (!pEnv->GetFormFillInfo() ||

-      pEnv->GetFormFillInfo()->m_pJsPlatform == NULL)

-    return;

-  if (pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print == NULL)

-    return;

-  pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print(

-      pEnv->GetFormFillInfo()->m_pJsPlatform,

-      dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage,

-      dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage,

-      dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder,

-      dwOptions & XFA_PRINTOPT_PrintAnnot);

-}

-

-void CPDFXFA_Document::GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL) {

-  if (hDoc != m_pXFADoc)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-

-  pEnv->FFI_GetURL(this, wsDocURL);

-}

-

-FX_ARGB CPDFXFA_Document::GetHighlightColor(IXFA_Doc* hDoc) {

-  if (hDoc != m_pXFADoc)

-    return 0;

-  if (m_pSDKDoc) {

-    if (CPDFSDK_InterForm* pInterForm = m_pSDKDoc->GetInterForm()) {

-      FX_COLORREF color = pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA);

-      uint8_t alpha = pInterForm->GetHighlightAlpha();

-      FX_ARGB argb = ArgbEncode((int)alpha, color);

-      return argb;

-    }

-  }

-  return 0;

-}

-

-FX_BOOL CPDFXFA_Document::_NotifySubmit(FX_BOOL bPrevOrPost) {

-  if (bPrevOrPost)

-    return _OnBeforeNotifySumbit();

-

-  _OnAfterNotifySumbit();

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_Document::_OnBeforeNotifySumbit() {

-#ifdef PDF_ENABLE_XFA

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)

-    return TRUE;

-  if (m_pXFADocView == NULL)

-    return TRUE;

-  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();

-  if (pWidgetHandler == NULL)

-    return TRUE;

-  IXFA_WidgetAccIterator* pWidgetAccIterator =

-      m_pXFADocView->CreateWidgetAccIterator();

-  if (pWidgetAccIterator) {

-    CXFA_EventParam Param;

-    Param.m_eType = XFA_EVENT_PreSubmit;

-    CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();

-    while (pWidgetAcc) {

-      pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);

-      pWidgetAcc = pWidgetAccIterator->MoveToNext();

-    }

-    pWidgetAccIterator->Release();

-  }

-  pWidgetAccIterator = m_pXFADocView->CreateWidgetAccIterator();

-  if (pWidgetAccIterator) {

-    CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();

-    pWidgetAcc = pWidgetAccIterator->MoveToNext();

-    while (pWidgetAcc) {

-      int fRet = pWidgetAcc->ProcessValidate(-1);

-      if (fRet == XFA_EVENTERROR_Error) {

-        CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-        if (pEnv == NULL)

-          return FALSE;

-        CFX_WideString ws;

-        ws.FromLocal(IDS_XFA_Validate_Input);

-        CFX_ByteString bs = ws.UTF16LE_Encode();

-        int len = bs.GetLength() / sizeof(unsigned short);

-        pEnv->FFI_Alert(

-            (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)),

-            (FPDF_WIDESTRING)L"", 0, 1);

-        bs.ReleaseBuffer(len * sizeof(unsigned short));

-        pWidgetAccIterator->Release();

-        return FALSE;

-      }

-      pWidgetAcc = pWidgetAccIterator->MoveToNext();

-    }

-    pWidgetAccIterator->Release();

-    m_pXFADocView->UpdateDocView();

-  }

-#endif

-  return TRUE;

-}

-void CPDFXFA_Document::_OnAfterNotifySumbit() {

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)

-    return;

-  if (m_pXFADocView == NULL)

-    return;

-  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();

-  if (pWidgetHandler == NULL)

-    return;

-  IXFA_WidgetAccIterator* pWidgetAccIterator =

-      m_pXFADocView->CreateWidgetAccIterator();

-  if (pWidgetAccIterator == NULL)

-    return;

-  CXFA_EventParam Param;

-  Param.m_eType = XFA_EVENT_PostSubmit;

-

-  CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();

-  while (pWidgetAcc) {

-    pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);

-    pWidgetAcc = pWidgetAccIterator->MoveToNext();

-  }

-  pWidgetAccIterator->Release();

-  m_pXFADocView->UpdateDocView();

-}

-

-FX_BOOL CPDFXFA_Document::SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) {

-  if (!_NotifySubmit(TRUE))

-    return FALSE;

-  if (NULL == m_pXFADocView)

-    return FALSE;

-  m_pXFADocView->UpdateDocView();

-

-  FX_BOOL ret = _SubmitData(hDoc, submit);

-  _NotifySubmit(FALSE);

-  return ret;

-}

-

-IFX_FileRead* CPDFXFA_Document::OpenLinkedFile(IXFA_Doc* hDoc,

-                                               const CFX_WideString& wsLink) {

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return FALSE;

-  CFX_ByteString bs = wsLink.UTF16LE_Encode();

-  int len = bs.GetLength() / sizeof(unsigned short);

-  FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile(

-      0, (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "rb");

-  bs.ReleaseBuffer(len * sizeof(unsigned short));

-

-  if (pFileHandler == NULL)

-    return NULL;

-  return new CFPDF_FileStream(pFileHandler);

-}

-FX_BOOL CPDFXFA_Document::_ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler,

-                                            int fileType,

-                                            FPDF_DWORD encodeType,

-                                            FPDF_DWORD flag) {

-  if (NULL == m_pXFADocView)

-    return FALSE;

-  IXFA_DocHandler* pDocHandler = m_pApp->GetXFAApp()->GetDocHandler();

-  CFX_ByteString content;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return FALSE;

-

-  CFPDF_FileStream fileStream(pFileHandler);

-

-  if (fileType == FXFA_SAVEAS_XML) {

-    CFX_WideString ws;

-    ws.FromLocal("data");

-    CFX_ByteString content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";

-    fileStream.WriteBlock((const FX_CHAR*)content, 0, content.GetLength());

-    pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);

-  } else if (fileType == FXFA_SAVEAS_XDP) {

-    if (flag == 0)

-      flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |

-             FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;

-    if (m_pPDFDoc == NULL) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();

-    if (pRoot == NULL) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");

-    if (NULL == pAcroForm) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    CPDF_Object* pXFA = pAcroForm->GetElement("XFA");

-    if (pXFA == NULL) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    if (!pXFA->IsArray()) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    CPDF_Array* pArray = pXFA->GetArray();

-    if (NULL == pArray) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    int size = pArray->GetCount();

-    for (int i = 1; i < size; i += 2) {

-      CPDF_Object* pPDFObj = pArray->GetElement(i);

-      CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1);

-      if (!pPrePDFObj->IsString())

-        continue;

-      if (!pPDFObj->IsReference())

-        continue;

-      CPDF_Object* pDirectObj = pPDFObj->GetDirect();

-      if (!pDirectObj->IsStream())

-        continue;

-      if (pPrePDFObj->GetString() == "config" && !(flag & FXFA_CONFIG))

-        continue;

-      if (pPrePDFObj->GetString() == "template" && !(flag & FXFA_TEMPLATE))

-        continue;

-      if (pPrePDFObj->GetString() == "localeSet" && !(flag & FXFA_LOCALESET))

-        continue;

-      if (pPrePDFObj->GetString() == "datasets" && !(flag & FXFA_DATASETS))

-        continue;

-      if (pPrePDFObj->GetString() == "xmpmeta" && !(flag & FXFA_XMPMETA))

-        continue;

-      if (pPrePDFObj->GetString() == "xfdf" && !(flag & FXFA_XFDF))

-        continue;

-      if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM))

-        continue;

-      if (pPrePDFObj->GetString() == "form") {

-        CFX_WideString ws;

-        ws.FromLocal("form");

-        pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);

-      } else if (pPrePDFObj->GetString() == "datasets") {

-        CFX_WideString ws;

-        ws.FromLocal("datasets");

-        pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);

-      } else {

-        // PDF,creator.

-        // TODO:

-      }

-    }

-  }

-  return TRUE;

-}

-

-void CPDFXFA_Document::_ClearChangeMark() {

-  if (m_pSDKDoc)

-    m_pSDKDoc->ClearChangeMark();

-}

-

-void CPDFXFA_Document::_ToXFAContentFlags(CFX_WideString csSrcContent,

-                                          FPDF_DWORD& flag) {

-  if (csSrcContent.Find(L" config ", 0) != -1)

-    flag |= FXFA_CONFIG;

-  if (csSrcContent.Find(L" template ", 0) != -1)

-    flag |= FXFA_TEMPLATE;

-  if (csSrcContent.Find(L" localeSet ", 0) != -1)

-    flag |= FXFA_LOCALESET;

-  if (csSrcContent.Find(L" datasets ", 0) != -1)

-    flag |= FXFA_DATASETS;

-  if (csSrcContent.Find(L" xmpmeta ", 0) != -1)

-    flag |= FXFA_XMPMETA;

-  if (csSrcContent.Find(L" xfdf ", 0) != -1)

-    flag |= FXFA_XFDF;

-  if (csSrcContent.Find(L" form ", 0) != -1)

-    flag |= FXFA_FORM;

-  if (flag == 0)

-    flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |

-           FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;

-}

-FX_BOOL CPDFXFA_Document::_MailToInfo(CFX_WideString& csURL,

-                                      CFX_WideString& csToAddress,

-                                      CFX_WideString& csCCAddress,

-                                      CFX_WideString& csBCCAddress,

-                                      CFX_WideString& csSubject,

-                                      CFX_WideString& csMsg) {

-  CFX_WideString srcURL = csURL;

-  srcURL.TrimLeft();

-  if (0 != srcURL.Left(7).CompareNoCase(L"mailto:"))

-    return FALSE;

-  int pos = srcURL.Find(L'?', 0);

-  CFX_WideString tmp;

-  if (pos == -1) {

-    pos = srcURL.Find(L'@', 0);

-    if (pos == -1)

-      return FALSE;

-    else {

-      tmp = srcURL.Right(csURL.GetLength() - 7);

-      tmp.TrimLeft();

-      tmp.TrimRight();

-    }

-  } else {

-    tmp = srcURL.Left(pos);

-    tmp = tmp.Right(tmp.GetLength() - 7);

-    tmp.TrimLeft();

-    tmp.TrimRight();

-  }

-

-  csToAddress = tmp;

-

-  srcURL = srcURL.Right(srcURL.GetLength() - (pos + 1));

-  while (!srcURL.IsEmpty()) {

-    srcURL.TrimLeft();

-    srcURL.TrimRight();

-    pos = srcURL.Find(L'&', 0);

-    if (pos == -1)

-      tmp = srcURL;

-    else

-      tmp = srcURL.Left(pos);

-

-    tmp.TrimLeft();

-    tmp.TrimRight();

-    if (tmp.GetLength() >= 3 && 0 == tmp.Left(3).CompareNoCase(L"cc=")) {

-      tmp = tmp.Right(tmp.GetLength() - 3);

-      if (!csCCAddress.IsEmpty())

-        csCCAddress += L';';

-      csCCAddress += tmp;

-

-    } else if (tmp.GetLength() >= 4 &&

-               0 == tmp.Left(4).CompareNoCase(L"bcc=")) {

-      tmp = tmp.Right(tmp.GetLength() - 4);

-      if (!csBCCAddress.IsEmpty())

-        csBCCAddress += L';';

-      csBCCAddress += tmp;

-    } else if (tmp.GetLength() >= 8 &&

-               0 == tmp.Left(8).CompareNoCase(L"subject=")) {

-      tmp = tmp.Right(tmp.GetLength() - 8);

-      csSubject += tmp;

-    } else if (tmp.GetLength() >= 5 &&

-               0 == tmp.Left(5).CompareNoCase(L"body=")) {

-      tmp = tmp.Right(tmp.GetLength() - 5);

-      csMsg += tmp;

-    }

-    if (pos == -1)

-      srcURL = L"";

-    else

-      srcURL = srcURL.Right(csURL.GetLength() - (pos + 1));

-  }

-  csToAddress.Replace(L",", L";");

-  csCCAddress.Replace(L",", L";");

-  csBCCAddress.Replace(L",", L";");

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_Document::_SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) {

-#ifdef PDF_ENABLE_XFA

-  CFX_WideStringC csURLC;

-  submit.GetSubmitTarget(csURLC);

-  CFX_WideString csURL = csURLC;

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return FALSE;

-  if (csURL.IsEmpty()) {

-    CFX_WideString ws;

-    ws.FromLocal("Submit cancelled.");

-    CFX_ByteString bs = ws.UTF16LE_Encode();

-    int len = bs.GetLength() / sizeof(unsigned short);

-    pEnv->FFI_Alert((FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)),

-                    (FPDF_WIDESTRING)L"", 0, 4);

-    bs.ReleaseBuffer(len * sizeof(unsigned short));

-    return FALSE;

-  }

-

-  FPDF_BOOL bRet = TRUE;

-  FPDF_FILEHANDLER* pFileHandler = NULL;

-  int fileFlag = -1;

-

-  if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xdp) {

-    CFX_WideStringC csContentC;

-    submit.GetSubmitXDPContent(csContentC);

-    CFX_WideString csContent;

-    csContent = csContentC.GetPtr();

-    csContent.TrimLeft();

-    csContent.TrimRight();

-    CFX_WideString space;

-    space.FromLocal(" ");

-    csContent = space + csContent + space;

-    FPDF_DWORD flag = 0;

-    if (submit.IsSubmitEmbedPDF())

-      flag |= FXFA_PDF;

-    _ToXFAContentFlags(csContent, flag);

-    pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XDP, NULL, "wb");

-    fileFlag = FXFA_SAVEAS_XDP;

-    _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag);

-  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xml) {

-    pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb");

-    fileFlag = FXFA_SAVEAS_XML;

-    _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0);

-  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Pdf) {

-    // csfilename = csDocName;

-  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Formdata) {

-    return FALSE;

-  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Urlencoded) {

-    pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb");

-    fileFlag = FXFA_SAVEAS_XML;

-    _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0);

-  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xfd) {

-    return FALSE;

-  } else {

-    return FALSE;

-  }

-  if (pFileHandler == NULL)

-    return FALSE;

-  if (0 == csURL.Left(7).CompareNoCase(L"mailto:")) {

-    CFX_WideString csToAddress;

-    CFX_WideString csCCAddress;

-    CFX_WideString csBCCAddress;

-    CFX_WideString csSubject;

-    CFX_WideString csMsg;

-

-    bRet = _MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject,

-                       csMsg);

-    if (FALSE == bRet)

-      return FALSE;

-

-    CFX_ByteString bsTo = CFX_WideString(csToAddress).UTF16LE_Encode();

-    CFX_ByteString bsCC = CFX_WideString(csCCAddress).UTF16LE_Encode();

-    CFX_ByteString bsBcc = CFX_WideString(csBCCAddress).UTF16LE_Encode();

-    CFX_ByteString bsSubject = CFX_WideString(csSubject).UTF16LE_Encode();

-    CFX_ByteString bsMsg = CFX_WideString(csMsg).UTF16LE_Encode();

-

-    FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength());

-    FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength());

-    FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength());

-    FPDF_WIDESTRING pSubject =

-        (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength());

-    FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());

-

-    pEnv->FFI_EmailTo(pFileHandler, pTo, pSubject, pCC, pBcc, pMsg);

-    bsTo.ReleaseBuffer();

-    bsCC.ReleaseBuffer();

-    bsBcc.ReleaseBuffer();

-    bsSubject.ReleaseBuffer();

-    bsMsg.ReleaseBuffer();

-  } else {

-    // http¡¢ftp

-    CFX_WideString ws;

-    CFX_ByteString bs = csURL.UTF16LE_Encode();

-    int len = bs.GetLength() / sizeof(unsigned short);

-    pEnv->FFI_UploadTo(

-        pFileHandler, fileFlag,

-        (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)));

-    bs.ReleaseBuffer(len * sizeof(unsigned short));

-  }

-

-  return bRet;

-#else

-  return TRUE;

-#endif

-}

-

-FX_BOOL CPDFXFA_Document::SetGlobalProperty(IXFA_Doc* hDoc,

-                                            const CFX_ByteStringC& szPropName,

-                                            FXJSE_HVALUE hValue) {

-  if (hDoc != m_pXFADoc)

-    return FALSE;

-

-  if (m_pSDKDoc && m_pSDKDoc->GetEnv()->GetJSRuntime())

-    return m_pSDKDoc->GetEnv()->GetJSRuntime()->SetHValueByName(szPropName,

-                                                                hValue);

-  return FALSE;

-}

-FX_BOOL CPDFXFA_Document::GetPDFScriptObject(IXFA_Doc* hDoc,

-                                             const CFX_ByteStringC& utf8Name,

-                                             FXJSE_HVALUE hValue) {

-  if (hDoc != m_pXFADoc)

-    return FALSE;

-

-  if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime())

-    return FALSE;

-

-  if (!m_pJSContext) {

-    m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc);

-    m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext();

-  }

-

-  return _GetHValueByName(utf8Name, hValue,

-                          m_pSDKDoc->GetEnv()->GetJSRuntime());

-}

-FX_BOOL CPDFXFA_Document::GetGlobalProperty(IXFA_Doc* hDoc,

-                                            const CFX_ByteStringC& szPropName,

-                                            FXJSE_HVALUE hValue) {

-  if (hDoc != m_pXFADoc)

-    return FALSE;

-  if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime())

-    return FALSE;

-

-  if (!m_pJSContext) {

-    m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc);

-    m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext();

-  }

-

-  return _GetHValueByName(szPropName, hValue,

-                          m_pSDKDoc->GetEnv()->GetJSRuntime());

-}

-FX_BOOL CPDFXFA_Document::_GetHValueByName(const CFX_ByteStringC& utf8Name,

-                                           FXJSE_HVALUE hValue,

-                                           IJS_Runtime* runTime) {

-  return runTime->GetHValueByName(utf8Name, hValue);

-}

+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/include/fsdk_define.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
+#include "fpdfsdk/include/fsdk_mgr.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
+#include "fpdfsdk/include/javascript/IJavaScript.h"
+#include "public/fpdf_formfill.h"
+
+#define IDS_XFA_Validate_Input                                          \
+  "At least one required field was empty. Please fill in the required " \
+  "fields\r\n(highlighted) before continuing."
+
+// submit
+#define FXFA_CONFIG 0x00000001
+#define FXFA_TEMPLATE 0x00000010
+#define FXFA_LOCALESET 0x00000100
+#define FXFA_DATASETS 0x00001000
+#define FXFA_XMPMETA 0x00010000
+#define FXFA_XFDF 0x00100000
+#define FXFA_FORM 0x01000000
+#define FXFA_PDF 0x10000000
+
+#ifndef _WIN32
+extern void SetLastError(int err);
+
+extern int GetLastError();
+#endif
+
+CPDFXFA_Document::CPDFXFA_Document(CPDF_Document* pPDFDoc,
+                                   CPDFXFA_App* pProvider)
+    : m_iDocType(DOCTYPE_PDF),
+      m_pPDFDoc(pPDFDoc),
+      m_pSDKDoc(nullptr),
+      m_pXFADoc(nullptr),
+      m_pXFADocView(nullptr),
+      m_pApp(pProvider),
+      m_pJSContext(nullptr) {
+}
+
+CPDFXFA_Document::~CPDFXFA_Document() {
+  if (m_pJSContext && m_pSDKDoc && m_pSDKDoc->GetEnv())
+    m_pSDKDoc->GetEnv()->GetJSRuntime()->ReleaseContext(m_pJSContext);
+
+  delete m_pSDKDoc;
+
+  if (m_pPDFDoc) {
+    CPDF_Parser* pParser = m_pPDFDoc->GetParser();
+    if (pParser)
+      delete pParser;
+    else
+      delete m_pPDFDoc;
+  }
+  if (m_pXFADoc) {
+    IXFA_App* pApp = m_pApp->GetXFAApp();
+    if (pApp) {
+      IXFA_DocHandler* pDocHandler = pApp->GetDocHandler();
+      if (pDocHandler) {
+        CloseXFADoc(pDocHandler);
+      }
+    }
+    delete m_pXFADoc;
+  }
+}
+
+FX_BOOL CPDFXFA_Document::LoadXFADoc() {
+  if (!m_pPDFDoc)
+    return FALSE;
+
+  m_XFAPageList.RemoveAll();
+
+  IXFA_App* pApp = m_pApp->GetXFAApp();
+  if (!pApp)
+    return FALSE;
+
+  m_pXFADoc = pApp->CreateDoc(this, m_pPDFDoc);
+  if (!m_pXFADoc) {
+    SetLastError(FPDF_ERR_XFALOAD);
+    return FALSE;
+  }
+
+  IXFA_DocHandler* pDocHandler = pApp->GetDocHandler();
+  if (!pDocHandler) {
+    SetLastError(FPDF_ERR_XFALOAD);
+    return FALSE;
+  }
+
+  pDocHandler->StartLoad(m_pXFADoc);
+  int iStatus = pDocHandler->DoLoad(m_pXFADoc, NULL);
+  if (iStatus != XFA_PARSESTATUS_Done) {
+    CloseXFADoc(pDocHandler);
+    SetLastError(FPDF_ERR_XFALOAD);
+    return FALSE;
+  }
+  pDocHandler->StopLoad(m_pXFADoc);
+  pDocHandler->SetJSERuntime(m_pXFADoc, m_pApp->GetJSERuntime());
+
+  if (pDocHandler->GetDocType(m_pXFADoc) == XFA_DOCTYPE_Dynamic)
+    m_iDocType = DOCTYPE_DYNAMIC_XFA;
+  else
+    m_iDocType = DOCTYPE_STATIC_XFA;
+
+  m_pXFADocView = pDocHandler->CreateDocView(m_pXFADoc, XFA_DOCVIEW_View);
+  if (m_pXFADocView->StartLayout() < 0) {
+    CloseXFADoc(pDocHandler);
+    SetLastError(FPDF_ERR_XFALAYOUT);
+    return FALSE;
+  }
+
+  m_pXFADocView->DoLayout(NULL);
+  m_pXFADocView->StopLayout();
+  return TRUE;
+}
+
+int CPDFXFA_Document::GetPageCount() {
+  if (!m_pPDFDoc && !m_pXFADoc)
+    return 0;
+
+  switch (m_iDocType) {
+    case DOCTYPE_PDF:
+    case DOCTYPE_STATIC_XFA:
+      if (m_pPDFDoc)
+        return m_pPDFDoc->GetPageCount();
+    case DOCTYPE_DYNAMIC_XFA:
+      if (m_pXFADoc)
+        return m_pXFADocView->CountPageViews();
+    default:
+      return 0;
+  }
+
+  return 0;
+}
+
+CPDFXFA_Page* CPDFXFA_Document::GetPage(int page_index) {
+  if (page_index < 0)
+    return nullptr;
+  CPDFXFA_Page* pPage = nullptr;
+  int nCount = m_XFAPageList.GetSize();
+  if (nCount > 0 && page_index < nCount) {
+    pPage = m_XFAPageList.GetAt(page_index);
+    if (pPage)
+      pPage->AddRef();
+  } else {
+    m_XFAPageList.SetSize(GetPageCount());
+  }
+  if (pPage)
+    return pPage;
+  pPage = new CPDFXFA_Page(this, page_index);
+  if (!pPage->LoadPage()) {
+    delete pPage;
+    return nullptr;
+  }
+  m_XFAPageList.SetAt(page_index, pPage);
+  return pPage;
+}
+
+CPDFXFA_Page* CPDFXFA_Document::GetPage(IXFA_PageView* pPage) {
+  if (!pPage)
+    return NULL;
+
+  if (!m_pXFADoc)
+    return NULL;
+
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)
+    return NULL;
+
+  int nSize = m_XFAPageList.GetSize();
+  for (int i = 0; i < nSize; i++) {
+    CPDFXFA_Page* pTempPage = m_XFAPageList.GetAt(i);
+    if (!pTempPage)
+      continue;
+    if (pTempPage->GetXFAPageView() && pTempPage->GetXFAPageView() == pPage)
+      return pTempPage;
+  }
+
+  return NULL;
+}
+
+void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) {
+  m_XFAPageList.SetAt(page->GetPageIndex(), NULL);
+}
+
+CPDFSDK_Document* CPDFXFA_Document::GetSDKDocument(
+    CPDFDoc_Environment* pFormFillEnv) {
+  if (!m_pSDKDoc && pFormFillEnv)
+    m_pSDKDoc = new CPDFSDK_Document(this, pFormFillEnv);
+  return m_pSDKDoc;
+}
+
+void CPDFXFA_Document::FXRect2PDFRect(const CFX_RectF& fxRectF,
+                                      CPDF_Rect& pdfRect) {
+  pdfRect.left = fxRectF.left;
+  pdfRect.top = fxRectF.bottom();
+  pdfRect.right = fxRectF.right();
+  pdfRect.bottom = fxRectF.top;
+}
+
+void CPDFXFA_Document::SetChangeMark(IXFA_Doc* hDoc) {
+  if (hDoc == m_pXFADoc && m_pSDKDoc) {
+    m_pSDKDoc->SetChangeMark();
+  }
+}
+
+FX_BOOL CPDFXFA_Document::GetChangeMark(IXFA_Doc* hDoc) {
+  if (hDoc == m_pXFADoc && m_pSDKDoc)
+    return m_pSDKDoc->GetChangeMark();
+  return FALSE;
+}
+
+void CPDFXFA_Document::InvalidateRect(IXFA_PageView* pPageView,
+                                      const CFX_RectF& rt,
+                                      FX_DWORD dwFlags /* = 0 */) {
+  if (!m_pXFADoc || !m_pSDKDoc)
+    return;
+
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)
+    return;
+
+  CPDF_Rect rcPage;
+  FXRect2PDFRect(rt, rcPage);
+
+  CPDFXFA_Page* pPage = GetPage(pPageView);
+
+  if (pPage == NULL)
+    return;
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (!pEnv)
+    return;
+
+  pEnv->FFI_Invalidate((FPDF_PAGE)pPage, rcPage.left, rcPage.bottom,
+                       rcPage.right, rcPage.top);
+}
+
+void CPDFXFA_Document::InvalidateRect(IXFA_Widget* hWidget,
+                                      FX_DWORD dwFlags /* = 0 */) {
+  if (!hWidget)
+    return;
+
+  if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView)
+    return;
+
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)
+    return;
+
+  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();
+  if (!pWidgetHandler)
+    return;
+
+  IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget);
+  if (!pPageView)
+    return;
+
+  CFX_RectF rect;
+  pWidgetHandler->GetRect(hWidget, rect);
+  InvalidateRect(pPageView, rect, dwFlags);
+}
+
+void CPDFXFA_Document::DisplayCaret(IXFA_Widget* hWidget,
+                                    FX_BOOL bVisible,
+                                    const CFX_RectF* pRtAnchor) {
+  if (!hWidget || pRtAnchor == NULL)
+    return;
+
+  if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView)
+    return;
+
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)
+    return;
+
+  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();
+  if (!pWidgetHandler)
+    return;
+
+  IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget);
+  if (!pPageView)
+    return;
+
+  CPDFXFA_Page* pPage = GetPage(pPageView);
+
+  if (pPage == NULL)
+    return;
+
+  CPDF_Rect rcCaret;
+  FXRect2PDFRect(*pRtAnchor, rcCaret);
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (!pEnv)
+    return;
+
+  pEnv->FFI_DisplayCaret((FPDF_PAGE)pPage, bVisible, rcCaret.left, rcCaret.top,
+                         rcCaret.right, rcCaret.bottom);
+}
+
+FX_BOOL CPDFXFA_Document::GetPopupPos(IXFA_Widget* hWidget,
+                                      FX_FLOAT fMinPopup,
+                                      FX_FLOAT fMaxPopup,
+                                      const CFX_RectF& rtAnchor,
+                                      CFX_RectF& rtPopup) {
+  if (NULL == hWidget) {
+    return FALSE;
+  }
+  IXFA_PageView* pXFAPageView =
+      m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);
+  if (NULL == pXFAPageView) {
+    return FALSE;
+  }
+  CPDFXFA_Page* pPage = GetPage(pXFAPageView);
+  if (pPage == NULL)
+    return FALSE;
+
+  CXFA_WidgetAcc* pWidgetAcc =
+      m_pXFADocView->GetWidgetHandler()->GetDataAcc(hWidget);
+
+  int nRotate = 0;
+#ifdef PDF_ENABLE_XFA
+  nRotate = pWidgetAcc->GetRotate();
+#endif
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return FALSE;
+  FS_RECTF pageViewRect;
+  pEnv->FFI_GetPageViewRect(pPage, pageViewRect);
+
+  CPDF_Rect rcAnchor;
+
+  rcAnchor.left = rtAnchor.left;
+  rcAnchor.top = rtAnchor.bottom();
+  rcAnchor.right = rtAnchor.right();
+  rcAnchor.bottom = rtAnchor.top;
+
+  int t1, t2, t;
+  FX_DWORD dwPos;
+  FX_FLOAT fPoupHeight;
+  switch (nRotate) {
+    case 90: {
+      t1 = (int)(pageViewRect.right - rcAnchor.right);
+      t2 = (int)(rcAnchor.left - pageViewRect.left);
+      if (rcAnchor.bottom < pageViewRect.bottom) {
+        rtPopup.left += rcAnchor.bottom - pageViewRect.bottom;
+      }
+
+      break;
+    }
+
+    case 180: {
+      t2 = (int)(pageViewRect.top - rcAnchor.top);
+      t1 = (int)(rcAnchor.bottom - pageViewRect.bottom);
+      if (rcAnchor.left < pageViewRect.left) {
+        rtPopup.left += rcAnchor.left - pageViewRect.left;
+      }
+      break;
+    }
+    case 270: {
+      t1 = (int)(rcAnchor.left - pageViewRect.left);
+      t2 = (int)(pageViewRect.right - rcAnchor.right);
+
+      if (rcAnchor.top > pageViewRect.top) {
+        rtPopup.left -= rcAnchor.top - pageViewRect.top;
+      }
+      break;
+    }
+    case 0:
+    default: {
+      t1 = (int)(pageViewRect.top - rcAnchor.top);
+      t2 = (int)(rcAnchor.bottom - pageViewRect.bottom);
+      if (rcAnchor.right > pageViewRect.right) {
+        rtPopup.left -= rcAnchor.right - pageViewRect.right;
+      }
+      break;
+    }
+  }
+
+  if (t1 <= 0 && t2 <= 0) {
+    return FALSE;
+  }
+  if (t1 <= 0) {
+    t = t2;
+    dwPos = 1;
+  } else if (t2 <= 0) {
+    t = t1;
+    dwPos = 0;
+  } else if (t1 > t2) {
+    t = t1;
+    dwPos = 0;
+  } else {
+    t = t2;
+    dwPos = 1;
+  }
+  if (t < fMinPopup) {
+    fPoupHeight = fMinPopup;
+  } else if (t > fMaxPopup) {
+    fPoupHeight = fMaxPopup;
+  } else {
+    fPoupHeight = (FX_FLOAT)t;
+  }
+
+  switch (nRotate) {
+    case 0:
+    case 180: {
+      if (dwPos == 0) {
+        rtPopup.top = rtAnchor.height;
+        rtPopup.height = fPoupHeight;
+      } else {
+        rtPopup.top = -fPoupHeight;
+        rtPopup.height = fPoupHeight;
+      }
+      break;
+    }
+    case 90:
+    case 270: {
+      if (dwPos == 0) {
+        rtPopup.top = rtAnchor.width;
+        rtPopup.height = fPoupHeight;
+      } else {
+        rtPopup.top = -fPoupHeight;
+        rtPopup.height = fPoupHeight;
+      }
+      break;
+    }
+    default:
+      break;
+  }
+
+  return TRUE;
+}
+
+FX_BOOL CPDFXFA_Document::PopupMenu(IXFA_Widget* hWidget,
+                                    CFX_PointF ptPopup,
+                                    const CFX_RectF* pRectExclude) {
+  if (NULL == hWidget) {
+    return FALSE;
+  }
+  IXFA_PageView* pXFAPageView =
+      m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);
+  if (pXFAPageView == NULL)
+    return FALSE;
+  CPDFXFA_Page* pPage = GetPage(pXFAPageView);
+
+  if (pPage == NULL)
+    return FALSE;
+
+  int menuFlag = 0;
+
+  IXFA_MenuHandler* pXFAMenuHander = m_pApp->GetXFAApp()->GetMenuHandler();
+  if (pXFAMenuHander->CanUndo(hWidget))
+    menuFlag |= FXFA_MEMU_UNDO;
+  if (pXFAMenuHander->CanRedo(hWidget))
+    menuFlag |= FXFA_MEMU_REDO;
+  if (pXFAMenuHander->CanPaste(hWidget))
+    menuFlag |= FXFA_MEMU_PASTE;
+  if (pXFAMenuHander->CanCopy(hWidget))
+    menuFlag |= FXFA_MEMU_COPY;
+  if (pXFAMenuHander->CanCut(hWidget))
+    menuFlag |= FXFA_MEMU_CUT;
+  if (pXFAMenuHander->CanSelectAll(hWidget))
+    menuFlag |= FXFA_MEMU_SELECTALL;
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return FALSE;
+
+  return pEnv->FFI_PopupMenu(pPage, hWidget, menuFlag, ptPopup, NULL);
+}
+
+void CPDFXFA_Document::PageViewEvent(IXFA_PageView* pPageView,
+                                     FX_DWORD dwFlags) {
+  if (!pPageView || (dwFlags != XFA_PAGEVIEWEVENT_PostAdded &&
+                     dwFlags != XFA_PAGEVIEWEVENT_PostRemoved)) {
+    return;
+  }
+  CPDFXFA_Page* pPage = nullptr;
+  if (dwFlags == XFA_PAGEVIEWEVENT_PostAdded) {
+    pPage = GetPage(pPageView->GetPageViewIndex());
+    if (pPage)
+      pPage->SetXFAPageView(pPageView);
+    return;
+  }
+  pPage = GetPage(pPageView);
+  if (!pPage)
+    return;
+  pPage->SetXFAPageView(nullptr);
+  m_pSDKDoc->GetPageView(pPage)->ClearFXAnnots();
+}
+
+void CPDFXFA_Document::WidgetEvent(IXFA_Widget* hWidget,
+                                   CXFA_WidgetAcc* pWidgetData,
+                                   FX_DWORD dwEvent,
+                                   void* pParam,
+                                   void* pAdditional) {
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA || !hWidget)
+    return;
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (!pEnv)
+    return;
+
+  IXFA_PageView* pPageView =
+      m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);
+  if (pPageView == NULL)
+    return;
+
+  CPDFXFA_Page* pXFAPage = GetPage(pPageView);
+  if (pXFAPage == NULL)
+    return;
+
+  CPDFSDK_PageView* pSdkPageView = m_pSDKDoc->GetPageView(pXFAPage);
+  if (dwEvent == XFA_WIDGETEVENT_PostAdded) {
+    pSdkPageView->AddAnnot(hWidget);
+
+  } else if (dwEvent == XFA_WIDGETEVENT_PreRemoved) {
+    CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget);
+    if (pAnnot) {
+      pSdkPageView->DeleteAnnot(pAnnot);
+    }
+  }
+}
+
+int32_t CPDFXFA_Document::CountPages(IXFA_Doc* hDoc) {
+  if (hDoc == m_pXFADoc && m_pSDKDoc) {
+    return GetPageCount();
+  }
+  return 0;
+}
+int32_t CPDFXFA_Document::GetCurrentPage(IXFA_Doc* hDoc) {
+  if (hDoc != m_pXFADoc || !m_pSDKDoc)
+    return -1;
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)
+    return -1;
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return -1;
+
+  return pEnv->FFI_GetCurrentPageIndex(this);
+}
+void CPDFXFA_Document::SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage) {
+  if (hDoc != m_pXFADoc || !m_pSDKDoc)
+    return;
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)
+    return;
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return;
+
+  pEnv->FFI_SetCurrentPage(this, iCurPage);
+}
+FX_BOOL CPDFXFA_Document::IsCalculationsEnabled(IXFA_Doc* hDoc) {
+  if (hDoc != m_pXFADoc || !m_pSDKDoc)
+    return FALSE;
+  if (m_pSDKDoc->GetInterForm())
+    return m_pSDKDoc->GetInterForm()->IsXfaCalculateEnabled();
+
+  return FALSE;
+}
+void CPDFXFA_Document::SetCalculationsEnabled(IXFA_Doc* hDoc,
+                                              FX_BOOL bEnabled) {
+  if (hDoc != m_pXFADoc || !m_pSDKDoc)
+    return;
+  if (m_pSDKDoc->GetInterForm())
+    m_pSDKDoc->GetInterForm()->XfaEnableCalculate(bEnabled);
+}
+
+void CPDFXFA_Document::GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle) {
+  if (hDoc != m_pXFADoc)
+    return;
+  if (m_pPDFDoc == NULL)
+    return;
+  CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo();
+
+  if (pInfoDict == NULL)
+    return;
+
+  CFX_ByteString csTitle = pInfoDict->GetString("Title");
+  wsTitle = wsTitle.FromLocal(csTitle.GetBuffer(csTitle.GetLength()));
+  csTitle.ReleaseBuffer(csTitle.GetLength());
+}
+void CPDFXFA_Document::SetTitle(IXFA_Doc* hDoc,
+                                const CFX_WideStringC& wsTitle) {
+  if (hDoc != m_pXFADoc)
+    return;
+  if (m_pPDFDoc == NULL)
+    return;
+  CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo();
+
+  if (pInfoDict == NULL)
+    return;
+  pInfoDict->SetAt("Title", new CPDF_String(wsTitle));
+}
+void CPDFXFA_Document::ExportData(IXFA_Doc* hDoc,
+                                  const CFX_WideStringC& wsFilePath,
+                                  FX_BOOL bXDP) {
+  if (hDoc != m_pXFADoc)
+    return;
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)
+    return;
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return;
+  int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML;
+  CFX_ByteString bs = CFX_WideString(wsFilePath).UTF16LE_Encode();
+
+  if (wsFilePath.IsEmpty()) {
+    if (!pEnv->GetFormFillInfo() ||
+        pEnv->GetFormFillInfo()->m_pJsPlatform == NULL)
+      return;
+    CFX_WideString filepath = pEnv->JS_fieldBrowse();
+    bs = filepath.UTF16LE_Encode();
+  }
+  int len = bs.GetLength() / sizeof(unsigned short);
+  FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile(
+      bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML,
+      (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "wb");
+  bs.ReleaseBuffer(len * sizeof(unsigned short));
+
+  if (pFileHandler == NULL)
+    return;
+
+  CFPDF_FileStream fileWrite(pFileHandler);
+
+  IXFA_DocHandler* pXFADocHander = m_pApp->GetXFAApp()->GetDocHandler();
+  CFX_ByteString content;
+  if (fileType == FXFA_SAVEAS_XML) {
+    content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
+    fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(),
+                         content.GetLength());
+    CFX_WideStringC data(L"data");
+    if (pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), data, &fileWrite)) {
+      // TODO: Maybe report error.
+    }
+  } else if (fileType == FXFA_SAVEAS_XDP) {
+    if (m_pPDFDoc == NULL)
+      return;
+    CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();
+    if (pRoot == NULL)
+      return;
+    CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
+    if (NULL == pAcroForm)
+      return;
+    CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
+    if (pXFA == NULL)
+      return;
+    if (!pXFA->IsArray())
+      return;
+    CPDF_Array* pArray = pXFA->GetArray();
+    if (NULL == pArray)
+      return;
+    int size = pArray->GetCount();
+    for (int i = 1; i < size; i += 2) {
+      CPDF_Object* pPDFObj = pArray->GetElement(i);
+      CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1);
+      if (!pPrePDFObj->IsString())
+        continue;
+      if (!pPDFObj->IsReference())
+        continue;
+      CPDF_Object* pDirectObj = pPDFObj->GetDirect();
+      if (!pDirectObj->IsStream())
+        continue;
+      if (pPrePDFObj->GetString() == "form") {
+        CFX_WideStringC form(L"form");
+        pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), form, &fileWrite);
+      } else if (pPrePDFObj->GetString() == "datasets") {
+        CFX_WideStringC datasets(L"datasets");
+        pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), datasets,
+                                   &fileWrite);
+      } else {
+        if (i == size - 1) {
+          CFX_WideString wPath = CFX_WideString::FromUTF16LE(
+              (unsigned short*)(const FX_CHAR*)bs,
+              bs.GetLength() / sizeof(unsigned short));
+          CFX_ByteString bPath = wPath.UTF8Encode();
+          CFX_ByteString szFormat =
+              "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";
+          content.Format(szFormat, (char*)(const FX_CHAR*)bPath);
+          fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(),
+                               content.GetLength());
+        }
+
+        CPDF_Stream* pStream = (CPDF_Stream*)pDirectObj;
+        CPDF_StreamAcc* pAcc = new CPDF_StreamAcc;
+        pAcc->LoadAllData(pStream);
+        fileWrite.WriteBlock(pAcc->GetData(), fileWrite.GetSize(),
+                             pAcc->GetSize());
+        delete pAcc;
+      }
+    }
+  }
+  if (!fileWrite.Flush()) {
+    // TODO: Report error.
+  }
+}
+void CPDFXFA_Document::ImportData(IXFA_Doc* hDoc,
+                                  const CFX_WideStringC& wsFilePath) {
+  // TODO...
+}
+
+void CPDFXFA_Document::GotoURL(IXFA_Doc* hDoc,
+                               const CFX_WideStringC& bsURL,
+                               FX_BOOL bAppend) {
+  if (hDoc != m_pXFADoc)
+    return;
+
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)
+    return;
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return;
+
+  CFX_WideStringC str(bsURL.GetPtr());
+
+  pEnv->FFI_GotoURL(this, str, bAppend);
+}
+
+FX_BOOL CPDFXFA_Document::IsValidationsEnabled(IXFA_Doc* hDoc) {
+  if (hDoc != m_pXFADoc || !m_pSDKDoc)
+    return FALSE;
+  if (m_pSDKDoc->GetInterForm())
+    return m_pSDKDoc->GetInterForm()->IsXfaValidationsEnabled();
+
+  return TRUE;
+}
+void CPDFXFA_Document::SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled) {
+  if (hDoc != m_pXFADoc || !m_pSDKDoc)
+    return;
+  if (m_pSDKDoc->GetInterForm())
+    m_pSDKDoc->GetInterForm()->XfaSetValidationsEnabled(bEnabled);
+}
+void CPDFXFA_Document::SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget) {
+  if (hDoc != m_pXFADoc)
+    return;
+
+  if (NULL == hWidget) {
+    m_pSDKDoc->SetFocusAnnot(NULL);
+    return;
+  }
+
+  int pageViewCount = m_pSDKDoc->GetPageViewCount();
+  for (int i = 0; i < pageViewCount; i++) {
+    CPDFSDK_PageView* pPageView = m_pSDKDoc->GetPageView(i);
+    if (pPageView == NULL)
+      continue;
+    CPDFSDK_Annot* pAnnot = pPageView->GetAnnotByXFAWidget(hWidget);
+    if (pAnnot) {
+      m_pSDKDoc->SetFocusAnnot(pAnnot);
+      break;
+    }
+  }
+}
+void CPDFXFA_Document::Print(IXFA_Doc* hDoc,
+                             int32_t nStartPage,
+                             int32_t nEndPage,
+                             FX_DWORD dwOptions) {
+  if (hDoc != m_pXFADoc)
+    return;
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return;
+
+  if (!pEnv->GetFormFillInfo() ||
+      pEnv->GetFormFillInfo()->m_pJsPlatform == NULL)
+    return;
+  if (pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print == NULL)
+    return;
+  pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print(
+      pEnv->GetFormFillInfo()->m_pJsPlatform,
+      dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage,
+      dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage,
+      dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder,
+      dwOptions & XFA_PRINTOPT_PrintAnnot);
+}
+
+void CPDFXFA_Document::GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL) {
+  if (hDoc != m_pXFADoc)
+    return;
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return;
+
+  pEnv->FFI_GetURL(this, wsDocURL);
+}
+
+FX_ARGB CPDFXFA_Document::GetHighlightColor(IXFA_Doc* hDoc) {
+  if (hDoc != m_pXFADoc)
+    return 0;
+  if (m_pSDKDoc) {
+    if (CPDFSDK_InterForm* pInterForm = m_pSDKDoc->GetInterForm()) {
+      FX_COLORREF color = pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA);
+      uint8_t alpha = pInterForm->GetHighlightAlpha();
+      FX_ARGB argb = ArgbEncode((int)alpha, color);
+      return argb;
+    }
+  }
+  return 0;
+}
+
+FX_BOOL CPDFXFA_Document::_NotifySubmit(FX_BOOL bPrevOrPost) {
+  if (bPrevOrPost)
+    return _OnBeforeNotifySumbit();
+
+  _OnAfterNotifySumbit();
+  return TRUE;
+}
+
+FX_BOOL CPDFXFA_Document::_OnBeforeNotifySumbit() {
+#ifdef PDF_ENABLE_XFA
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)
+    return TRUE;
+  if (m_pXFADocView == NULL)
+    return TRUE;
+  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();
+  if (pWidgetHandler == NULL)
+    return TRUE;
+  IXFA_WidgetAccIterator* pWidgetAccIterator =
+      m_pXFADocView->CreateWidgetAccIterator();
+  if (pWidgetAccIterator) {
+    CXFA_EventParam Param;
+    Param.m_eType = XFA_EVENT_PreSubmit;
+    CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();
+    while (pWidgetAcc) {
+      pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);
+      pWidgetAcc = pWidgetAccIterator->MoveToNext();
+    }
+    pWidgetAccIterator->Release();
+  }
+  pWidgetAccIterator = m_pXFADocView->CreateWidgetAccIterator();
+  if (pWidgetAccIterator) {
+    CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();
+    pWidgetAcc = pWidgetAccIterator->MoveToNext();
+    while (pWidgetAcc) {
+      int fRet = pWidgetAcc->ProcessValidate(-1);
+      if (fRet == XFA_EVENTERROR_Error) {
+        CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+        if (pEnv == NULL)
+          return FALSE;
+        CFX_WideString ws;
+        ws.FromLocal(IDS_XFA_Validate_Input);
+        CFX_ByteString bs = ws.UTF16LE_Encode();
+        int len = bs.GetLength() / sizeof(unsigned short);
+        pEnv->FFI_Alert(
+            (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)),
+            (FPDF_WIDESTRING)L"", 0, 1);
+        bs.ReleaseBuffer(len * sizeof(unsigned short));
+        pWidgetAccIterator->Release();
+        return FALSE;
+      }
+      pWidgetAcc = pWidgetAccIterator->MoveToNext();
+    }
+    pWidgetAccIterator->Release();
+    m_pXFADocView->UpdateDocView();
+  }
+#endif
+  return TRUE;
+}
+void CPDFXFA_Document::_OnAfterNotifySumbit() {
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)
+    return;
+  if (m_pXFADocView == NULL)
+    return;
+  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();
+  if (pWidgetHandler == NULL)
+    return;
+  IXFA_WidgetAccIterator* pWidgetAccIterator =
+      m_pXFADocView->CreateWidgetAccIterator();
+  if (pWidgetAccIterator == NULL)
+    return;
+  CXFA_EventParam Param;
+  Param.m_eType = XFA_EVENT_PostSubmit;
+
+  CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();
+  while (pWidgetAcc) {
+    pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);
+    pWidgetAcc = pWidgetAccIterator->MoveToNext();
+  }
+  pWidgetAccIterator->Release();
+  m_pXFADocView->UpdateDocView();
+}
+
+FX_BOOL CPDFXFA_Document::SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) {
+  if (!_NotifySubmit(TRUE))
+    return FALSE;
+  if (NULL == m_pXFADocView)
+    return FALSE;
+  m_pXFADocView->UpdateDocView();
+
+  FX_BOOL ret = _SubmitData(hDoc, submit);
+  _NotifySubmit(FALSE);
+  return ret;
+}
+
+IFX_FileRead* CPDFXFA_Document::OpenLinkedFile(IXFA_Doc* hDoc,
+                                               const CFX_WideString& wsLink) {
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return FALSE;
+  CFX_ByteString bs = wsLink.UTF16LE_Encode();
+  int len = bs.GetLength() / sizeof(unsigned short);
+  FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile(
+      0, (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "rb");
+  bs.ReleaseBuffer(len * sizeof(unsigned short));
+
+  if (pFileHandler == NULL)
+    return NULL;
+  return new CFPDF_FileStream(pFileHandler);
+}
+FX_BOOL CPDFXFA_Document::_ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler,
+                                            int fileType,
+                                            FPDF_DWORD encodeType,
+                                            FPDF_DWORD flag) {
+  if (NULL == m_pXFADocView)
+    return FALSE;
+  IXFA_DocHandler* pDocHandler = m_pApp->GetXFAApp()->GetDocHandler();
+  CFX_ByteString content;
+
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return FALSE;
+
+  CFPDF_FileStream fileStream(pFileHandler);
+
+  if (fileType == FXFA_SAVEAS_XML) {
+    CFX_WideString ws;
+    ws.FromLocal("data");
+    CFX_ByteString content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
+    fileStream.WriteBlock((const FX_CHAR*)content, 0, content.GetLength());
+    pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);
+  } else if (fileType == FXFA_SAVEAS_XDP) {
+    if (flag == 0)
+      flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
+             FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
+    if (m_pPDFDoc == NULL) {
+      fileStream.Flush();
+      return FALSE;
+    }
+    CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();
+    if (pRoot == NULL) {
+      fileStream.Flush();
+      return FALSE;
+    }
+    CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
+    if (NULL == pAcroForm) {
+      fileStream.Flush();
+      return FALSE;
+    }
+    CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
+    if (pXFA == NULL) {
+      fileStream.Flush();
+      return FALSE;
+    }
+    if (!pXFA->IsArray()) {
+      fileStream.Flush();
+      return FALSE;
+    }
+    CPDF_Array* pArray = pXFA->GetArray();
+    if (NULL == pArray) {
+      fileStream.Flush();
+      return FALSE;
+    }
+    int size = pArray->GetCount();
+    for (int i = 1; i < size; i += 2) {
+      CPDF_Object* pPDFObj = pArray->GetElement(i);
+      CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1);
+      if (!pPrePDFObj->IsString())
+        continue;
+      if (!pPDFObj->IsReference())
+        continue;
+      CPDF_Object* pDirectObj = pPDFObj->GetDirect();
+      if (!pDirectObj->IsStream())
+        continue;
+      if (pPrePDFObj->GetString() == "config" && !(flag & FXFA_CONFIG))
+        continue;
+      if (pPrePDFObj->GetString() == "template" && !(flag & FXFA_TEMPLATE))
+        continue;
+      if (pPrePDFObj->GetString() == "localeSet" && !(flag & FXFA_LOCALESET))
+        continue;
+      if (pPrePDFObj->GetString() == "datasets" && !(flag & FXFA_DATASETS))
+        continue;
+      if (pPrePDFObj->GetString() == "xmpmeta" && !(flag & FXFA_XMPMETA))
+        continue;
+      if (pPrePDFObj->GetString() == "xfdf" && !(flag & FXFA_XFDF))
+        continue;
+      if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM))
+        continue;
+      if (pPrePDFObj->GetString() == "form") {
+        CFX_WideString ws;
+        ws.FromLocal("form");
+        pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);
+      } else if (pPrePDFObj->GetString() == "datasets") {
+        CFX_WideString ws;
+        ws.FromLocal("datasets");
+        pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);
+      } else {
+        // PDF,creator.
+        // TODO:
+      }
+    }
+  }
+  return TRUE;
+}
+
+void CPDFXFA_Document::_ClearChangeMark() {
+  if (m_pSDKDoc)
+    m_pSDKDoc->ClearChangeMark();
+}
+
+void CPDFXFA_Document::_ToXFAContentFlags(CFX_WideString csSrcContent,
+                                          FPDF_DWORD& flag) {
+  if (csSrcContent.Find(L" config ", 0) != -1)
+    flag |= FXFA_CONFIG;
+  if (csSrcContent.Find(L" template ", 0) != -1)
+    flag |= FXFA_TEMPLATE;
+  if (csSrcContent.Find(L" localeSet ", 0) != -1)
+    flag |= FXFA_LOCALESET;
+  if (csSrcContent.Find(L" datasets ", 0) != -1)
+    flag |= FXFA_DATASETS;
+  if (csSrcContent.Find(L" xmpmeta ", 0) != -1)
+    flag |= FXFA_XMPMETA;
+  if (csSrcContent.Find(L" xfdf ", 0) != -1)
+    flag |= FXFA_XFDF;
+  if (csSrcContent.Find(L" form ", 0) != -1)
+    flag |= FXFA_FORM;
+  if (flag == 0)
+    flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
+           FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
+}
+FX_BOOL CPDFXFA_Document::_MailToInfo(CFX_WideString& csURL,
+                                      CFX_WideString& csToAddress,
+                                      CFX_WideString& csCCAddress,
+                                      CFX_WideString& csBCCAddress,
+                                      CFX_WideString& csSubject,
+                                      CFX_WideString& csMsg) {
+  CFX_WideString srcURL = csURL;
+  srcURL.TrimLeft();
+  if (0 != srcURL.Left(7).CompareNoCase(L"mailto:"))
+    return FALSE;
+  int pos = srcURL.Find(L'?', 0);
+  CFX_WideString tmp;
+  if (pos == -1) {
+    pos = srcURL.Find(L'@', 0);
+    if (pos == -1)
+      return FALSE;
+    else {
+      tmp = srcURL.Right(csURL.GetLength() - 7);
+      tmp.TrimLeft();
+      tmp.TrimRight();
+    }
+  } else {
+    tmp = srcURL.Left(pos);
+    tmp = tmp.Right(tmp.GetLength() - 7);
+    tmp.TrimLeft();
+    tmp.TrimRight();
+  }
+
+  csToAddress = tmp;
+
+  srcURL = srcURL.Right(srcURL.GetLength() - (pos + 1));
+  while (!srcURL.IsEmpty()) {
+    srcURL.TrimLeft();
+    srcURL.TrimRight();
+    pos = srcURL.Find(L'&', 0);
+    if (pos == -1)
+      tmp = srcURL;
+    else
+      tmp = srcURL.Left(pos);
+
+    tmp.TrimLeft();
+    tmp.TrimRight();
+    if (tmp.GetLength() >= 3 && 0 == tmp.Left(3).CompareNoCase(L"cc=")) {
+      tmp = tmp.Right(tmp.GetLength() - 3);
+      if (!csCCAddress.IsEmpty())
+        csCCAddress += L';';
+      csCCAddress += tmp;
+
+    } else if (tmp.GetLength() >= 4 &&
+               0 == tmp.Left(4).CompareNoCase(L"bcc=")) {
+      tmp = tmp.Right(tmp.GetLength() - 4);
+      if (!csBCCAddress.IsEmpty())
+        csBCCAddress += L';';
+      csBCCAddress += tmp;
+    } else if (tmp.GetLength() >= 8 &&
+               0 == tmp.Left(8).CompareNoCase(L"subject=")) {
+      tmp = tmp.Right(tmp.GetLength() - 8);
+      csSubject += tmp;
+    } else if (tmp.GetLength() >= 5 &&
+               0 == tmp.Left(5).CompareNoCase(L"body=")) {
+      tmp = tmp.Right(tmp.GetLength() - 5);
+      csMsg += tmp;
+    }
+    if (pos == -1)
+      srcURL = L"";
+    else
+      srcURL = srcURL.Right(csURL.GetLength() - (pos + 1));
+  }
+  csToAddress.Replace(L",", L";");
+  csCCAddress.Replace(L",", L";");
+  csBCCAddress.Replace(L",", L";");
+  return TRUE;
+}
+
+FX_BOOL CPDFXFA_Document::_SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) {
+#ifdef PDF_ENABLE_XFA
+  CFX_WideStringC csURLC;
+  submit.GetSubmitTarget(csURLC);
+  CFX_WideString csURL = csURLC;
+  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+  if (pEnv == NULL)
+    return FALSE;
+  if (csURL.IsEmpty()) {
+    CFX_WideString ws;
+    ws.FromLocal("Submit cancelled.");
+    CFX_ByteString bs = ws.UTF16LE_Encode();
+    int len = bs.GetLength() / sizeof(unsigned short);
+    pEnv->FFI_Alert((FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)),
+                    (FPDF_WIDESTRING)L"", 0, 4);
+    bs.ReleaseBuffer(len * sizeof(unsigned short));
+    return FALSE;
+  }
+
+  FPDF_BOOL bRet = TRUE;
+  FPDF_FILEHANDLER* pFileHandler = NULL;
+  int fileFlag = -1;
+
+  if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xdp) {
+    CFX_WideStringC csContentC;
+    submit.GetSubmitXDPContent(csContentC);
+    CFX_WideString csContent;
+    csContent = csContentC.GetPtr();
+    csContent.TrimLeft();
+    csContent.TrimRight();
+    CFX_WideString space;
+    space.FromLocal(" ");
+    csContent = space + csContent + space;
+    FPDF_DWORD flag = 0;
+    if (submit.IsSubmitEmbedPDF())
+      flag |= FXFA_PDF;
+    _ToXFAContentFlags(csContent, flag);
+    pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XDP, NULL, "wb");
+    fileFlag = FXFA_SAVEAS_XDP;
+    _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag);
+  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xml) {
+    pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb");
+    fileFlag = FXFA_SAVEAS_XML;
+    _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0);
+  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Pdf) {
+    // csfilename = csDocName;
+  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Formdata) {
+    return FALSE;
+  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Urlencoded) {
+    pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb");
+    fileFlag = FXFA_SAVEAS_XML;
+    _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0);
+  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xfd) {
+    return FALSE;
+  } else {
+    return FALSE;
+  }
+  if (pFileHandler == NULL)
+    return FALSE;
+  if (0 == csURL.Left(7).CompareNoCase(L"mailto:")) {
+    CFX_WideString csToAddress;
+    CFX_WideString csCCAddress;
+    CFX_WideString csBCCAddress;
+    CFX_WideString csSubject;
+    CFX_WideString csMsg;
+
+    bRet = _MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject,
+                       csMsg);
+    if (FALSE == bRet)
+      return FALSE;
+
+    CFX_ByteString bsTo = CFX_WideString(csToAddress).UTF16LE_Encode();
+    CFX_ByteString bsCC = CFX_WideString(csCCAddress).UTF16LE_Encode();
+    CFX_ByteString bsBcc = CFX_WideString(csBCCAddress).UTF16LE_Encode();
+    CFX_ByteString bsSubject = CFX_WideString(csSubject).UTF16LE_Encode();
+    CFX_ByteString bsMsg = CFX_WideString(csMsg).UTF16LE_Encode();
+
+    FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength());
+    FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength());
+    FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength());
+    FPDF_WIDESTRING pSubject =
+        (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength());
+    FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());
+
+    pEnv->FFI_EmailTo(pFileHandler, pTo, pSubject, pCC, pBcc, pMsg);
+    bsTo.ReleaseBuffer();
+    bsCC.ReleaseBuffer();
+    bsBcc.ReleaseBuffer();
+    bsSubject.ReleaseBuffer();
+    bsMsg.ReleaseBuffer();
+  } else {
+    // http¡¢ftp
+    CFX_WideString ws;
+    CFX_ByteString bs = csURL.UTF16LE_Encode();
+    int len = bs.GetLength() / sizeof(unsigned short);
+    pEnv->FFI_UploadTo(
+        pFileHandler, fileFlag,
+        (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)));
+    bs.ReleaseBuffer(len * sizeof(unsigned short));
+  }
+
+  return bRet;
+#else
+  return TRUE;
+#endif
+}
+
+FX_BOOL CPDFXFA_Document::SetGlobalProperty(IXFA_Doc* hDoc,
+                                            const CFX_ByteStringC& szPropName,
+                                            FXJSE_HVALUE hValue) {
+  if (hDoc != m_pXFADoc)
+    return FALSE;
+
+  if (m_pSDKDoc && m_pSDKDoc->GetEnv()->GetJSRuntime())
+    return m_pSDKDoc->GetEnv()->GetJSRuntime()->SetHValueByName(szPropName,
+                                                                hValue);
+  return FALSE;
+}
+FX_BOOL CPDFXFA_Document::GetPDFScriptObject(IXFA_Doc* hDoc,
+                                             const CFX_ByteStringC& utf8Name,
+                                             FXJSE_HVALUE hValue) {
+  if (hDoc != m_pXFADoc)
+    return FALSE;
+
+  if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime())
+    return FALSE;
+
+  if (!m_pJSContext) {
+    m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc);
+    m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext();
+  }
+
+  return _GetHValueByName(utf8Name, hValue,
+                          m_pSDKDoc->GetEnv()->GetJSRuntime());
+}
+FX_BOOL CPDFXFA_Document::GetGlobalProperty(IXFA_Doc* hDoc,
+                                            const CFX_ByteStringC& szPropName,
+                                            FXJSE_HVALUE hValue) {
+  if (hDoc != m_pXFADoc)
+    return FALSE;
+  if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime())
+    return FALSE;
+
+  if (!m_pJSContext) {
+    m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc);
+    m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext();
+  }
+
+  return _GetHValueByName(szPropName, hValue,
+                          m_pSDKDoc->GetEnv()->GetJSRuntime());
+}
+FX_BOOL CPDFXFA_Document::_GetHValueByName(const CFX_ByteStringC& utf8Name,
+                                           FXJSE_HVALUE hValue,
+                                           IJS_Runtime* runTime) {
+  return runTime->GetHValueByName(utf8Name, hValue);
+}
diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp
index edd25c7..24c1ed1 100644
--- a/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp
+++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp
@@ -1,255 +1,255 @@
-// Copyright 2014 PDFium Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-

-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

-

-#include "fpdfsdk/include/fsdk_define.h"

-#include "fpdfsdk/include/fsdk_mgr.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"

-

-CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index)

-    : m_pPDFPage(NULL),

-      m_pXFAPageView(NULL),

-      m_iPageIndex(page_index),

-      m_pDocument(pDoc),

-      m_iRef(1) {}

-

-CPDFXFA_Page::~CPDFXFA_Page() {

-  if (m_pPDFPage)

-    delete m_pPDFPage;

-  m_pPDFPage = NULL;

-  m_pXFAPageView = NULL;

-}

-

-void CPDFXFA_Page::Release() {

-  m_iRef--;

-  if (m_iRef > 0)

-    return;

-

-  if (m_pDocument)

-    m_pDocument->RemovePage(this);

-

-  delete this;

-}

-

-FX_BOOL CPDFXFA_Page::LoadPDFPage() {

-  if (!m_pDocument)

-    return FALSE;

-  CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc();

-  if (pPDFDoc) {

-    CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex);

-    if (pDict == NULL)

-      return FALSE;

-    if (m_pPDFPage) {

-      if (m_pPDFPage->m_pFormDict == pDict)

-        return TRUE;

-

-      delete m_pPDFPage;

-      m_pPDFPage = NULL;

-    }

-

-    m_pPDFPage = new CPDF_Page;

-    m_pPDFPage->Load(pPDFDoc, pDict);

-    m_pPDFPage->ParseContent(nullptr);

-    return TRUE;

-  }

-

-  return FALSE;

-}

-

-FX_BOOL CPDFXFA_Page::LoadXFAPageView() {

-  if (!m_pDocument)

-    return FALSE;

-  IXFA_Doc* pXFADoc = m_pDocument->GetXFADoc();

-  if (!pXFADoc)

-    return FALSE;

-

-  IXFA_DocView* pXFADocView = m_pDocument->GetXFADocView();

-  if (!pXFADocView)

-    return FALSE;

-

-  IXFA_PageView* pPageView = pXFADocView->GetPageView(m_iPageIndex);

-  if (!pPageView)

-    return FALSE;

-

-  if (m_pXFAPageView == pPageView)

-    return TRUE;

-

-  m_pXFAPageView = pPageView;

-  (void)m_pXFAPageView->LoadPageView(nullptr);

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_Page::LoadPage() {

-  if (!m_pDocument || m_iPageIndex < 0)

-    return FALSE;

-

-  int iDocType = m_pDocument->GetDocType();

-  switch (iDocType) {

-    case DOCTYPE_PDF:

-    case DOCTYPE_STATIC_XFA: {

-      return LoadPDFPage();

-    }

-    case DOCTYPE_DYNAMIC_XFA: {

-      return LoadXFAPageView();

-    }

-    default:

-      return FALSE;

-  }

-

-  return FALSE;

-}

-

-FX_BOOL CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) {

-  if (!m_pDocument || m_iPageIndex < 0 || !pageDict)

-    return FALSE;

-

-  if (m_pPDFPage)

-    delete m_pPDFPage;

-

-  m_pPDFPage = new CPDF_Page();

-  m_pPDFPage->Load(m_pDocument->GetPDFDoc(), pageDict);

-  m_pPDFPage->ParseContent(nullptr);

-

-  return TRUE;

-}

-

-FX_FLOAT CPDFXFA_Page::GetPageWidth() {

-  ASSERT(m_pDocument != NULL);

-

-  if (!m_pPDFPage && !m_pXFAPageView)

-    return 0.0f;

-

-  int nDocType = m_pDocument->GetDocType();

-  switch (nDocType) {

-    case DOCTYPE_DYNAMIC_XFA: {

-      if (m_pXFAPageView) {

-        CFX_RectF rect;

-        m_pXFAPageView->GetPageViewRect(rect);

-        return rect.width;

-      }

-    } break;

-    case DOCTYPE_STATIC_XFA:

-    case DOCTYPE_PDF: {

-      if (m_pPDFPage)

-        return m_pPDFPage->GetPageWidth();

-    } break;

-    default:

-      return 0.0f;

-  }

-

-  return 0.0f;

-}

-

-FX_FLOAT CPDFXFA_Page::GetPageHeight() {

-  ASSERT(m_pDocument != NULL);

-

-  if (!m_pPDFPage && !m_pXFAPageView)

-    return 0.0f;

-

-  int nDocType = m_pDocument->GetDocType();

-  switch (nDocType) {

-    case DOCTYPE_PDF:

-    case DOCTYPE_STATIC_XFA: {

-      if (m_pPDFPage)

-        return m_pPDFPage->GetPageHeight();

-    } break;

-    case DOCTYPE_DYNAMIC_XFA: {

-      if (m_pXFAPageView) {

-        CFX_RectF rect;

-        m_pXFAPageView->GetPageViewRect(rect);

-        return rect.height;

-      }

-    } break;

-    default:

-      return 0.0f;

-  }

-

-  return 0.0f;

-}

-

-void CPDFXFA_Page::DeviceToPage(int start_x,

-                                int start_y,

-                                int size_x,

-                                int size_y,

-                                int rotate,

-                                int device_x,

-                                int device_y,

-                                double* page_x,

-                                double* page_y) {

-  ASSERT(m_pDocument != NULL);

-

-  if (!m_pPDFPage && !m_pXFAPageView)

-    return;

-

-  CFX_Matrix page2device;

-  CFX_Matrix device2page;

-  FX_FLOAT page_x_f, page_y_f;

-

-  GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);

-

-  device2page.SetReverse(page2device);

-  device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f,

-                        page_y_f);

-

-  *page_x = (page_x_f);

-  *page_y = (page_y_f);

-}

-

-void CPDFXFA_Page::PageToDevice(int start_x,

-                                int start_y,

-                                int size_x,

-                                int size_y,

-                                int rotate,

-                                double page_x,

-                                double page_y,

-                                int* device_x,

-                                int* device_y) {

-  if (!m_pPDFPage && !m_pXFAPageView)

-    return;

-

-  CFX_Matrix page2device;

-  FX_FLOAT device_x_f, device_y_f;

-

-  GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);

-

-  page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f,

-                        device_y_f);

-

-  *device_x = FXSYS_round(device_x_f);

-  *device_y = FXSYS_round(device_y_f);

-}

-

-void CPDFXFA_Page::GetDisplayMatrix(CFX_Matrix& matrix,

-                                    int xPos,

-                                    int yPos,

-                                    int xSize,

-                                    int ySize,

-                                    int iRotate) const {

-  ASSERT(m_pDocument != NULL);

-

-  if (!m_pPDFPage && !m_pXFAPageView)

-    return;

-

-  int nDocType = m_pDocument->GetDocType();

-  switch (nDocType) {

-    case DOCTYPE_DYNAMIC_XFA: {

-      if (m_pXFAPageView) {

-        CFX_Rect rect;

-        rect.Set(xPos, yPos, xSize, ySize);

-        m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate);

-      }

-    } break;

-    case DOCTYPE_PDF:

-    case DOCTYPE_STATIC_XFA: {

-      if (m_pPDFPage) {

-        m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate);

-      }

-    } break;

-    default:

-      return;

-  }

-}

+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/include/fsdk_define.h"
+#include "fpdfsdk/include/fsdk_mgr.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
+
+CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index)
+    : m_pPDFPage(NULL),
+      m_pXFAPageView(NULL),
+      m_iPageIndex(page_index),
+      m_pDocument(pDoc),
+      m_iRef(1) {}
+
+CPDFXFA_Page::~CPDFXFA_Page() {
+  if (m_pPDFPage)
+    delete m_pPDFPage;
+  m_pPDFPage = NULL;
+  m_pXFAPageView = NULL;
+}
+
+void CPDFXFA_Page::Release() {
+  m_iRef--;
+  if (m_iRef > 0)
+    return;
+
+  if (m_pDocument)
+    m_pDocument->RemovePage(this);
+
+  delete this;
+}
+
+FX_BOOL CPDFXFA_Page::LoadPDFPage() {
+  if (!m_pDocument)
+    return FALSE;
+  CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc();
+  if (pPDFDoc) {
+    CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex);
+    if (pDict == NULL)
+      return FALSE;
+    if (m_pPDFPage) {
+      if (m_pPDFPage->m_pFormDict == pDict)
+        return TRUE;
+
+      delete m_pPDFPage;
+      m_pPDFPage = NULL;
+    }
+
+    m_pPDFPage = new CPDF_Page;
+    m_pPDFPage->Load(pPDFDoc, pDict);
+    m_pPDFPage->ParseContent(nullptr);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+FX_BOOL CPDFXFA_Page::LoadXFAPageView() {
+  if (!m_pDocument)
+    return FALSE;
+  IXFA_Doc* pXFADoc = m_pDocument->GetXFADoc();
+  if (!pXFADoc)
+    return FALSE;
+
+  IXFA_DocView* pXFADocView = m_pDocument->GetXFADocView();
+  if (!pXFADocView)
+    return FALSE;
+
+  IXFA_PageView* pPageView = pXFADocView->GetPageView(m_iPageIndex);
+  if (!pPageView)
+    return FALSE;
+
+  if (m_pXFAPageView == pPageView)
+    return TRUE;
+
+  m_pXFAPageView = pPageView;
+  (void)m_pXFAPageView->LoadPageView(nullptr);
+  return TRUE;
+}
+
+FX_BOOL CPDFXFA_Page::LoadPage() {
+  if (!m_pDocument || m_iPageIndex < 0)
+    return FALSE;
+
+  int iDocType = m_pDocument->GetDocType();
+  switch (iDocType) {
+    case DOCTYPE_PDF:
+    case DOCTYPE_STATIC_XFA: {
+      return LoadPDFPage();
+    }
+    case DOCTYPE_DYNAMIC_XFA: {
+      return LoadXFAPageView();
+    }
+    default:
+      return FALSE;
+  }
+
+  return FALSE;
+}
+
+FX_BOOL CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) {
+  if (!m_pDocument || m_iPageIndex < 0 || !pageDict)
+    return FALSE;
+
+  if (m_pPDFPage)
+    delete m_pPDFPage;
+
+  m_pPDFPage = new CPDF_Page();
+  m_pPDFPage->Load(m_pDocument->GetPDFDoc(), pageDict);
+  m_pPDFPage->ParseContent(nullptr);
+
+  return TRUE;
+}
+
+FX_FLOAT CPDFXFA_Page::GetPageWidth() {
+  ASSERT(m_pDocument != NULL);
+
+  if (!m_pPDFPage && !m_pXFAPageView)
+    return 0.0f;
+
+  int nDocType = m_pDocument->GetDocType();
+  switch (nDocType) {
+    case DOCTYPE_DYNAMIC_XFA: {
+      if (m_pXFAPageView) {
+        CFX_RectF rect;
+        m_pXFAPageView->GetPageViewRect(rect);
+        return rect.width;
+      }
+    } break;
+    case DOCTYPE_STATIC_XFA:
+    case DOCTYPE_PDF: {
+      if (m_pPDFPage)
+        return m_pPDFPage->GetPageWidth();
+    } break;
+    default:
+      return 0.0f;
+  }
+
+  return 0.0f;
+}
+
+FX_FLOAT CPDFXFA_Page::GetPageHeight() {
+  ASSERT(m_pDocument != NULL);
+
+  if (!m_pPDFPage && !m_pXFAPageView)
+    return 0.0f;
+
+  int nDocType = m_pDocument->GetDocType();
+  switch (nDocType) {
+    case DOCTYPE_PDF:
+    case DOCTYPE_STATIC_XFA: {
+      if (m_pPDFPage)
+        return m_pPDFPage->GetPageHeight();
+    } break;
+    case DOCTYPE_DYNAMIC_XFA: {
+      if (m_pXFAPageView) {
+        CFX_RectF rect;
+        m_pXFAPageView->GetPageViewRect(rect);
+        return rect.height;
+      }
+    } break;
+    default:
+      return 0.0f;
+  }
+
+  return 0.0f;
+}
+
+void CPDFXFA_Page::DeviceToPage(int start_x,
+                                int start_y,
+                                int size_x,
+                                int size_y,
+                                int rotate,
+                                int device_x,
+                                int device_y,
+                                double* page_x,
+                                double* page_y) {
+  ASSERT(m_pDocument != NULL);
+
+  if (!m_pPDFPage && !m_pXFAPageView)
+    return;
+
+  CFX_Matrix page2device;
+  CFX_Matrix device2page;
+  FX_FLOAT page_x_f, page_y_f;
+
+  GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
+
+  device2page.SetReverse(page2device);
+  device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f,
+                        page_y_f);
+
+  *page_x = (page_x_f);
+  *page_y = (page_y_f);
+}
+
+void CPDFXFA_Page::PageToDevice(int start_x,
+                                int start_y,
+                                int size_x,
+                                int size_y,
+                                int rotate,
+                                double page_x,
+                                double page_y,
+                                int* device_x,
+                                int* device_y) {
+  if (!m_pPDFPage && !m_pXFAPageView)
+    return;
+
+  CFX_Matrix page2device;
+  FX_FLOAT device_x_f, device_y_f;
+
+  GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
+
+  page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f,
+                        device_y_f);
+
+  *device_x = FXSYS_round(device_x_f);
+  *device_y = FXSYS_round(device_y_f);
+}
+
+void CPDFXFA_Page::GetDisplayMatrix(CFX_Matrix& matrix,
+                                    int xPos,
+                                    int yPos,
+                                    int xSize,
+                                    int ySize,
+                                    int iRotate) const {
+  ASSERT(m_pDocument != NULL);
+
+  if (!m_pPDFPage && !m_pXFAPageView)
+    return;
+
+  int nDocType = m_pDocument->GetDocType();
+  switch (nDocType) {
+    case DOCTYPE_DYNAMIC_XFA: {
+      if (m_pXFAPageView) {
+        CFX_Rect rect;
+        rect.Set(xPos, yPos, xSize, ySize);
+        m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate);
+      }
+    } break;
+    case DOCTYPE_PDF:
+    case DOCTYPE_STATIC_XFA: {
+      if (m_pPDFPage) {
+        m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate);
+      }
+    } break;
+    default:
+      return;
+  }
+}
diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp
index dc1cf9b..5f8a9f0 100644
--- a/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp
+++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp
@@ -1,65 +1,65 @@
-// Copyright 2014 PDFium Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-

-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

-

-#include "fpdfsdk/include/fsdk_define.h"

-#include "fpdfsdk/include/fsdk_mgr.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"

-

-CFX_PtrArray CXFA_FWLAdapterTimerMgr::ms_timerArray;

-

-FWL_ERR CXFA_FWLAdapterTimerMgr::Start(IFWL_Timer* pTimer,

-                                       FX_DWORD dwElapse,

-                                       FWL_HTIMER& hTimer,

-                                       FX_BOOL bImmediately /* = TRUE */) {

-  if (m_pEnv) {

-    uint32_t uIDEvent = m_pEnv->FFI_SetTimer(dwElapse, TimerProc);

-    CFWL_TimerInfo* pInfo = new CFWL_TimerInfo;

-    pInfo->uIDEvent = uIDEvent;

-    pInfo->pTimer = pTimer;

-    ms_timerArray.Add(pInfo);

-

-    hTimer = (FWL_HTIMER)pInfo;

-    return FWL_ERR_Succeeded;

-  }

-

-  return FWL_ERR_Indefinite;

-}

-

-FWL_ERR CXFA_FWLAdapterTimerMgr::Stop(FWL_HTIMER hTimer) {

-  if (!hTimer)

-    return FWL_ERR_Indefinite;

-

-  if (m_pEnv) {

-    CFWL_TimerInfo* pInfo = (CFWL_TimerInfo*)hTimer;

-

-    m_pEnv->FFI_KillTimer(pInfo->uIDEvent);

-

-    int32_t index = ms_timerArray.Find(pInfo);

-    if (index >= 0) {

-      ms_timerArray.RemoveAt(index);

-      delete pInfo;

-    }

-    return FWL_ERR_Succeeded;

-  }

-

-  return FWL_ERR_Indefinite;

-}

-

-void CXFA_FWLAdapterTimerMgr::TimerProc(int32_t idEvent) {

-  CFWL_TimerInfo* pInfo = NULL;

-  int32_t iCount = CXFA_FWLAdapterTimerMgr::ms_timerArray.GetSize();

-  for (int32_t i = 0; i < iCount; i++) {

-    CFWL_TimerInfo* pTemp =

-        (CFWL_TimerInfo*)CXFA_FWLAdapterTimerMgr::ms_timerArray.GetAt(i);

-    if (pTemp->uIDEvent == idEvent) {

-      pInfo = pTemp;

-      break;

-    }

-  }

-  if (pInfo) {

-    pInfo->pTimer->Run((FWL_HTIMER)pInfo);

-  }

-}

+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/include/fsdk_define.h"
+#include "fpdfsdk/include/fsdk_mgr.h"
+#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
+
+CFX_PtrArray CXFA_FWLAdapterTimerMgr::ms_timerArray;
+
+FWL_ERR CXFA_FWLAdapterTimerMgr::Start(IFWL_Timer* pTimer,
+                                       FX_DWORD dwElapse,
+                                       FWL_HTIMER& hTimer,
+                                       FX_BOOL bImmediately /* = TRUE */) {
+  if (m_pEnv) {
+    uint32_t uIDEvent = m_pEnv->FFI_SetTimer(dwElapse, TimerProc);
+    CFWL_TimerInfo* pInfo = new CFWL_TimerInfo;
+    pInfo->uIDEvent = uIDEvent;
+    pInfo->pTimer = pTimer;
+    ms_timerArray.Add(pInfo);
+
+    hTimer = (FWL_HTIMER)pInfo;
+    return FWL_ERR_Succeeded;
+  }
+
+  return FWL_ERR_Indefinite;
+}
+
+FWL_ERR CXFA_FWLAdapterTimerMgr::Stop(FWL_HTIMER hTimer) {
+  if (!hTimer)
+    return FWL_ERR_Indefinite;
+
+  if (m_pEnv) {
+    CFWL_TimerInfo* pInfo = (CFWL_TimerInfo*)hTimer;
+
+    m_pEnv->FFI_KillTimer(pInfo->uIDEvent);
+
+    int32_t index = ms_timerArray.Find(pInfo);
+    if (index >= 0) {
+      ms_timerArray.RemoveAt(index);
+      delete pInfo;
+    }
+    return FWL_ERR_Succeeded;
+  }
+
+  return FWL_ERR_Indefinite;
+}
+
+void CXFA_FWLAdapterTimerMgr::TimerProc(int32_t idEvent) {
+  CFWL_TimerInfo* pInfo = NULL;
+  int32_t iCount = CXFA_FWLAdapterTimerMgr::ms_timerArray.GetSize();
+  for (int32_t i = 0; i < iCount; i++) {
+    CFWL_TimerInfo* pTemp =
+        (CFWL_TimerInfo*)CXFA_FWLAdapterTimerMgr::ms_timerArray.GetAt(i);
+    if (pTemp->uIDEvent == idEvent) {
+      pInfo = pTemp;
+      break;
+    }
+  }
+  if (pInfo) {
+    pInfo->pTimer->Run((FWL_HTIMER)pInfo);
+  }
+}