Move JpegModule::ProgressiveDecoder into its own file.

Rename JpegModule::ProgressiveDecoder to JpegProgressiveDecoder. Also
add a separate header to share the common bits between JpegModule and
JpegProgressiveDecoder.

Change-Id: Ia1c43e52ee66839f807c081861d0aa9692b1b6c6
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/69931
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcodec/BUILD.gn b/core/fxcodec/BUILD.gn
index db8ff37..99122f1 100644
--- a/core/fxcodec/BUILD.gn
+++ b/core/fxcodec/BUILD.gn
@@ -58,6 +58,8 @@
     "jbig2/JBig2_TrdProc.h",
     "jbig2/jbig2module.cpp",
     "jbig2/jbig2module.h",
+    "jpeg/jpeg_common.cpp",
+    "jpeg/jpeg_common.h",
     "jpeg/jpegmodule.cpp",
     "jpeg/jpegmodule.h",
     "jpx/cjpx_decoder.cpp",
@@ -80,6 +82,8 @@
 
   if (pdf_enable_xfa) {
     sources += [
+      "jpeg/jpeg_progressive_decoder.cpp",
+      "jpeg/jpeg_progressive_decoder.h",
       "progressive_decoder_iface.h",
       "progressivedecoder.cpp",
       "progressivedecoder.h",
diff --git a/core/fxcodec/jpeg/jpeg_common.cpp b/core/fxcodec/jpeg/jpeg_common.cpp
new file mode 100644
index 0000000..bbe2dce
--- /dev/null
+++ b/core/fxcodec/jpeg/jpeg_common.cpp
@@ -0,0 +1,27 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fxcodec/jpeg/jpeg_common.h"
+
+extern "C" {
+
+void src_do_nothing(jpeg_decompress_struct* cinfo) {}
+
+boolean src_fill_buffer(j_decompress_ptr cinfo) {
+  return FALSE;
+}
+
+boolean src_resync(j_decompress_ptr cinfo, int desired) {
+  return FALSE;
+}
+
+void error_do_nothing(j_common_ptr cinfo) {}
+
+void error_do_nothing_int(j_common_ptr cinfo, int) {}
+
+void error_do_nothing_char(j_common_ptr cinfo, char*) {}
+
+}  // extern "C"
diff --git a/core/fxcodec/jpeg/jpeg_common.h b/core/fxcodec/jpeg/jpeg_common.h
new file mode 100644
index 0000000..a56e4e9
--- /dev/null
+++ b/core/fxcodec/jpeg/jpeg_common.h
@@ -0,0 +1,38 @@
+// Copyright 2020 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 CORE_FXCODEC_JPEG_JPEG_COMMON_H_
+#define CORE_FXCODEC_JPEG_JPEG_COMMON_H_
+
+// Common code for interacting with libjpeg shared by other files in
+// core/fxcodec/jpeg/. Not intended to be included in headers.
+
+#include <stdio.h>
+
+extern "C" {
+
+#undef FAR
+#if defined(USE_SYSTEM_LIBJPEG)
+#include <jerror.h>
+#include <jpeglib.h>
+#elif defined(USE_LIBJPEG_TURBO)
+#include "third_party/libjpeg_turbo/jerror.h"
+#include "third_party/libjpeg_turbo/jpeglib.h"
+#else
+#include "third_party/libjpeg/jerror.h"
+#include "third_party/libjpeg/jpeglib.h"
+#endif
+
+void src_do_nothing(jpeg_decompress_struct* cinfo);
+boolean src_fill_buffer(j_decompress_ptr cinfo);
+boolean src_resync(j_decompress_ptr cinfo, int desired);
+void error_do_nothing(j_common_ptr cinfo);
+void error_do_nothing_int(j_common_ptr cinfo, int);
+void error_do_nothing_char(j_common_ptr cinfo, char*);
+
+}  // extern "C"
+
+#endif  // CORE_FXCODEC_JPEG_JPEG_COMMON_H_
diff --git a/core/fxcodec/jpeg/jpeg_progressive_decoder.cpp b/core/fxcodec/jpeg/jpeg_progressive_decoder.cpp
new file mode 100644
index 0000000..1dd466a
--- /dev/null
+++ b/core/fxcodec/jpeg/jpeg_progressive_decoder.cpp
@@ -0,0 +1,190 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fxcodec/jpeg/jpeg_progressive_decoder.h"
+
+#include <utility>
+
+#include "core/fxcodec/cfx_codec_memory.h"
+#include "core/fxcodec/fx_codec.h"
+#include "core/fxcodec/jpeg/jpeg_common.h"
+#include "core/fxcodec/scanlinedecoder.h"
+#include "core/fxcrt/fx_memory_wrappers.h"
+#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxge/dib/cfx_dibbase.h"
+#include "core/fxge/fx_dib.h"
+#include "third_party/base/logging.h"
+#include "third_party/base/optional.h"
+#include "third_party/base/ptr_util.h"
+
+class CJpegContext final : public ProgressiveDecoderIface::Context {
+ public:
+  CJpegContext();
+  ~CJpegContext() override;
+
+  jmp_buf& GetJumpMark() { return m_JumpMark; }
+
+  jmp_buf m_JumpMark;
+  jpeg_decompress_struct m_Info = {};
+  jpeg_error_mgr m_ErrMgr = {};
+  jpeg_source_mgr m_SrcMgr = {};
+  unsigned int m_SkipSize = 0;
+  void* (*m_AllocFunc)(unsigned int);
+  void (*m_FreeFunc)(void*);
+};
+
+extern "C" {
+
+static void error_fatal(j_common_ptr cinfo) {
+  auto* pContext = reinterpret_cast<CJpegContext*>(cinfo->client_data);
+  longjmp(pContext->m_JumpMark, -1);
+}
+
+static void src_skip_data(jpeg_decompress_struct* cinfo, long num) {
+  if (cinfo->src->bytes_in_buffer < static_cast<size_t>(num)) {
+    auto* pContext = reinterpret_cast<CJpegContext*>(cinfo->client_data);
+    pContext->m_SkipSize = (unsigned int)(num - cinfo->src->bytes_in_buffer);
+    cinfo->src->bytes_in_buffer = 0;
+  } else {
+    cinfo->src->next_input_byte += num;
+    cinfo->src->bytes_in_buffer -= num;
+  }
+}
+
+static void* jpeg_alloc_func(unsigned int size) {
+  return FX_Alloc(char, size);
+}
+
+static void jpeg_free_func(void* p) {
+  FX_Free(p);
+}
+
+}  // extern "C"
+
+static void JpegLoadAttribute(const jpeg_decompress_struct& info,
+                              CFX_DIBAttribute* pAttribute) {
+  pAttribute->m_nXDPI = info.X_density;
+  pAttribute->m_nYDPI = info.Y_density;
+  pAttribute->m_wDPIUnit = info.density_unit;
+}
+
+CJpegContext::CJpegContext()
+    : m_AllocFunc(jpeg_alloc_func), m_FreeFunc(jpeg_free_func) {
+  m_Info.client_data = this;
+  m_Info.err = &m_ErrMgr;
+
+  m_ErrMgr.error_exit = error_fatal;
+  m_ErrMgr.emit_message = error_do_nothing_int;
+  m_ErrMgr.output_message = error_do_nothing;
+  m_ErrMgr.format_message = error_do_nothing_char;
+  m_ErrMgr.reset_error_mgr = error_do_nothing;
+
+  m_SrcMgr.init_source = src_do_nothing;
+  m_SrcMgr.term_source = src_do_nothing;
+  m_SrcMgr.skip_input_data = src_skip_data;
+  m_SrcMgr.fill_input_buffer = src_fill_buffer;
+  m_SrcMgr.resync_to_restart = src_resync;
+}
+
+CJpegContext::~CJpegContext() {
+  jpeg_destroy_decompress(&m_Info);
+}
+
+namespace fxcodec {
+
+// static
+JpegProgressiveDecoder* JpegProgressiveDecoder::GetInstance() {
+  static pdfium::base::NoDestructor<JpegProgressiveDecoder> s;
+  return s.get();
+}
+
+// static
+std::unique_ptr<ProgressiveDecoderIface::Context>
+JpegProgressiveDecoder::Start() {
+  // Use ordinary pointer until past the possibility of a longjump.
+  auto* pContext = new CJpegContext();
+  if (setjmp(pContext->m_JumpMark) == -1) {
+    delete pContext;
+    return nullptr;
+  }
+
+  jpeg_create_decompress(&pContext->m_Info);
+  pContext->m_Info.src = &pContext->m_SrcMgr;
+  pContext->m_SkipSize = 0;
+  return pdfium::WrapUnique(pContext);
+}
+
+// static
+jmp_buf& JpegProgressiveDecoder::GetJumpMark(Context* pContext) {
+  return static_cast<CJpegContext*>(pContext)->GetJumpMark();
+}
+
+// static
+int JpegProgressiveDecoder::ReadHeader(Context* pContext,
+                                       int* width,
+                                       int* height,
+                                       int* nComps,
+                                       CFX_DIBAttribute* pAttribute) {
+  ASSERT(pAttribute);
+
+  auto* ctx = static_cast<CJpegContext*>(pContext);
+  int ret = jpeg_read_header(&ctx->m_Info, TRUE);
+  if (ret == JPEG_SUSPENDED)
+    return 2;
+  if (ret != JPEG_HEADER_OK)
+    return 1;
+
+  *width = ctx->m_Info.image_width;
+  *height = ctx->m_Info.image_height;
+  *nComps = ctx->m_Info.num_components;
+  JpegLoadAttribute(ctx->m_Info, pAttribute);
+  return 0;
+}
+
+// static
+bool JpegProgressiveDecoder::StartScanline(Context* pContext, int down_scale) {
+  auto* ctx = static_cast<CJpegContext*>(pContext);
+  ctx->m_Info.scale_denom = static_cast<unsigned int>(down_scale);
+  return !!jpeg_start_decompress(&ctx->m_Info);
+}
+
+// static
+bool JpegProgressiveDecoder::ReadScanline(Context* pContext,
+                                          unsigned char* dest_buf) {
+  auto* ctx = static_cast<CJpegContext*>(pContext);
+  unsigned int nlines = jpeg_read_scanlines(&ctx->m_Info, &dest_buf, 1);
+  return nlines == 1;
+}
+
+FX_FILESIZE JpegProgressiveDecoder::GetAvailInput(Context* pContext) const {
+  auto* ctx = static_cast<CJpegContext*>(pContext);
+  return static_cast<FX_FILESIZE>(ctx->m_SrcMgr.bytes_in_buffer);
+}
+
+bool JpegProgressiveDecoder::Input(Context* pContext,
+                                   RetainPtr<CFX_CodecMemory> codec_memory,
+                                   CFX_DIBAttribute*) {
+  pdfium::span<uint8_t> src_buf = codec_memory->GetSpan();
+  auto* ctx = static_cast<CJpegContext*>(pContext);
+  if (ctx->m_SkipSize) {
+    if (ctx->m_SkipSize > src_buf.size()) {
+      ctx->m_SrcMgr.bytes_in_buffer = 0;
+      ctx->m_SkipSize -= src_buf.size();
+      return true;
+    }
+    src_buf = src_buf.subspan(ctx->m_SkipSize);
+    ctx->m_SkipSize = 0;
+  }
+  ctx->m_SrcMgr.next_input_byte = src_buf.data();
+  ctx->m_SrcMgr.bytes_in_buffer = src_buf.size();
+  return true;
+}
+
+JpegProgressiveDecoder::JpegProgressiveDecoder() = default;
+
+JpegProgressiveDecoder::~JpegProgressiveDecoder() = default;
+
+}  // namespace fxcodec
diff --git a/core/fxcodec/jpeg/jpeg_progressive_decoder.h b/core/fxcodec/jpeg/jpeg_progressive_decoder.h
new file mode 100644
index 0000000..f1573d3
--- /dev/null
+++ b/core/fxcodec/jpeg/jpeg_progressive_decoder.h
@@ -0,0 +1,54 @@
+// Copyright 2020 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 CORE_FXCODEC_JPEG_JPEG_PROGRESSIVE_DECODER_H_
+#define CORE_FXCODEC_JPEG_JPEG_PROGRESSIVE_DECODER_H_
+
+#include <csetjmp>
+#include <memory>
+
+#include "core/fxcodec/progressive_decoder_iface.h"
+#include "third_party/base/no_destructor.h"
+
+namespace fxcodec {
+
+class CFX_DIBAttribute;
+
+class JpegProgressiveDecoder final : public ProgressiveDecoderIface {
+ public:
+  static JpegProgressiveDecoder* GetInstance();
+
+  static std::unique_ptr<Context> Start();
+
+  static jmp_buf& GetJumpMark(Context* pContext);
+
+  static int ReadHeader(Context* pContext,
+                        int* width,
+                        int* height,
+                        int* nComps,
+                        CFX_DIBAttribute* pAttribute);
+
+  static bool StartScanline(Context* pContext, int down_scale);
+  static bool ReadScanline(Context* pContext, uint8_t* dest_buf);
+
+  // ProgressiveDecoderIface:
+  FX_FILESIZE GetAvailInput(Context* pContext) const override;
+  bool Input(Context* pContext,
+             RetainPtr<CFX_CodecMemory> codec_memory,
+             CFX_DIBAttribute* pAttribute) override;
+
+ private:
+  friend pdfium::base::NoDestructor<JpegProgressiveDecoder>;
+
+  JpegProgressiveDecoder();
+  ~JpegProgressiveDecoder() override;
+};
+
+}  // namespace fxcodec
+
+using JpegProgressiveDecoder = fxcodec::JpegProgressiveDecoder;
+
+#endif  // CORE_FXCODEC_JPEG_JPEG_PROGRESSIVE_DECODER_H_
diff --git a/core/fxcodec/jpeg/jpegmodule.cpp b/core/fxcodec/jpeg/jpegmodule.cpp
index 634dbbf..8724500 100644
--- a/core/fxcodec/jpeg/jpegmodule.cpp
+++ b/core/fxcodec/jpeg/jpegmodule.cpp
@@ -14,6 +14,7 @@
 #include "build/build_config.h"
 #include "core/fxcodec/cfx_codec_memory.h"
 #include "core/fxcodec/fx_codec.h"
+#include "core/fxcodec/jpeg/jpeg_common.h"
 #include "core/fxcodec/scanlinedecoder.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/fx_safe_types.h"
@@ -23,42 +24,6 @@
 #include "third_party/base/optional.h"
 #include "third_party/base/ptr_util.h"
 
-extern "C" {
-#undef FAR
-#if defined(USE_SYSTEM_LIBJPEG)
-#include <jerror.h>
-#include <jpeglib.h>
-#elif defined(USE_LIBJPEG_TURBO)
-#include "third_party/libjpeg_turbo/jerror.h"
-#include "third_party/libjpeg_turbo/jpeglib.h"
-#else
-#include "third_party/libjpeg/jerror.h"
-#include "third_party/libjpeg/jpeglib.h"
-#endif
-}  // extern "C"
-
-#ifdef PDF_ENABLE_XFA
-#include "third_party/base/no_destructor.h"
-#endif
-
-#ifdef PDF_ENABLE_XFA
-class CJpegContext final : public ProgressiveDecoderIface::Context {
- public:
-  CJpegContext();
-  ~CJpegContext() override;
-
-  jmp_buf& GetJumpMark() { return m_JumpMark; }
-
-  jmp_buf m_JumpMark;
-  jpeg_decompress_struct m_Info = {};
-  jpeg_error_mgr m_ErrMgr = {};
-  jpeg_source_mgr m_SrcMgr = {};
-  unsigned int m_SkipSize = 0;
-  void* (*m_AllocFunc)(unsigned int);
-  void (*m_FreeFunc)(void*);
-};
-#endif
-
 static pdfium::span<const uint8_t> JpegScanSOI(
     pdfium::span<const uint8_t> src_span) {
   ASSERT(!src_span.empty());
@@ -72,8 +37,6 @@
 
 extern "C" {
 
-static void src_do_nothing(jpeg_decompress_struct* cinfo) {}
-
 static void error_fatal(j_common_ptr cinfo) {
   longjmp(*(jmp_buf*)cinfo->client_data, -1);
 }
@@ -86,20 +49,6 @@
   cinfo->src->bytes_in_buffer -= num;
 }
 
-static boolean src_fill_buffer(j_decompress_ptr cinfo) {
-  return FALSE;
-}
-
-static boolean src_resync(j_decompress_ptr cinfo, int desired) {
-  return FALSE;
-}
-
-static void error_do_nothing(j_common_ptr cinfo) {}
-
-static void error_do_nothing1(j_common_ptr cinfo, int) {}
-
-static void error_do_nothing2(j_common_ptr cinfo, char*) {}
-
 #if defined(OS_WIN)
 static void dest_do_nothing(j_compress_ptr cinfo) {}
 
@@ -108,43 +57,8 @@
 }
 #endif  // defined(OS_WIN)
 
-#ifdef PDF_ENABLE_XFA
-static void error_fatal1(j_common_ptr cinfo) {
-  auto* pContext = reinterpret_cast<CJpegContext*>(cinfo->client_data);
-  longjmp(pContext->m_JumpMark, -1);
-}
-
-static void src_skip_data1(jpeg_decompress_struct* cinfo, long num) {
-  if (cinfo->src->bytes_in_buffer < static_cast<size_t>(num)) {
-    auto* pContext = reinterpret_cast<CJpegContext*>(cinfo->client_data);
-    pContext->m_SkipSize = (unsigned int)(num - cinfo->src->bytes_in_buffer);
-    cinfo->src->bytes_in_buffer = 0;
-  } else {
-    cinfo->src->next_input_byte += num;
-    cinfo->src->bytes_in_buffer -= num;
-  }
-}
-
-static void* jpeg_alloc_func(unsigned int size) {
-  return FX_Alloc(char, size);
-}
-
-static void jpeg_free_func(void* p) {
-  FX_Free(p);
-}
-#endif
-
 }  // extern "C"
 
-#ifdef PDF_ENABLE_XFA
-static void JpegLoadAttribute(const jpeg_decompress_struct& info,
-                              CFX_DIBAttribute* pAttribute) {
-  pAttribute->m_nXDPI = info.X_density;
-  pAttribute->m_nYDPI = info.Y_density;
-  pAttribute->m_wDPIUnit = info.density_unit;
-}
-#endif  // PDF_ENABLE_XFA
-
 static bool JpegLoadInfo(pdfium::span<const uint8_t> src_span,
                          int* width,
                          int* height,
@@ -155,9 +69,9 @@
   jpeg_decompress_struct cinfo;
   jpeg_error_mgr jerr;
   jerr.error_exit = error_fatal;
-  jerr.emit_message = error_do_nothing1;
+  jerr.emit_message = error_do_nothing_int;
   jerr.output_message = error_do_nothing;
-  jerr.format_message = error_do_nothing2;
+  jerr.format_message = error_do_nothing_char;
   jerr.reset_error_mgr = error_do_nothing;
   jerr.trace_level = 0;
   cinfo.err = &jerr;
@@ -195,30 +109,6 @@
   return true;
 }
 
-#ifdef PDF_ENABLE_XFA
-CJpegContext::CJpegContext()
-    : m_AllocFunc(jpeg_alloc_func), m_FreeFunc(jpeg_free_func) {
-  m_Info.client_data = this;
-  m_Info.err = &m_ErrMgr;
-
-  m_ErrMgr.error_exit = error_fatal1;
-  m_ErrMgr.emit_message = error_do_nothing1;
-  m_ErrMgr.output_message = error_do_nothing;
-  m_ErrMgr.format_message = error_do_nothing2;
-  m_ErrMgr.reset_error_mgr = error_do_nothing;
-
-  m_SrcMgr.init_source = src_do_nothing;
-  m_SrcMgr.term_source = src_do_nothing;
-  m_SrcMgr.skip_input_data = src_skip_data1;
-  m_SrcMgr.fill_input_buffer = src_fill_buffer;
-  m_SrcMgr.resync_to_restart = src_resync;
-}
-
-CJpegContext::~CJpegContext() {
-  jpeg_destroy_decompress(&m_Info);
-}
-#endif
-
 namespace fxcodec {
 
 namespace {
@@ -353,9 +243,9 @@
   PatchUpTrailer();
 
   m_Jerr.error_exit = error_fatal;
-  m_Jerr.emit_message = error_do_nothing1;
+  m_Jerr.emit_message = error_do_nothing_int;
   m_Jerr.output_message = error_do_nothing;
-  m_Jerr.format_message = error_do_nothing2;
+  m_Jerr.format_message = error_do_nothing_char;
   m_Jerr.reset_error_mgr = error_do_nothing;
   m_Src.init_source = src_do_nothing;
   m_Src.term_source = src_do_nothing;
@@ -514,110 +404,15 @@
   return info;
 }
 
-#ifdef PDF_ENABLE_XFA
-// static
-JpegModule::ProgressiveDecoder* JpegModule::ProgressiveDecoder::GetInstance() {
-  static pdfium::base::NoDestructor<JpegModule::ProgressiveDecoder> s;
-  return s.get();
-}
-
-// static
-std::unique_ptr<ProgressiveDecoderIface::Context>
-JpegModule::ProgressiveDecoder::Start() {
-  // Use ordinary pointer until past the possibility of a longjump.
-  auto* pContext = new CJpegContext();
-  if (setjmp(pContext->m_JumpMark) == -1) {
-    delete pContext;
-    return nullptr;
-  }
-
-  jpeg_create_decompress(&pContext->m_Info);
-  pContext->m_Info.src = &pContext->m_SrcMgr;
-  pContext->m_SkipSize = 0;
-  return pdfium::WrapUnique(pContext);
-}
-
-// static
-jmp_buf& JpegModule::ProgressiveDecoder::GetJumpMark(Context* pContext) {
-  return static_cast<CJpegContext*>(pContext)->GetJumpMark();
-}
-
-// static
-int JpegModule::ProgressiveDecoder::ReadHeader(Context* pContext,
-                                               int* width,
-                                               int* height,
-                                               int* nComps,
-                                               CFX_DIBAttribute* pAttribute) {
-  ASSERT(pAttribute);
-
-  auto* ctx = static_cast<CJpegContext*>(pContext);
-  int ret = jpeg_read_header(&ctx->m_Info, TRUE);
-  if (ret == JPEG_SUSPENDED)
-    return 2;
-  if (ret != JPEG_HEADER_OK)
-    return 1;
-
-  *width = ctx->m_Info.image_width;
-  *height = ctx->m_Info.image_height;
-  *nComps = ctx->m_Info.num_components;
-  JpegLoadAttribute(ctx->m_Info, pAttribute);
-  return 0;
-}
-
-// static
-bool JpegModule::ProgressiveDecoder::StartScanline(Context* pContext,
-                                                   int down_scale) {
-  auto* ctx = static_cast<CJpegContext*>(pContext);
-  ctx->m_Info.scale_denom = static_cast<unsigned int>(down_scale);
-  return !!jpeg_start_decompress(&ctx->m_Info);
-}
-
-// static
-bool JpegModule::ProgressiveDecoder::ReadScanline(Context* pContext,
-                                                  unsigned char* dest_buf) {
-  auto* ctx = static_cast<CJpegContext*>(pContext);
-  unsigned int nlines = jpeg_read_scanlines(&ctx->m_Info, &dest_buf, 1);
-  return nlines == 1;
-}
-
-JpegModule::ProgressiveDecoder::ProgressiveDecoder() = default;
-
-FX_FILESIZE JpegModule::ProgressiveDecoder::GetAvailInput(
-    Context* pContext) const {
-  auto* ctx = static_cast<CJpegContext*>(pContext);
-  return static_cast<FX_FILESIZE>(ctx->m_SrcMgr.bytes_in_buffer);
-}
-
-bool JpegModule::ProgressiveDecoder::Input(
-    Context* pContext,
-    RetainPtr<CFX_CodecMemory> codec_memory,
-    CFX_DIBAttribute*) {
-  pdfium::span<uint8_t> src_buf = codec_memory->GetSpan();
-  auto* ctx = static_cast<CJpegContext*>(pContext);
-  if (ctx->m_SkipSize) {
-    if (ctx->m_SkipSize > src_buf.size()) {
-      ctx->m_SrcMgr.bytes_in_buffer = 0;
-      ctx->m_SkipSize -= src_buf.size();
-      return true;
-    }
-    src_buf = src_buf.subspan(ctx->m_SkipSize);
-    ctx->m_SkipSize = 0;
-  }
-  ctx->m_SrcMgr.next_input_byte = src_buf.data();
-  ctx->m_SrcMgr.bytes_in_buffer = src_buf.size();
-  return true;
-}
-#endif  // PDF_ENABLE_XFA
-
 #if defined(OS_WIN)
 bool JpegModule::JpegEncode(const RetainPtr<CFX_DIBBase>& pSource,
                             uint8_t** dest_buf,
                             size_t* dest_size) {
   jpeg_error_mgr jerr;
   jerr.error_exit = error_do_nothing;
-  jerr.emit_message = error_do_nothing1;
+  jerr.emit_message = error_do_nothing_int;
   jerr.output_message = error_do_nothing;
-  jerr.format_message = error_do_nothing2;
+  jerr.format_message = error_do_nothing_char;
   jerr.reset_error_mgr = error_do_nothing;
 
   jpeg_compress_struct cinfo;
diff --git a/core/fxcodec/jpeg/jpegmodule.h b/core/fxcodec/jpeg/jpegmodule.h
index de970b3..98adbef 100644
--- a/core/fxcodec/jpeg/jpegmodule.h
+++ b/core/fxcodec/jpeg/jpegmodule.h
@@ -17,17 +17,10 @@
 #include "core/fxcrt/retain_ptr.h"
 #endif
 
-#ifdef PDF_ENABLE_XFA
-#include <csetjmp>
-
-#include "core/fxcodec/progressive_decoder_iface.h"
-#endif
-
 class CFX_DIBBase;
 
 namespace fxcodec {
 
-class CFX_DIBAttribute;
 class ScanlineDecoder;
 
 class JpegModule {
@@ -40,34 +33,6 @@
     bool color_transform;
   };
 
-#ifdef PDF_ENABLE_XFA
-  class ProgressiveDecoder final : public ProgressiveDecoderIface {
-   public:
-    static ProgressiveDecoder* GetInstance();
-
-    static std::unique_ptr<Context> Start();
-
-    static jmp_buf& GetJumpMark(Context* pContext);
-
-    static int ReadHeader(Context* pContext,
-                          int* width,
-                          int* height,
-                          int* nComps,
-                          CFX_DIBAttribute* pAttribute);
-
-    static bool StartScanline(Context* pContext, int down_scale);
-    static bool ReadScanline(Context* pContext, uint8_t* dest_buf);
-
-    ProgressiveDecoder();
-
-    // ProgressiveDecoderIface:
-    FX_FILESIZE GetAvailInput(Context* pContext) const override;
-    bool Input(Context* pContext,
-               RetainPtr<CFX_CodecMemory> codec_memory,
-               CFX_DIBAttribute* pAttribute) override;
-  };
-#endif  // PDF_ENABLE_XFA
-
   static std::unique_ptr<ScanlineDecoder> CreateDecoder(
       pdfium::span<const uint8_t> src_span,
       int width,
diff --git a/core/fxcodec/progressivedecoder.cpp b/core/fxcodec/progressivedecoder.cpp
index 5b890ad..87772b7 100644
--- a/core/fxcodec/progressivedecoder.cpp
+++ b/core/fxcodec/progressivedecoder.cpp
@@ -14,6 +14,7 @@
 #include "build/build_config.h"
 #include "core/fxcodec/cfx_codec_memory.h"
 #include "core/fxcodec/fx_codec.h"
+#include "core/fxcodec/jpeg/jpeg_progressive_decoder.h"
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxcrt/fx_stream.h"
 #include "core/fxge/dib/cfx_cmyk_to_srgb.h"
@@ -975,30 +976,29 @@
 #endif  // PDF_ENABLE_XFA_GIF
 
 bool ProgressiveDecoder::JpegReadMoreData(FXCODEC_STATUS* err_status) {
-  return ReadMoreData(JpegModule::ProgressiveDecoder::GetInstance(),
+  return ReadMoreData(JpegProgressiveDecoder::GetInstance(),
                       m_pJpegContext.get(), false, err_status);
 }
 
 bool ProgressiveDecoder::JpegDetectImageTypeInBuffer(
     CFX_DIBAttribute* pAttribute) {
-  m_pJpegContext = JpegModule::ProgressiveDecoder::Start();
+  m_pJpegContext = JpegProgressiveDecoder::Start();
   if (!m_pJpegContext) {
     m_status = FXCODEC_STATUS_ERR_MEMORY;
     return false;
   }
-  JpegModule::ProgressiveDecoder::GetInstance()->Input(m_pJpegContext.get(),
-                                                       m_pCodecMemory, nullptr);
+  JpegProgressiveDecoder::GetInstance()->Input(m_pJpegContext.get(),
+                                               m_pCodecMemory, nullptr);
 
   // Setting jump marker before calling ReadHeader, since a longjmp to
   // the marker indicates a fatal error.
-  if (setjmp(JpegModule::ProgressiveDecoder::GetJumpMark(
-          m_pJpegContext.get())) == -1) {
+  if (setjmp(JpegProgressiveDecoder::GetJumpMark(m_pJpegContext.get())) == -1) {
     m_pJpegContext.reset();
     m_status = FXCODEC_STATUS_ERR_FORMAT;
     return false;
   }
 
-  int32_t readResult = JpegModule::ProgressiveDecoder::ReadHeader(
+  int32_t readResult = JpegProgressiveDecoder::ReadHeader(
       m_pJpegContext.get(), &m_SrcWidth, &m_SrcHeight, &m_SrcComponents,
       pAttribute);
   while (readResult == 2) {
@@ -1007,7 +1007,7 @@
       m_status = error_status;
       return false;
     }
-    readResult = JpegModule::ProgressiveDecoder::ReadHeader(
+    readResult = JpegProgressiveDecoder::ReadHeader(
         m_pJpegContext.get(), &m_SrcWidth, &m_SrcHeight, &m_SrcComponents,
         pAttribute);
   }
@@ -1026,15 +1026,14 @@
   int down_scale = GetDownScale();
   // Setting jump marker before calling StartScanLine, since a longjmp to
   // the marker indicates a fatal error.
-  if (setjmp(JpegModule::ProgressiveDecoder::GetJumpMark(
-          m_pJpegContext.get())) == -1) {
+  if (setjmp(JpegProgressiveDecoder::GetJumpMark(m_pJpegContext.get())) == -1) {
     m_pJpegContext.reset();
     m_status = FXCODEC_STATUS_ERROR;
     return FXCODEC_STATUS_ERROR;
   }
 
-  bool startStatus = JpegModule::ProgressiveDecoder::StartScanline(
-      m_pJpegContext.get(), down_scale);
+  bool startStatus =
+      JpegProgressiveDecoder::StartScanline(m_pJpegContext.get(), down_scale);
   while (!startStatus) {
     FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
     if (!JpegReadMoreData(&error_status)) {
@@ -1044,8 +1043,8 @@
       return m_status;
     }
 
-    startStatus = JpegModule::ProgressiveDecoder::StartScanline(
-        m_pJpegContext.get(), down_scale);
+    startStatus =
+        JpegProgressiveDecoder::StartScanline(m_pJpegContext.get(), down_scale);
   }
   int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale;
   scanline_size = FxAlignToBoundary<4>(scanline_size * m_SrcComponents);
@@ -1072,16 +1071,15 @@
   // JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
   // Setting jump marker before calling ReadScanLine, since a longjmp to
   // the marker indicates a fatal error.
-  if (setjmp(JpegModule::ProgressiveDecoder::GetJumpMark(
-          m_pJpegContext.get())) == -1) {
+  if (setjmp(JpegProgressiveDecoder::GetJumpMark(m_pJpegContext.get())) == -1) {
     m_pJpegContext.reset();
     m_status = FXCODEC_STATUS_ERROR;
     return FXCODEC_STATUS_ERROR;
   }
 
   while (true) {
-    bool readRes = JpegModule::ProgressiveDecoder::ReadScanline(
-        m_pJpegContext.get(), m_pDecodeBuf.get());
+    bool readRes = JpegProgressiveDecoder::ReadScanline(m_pJpegContext.get(),
+                                                        m_pDecodeBuf.get());
     while (!readRes) {
       FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
       if (!JpegReadMoreData(&error_status)) {
@@ -1090,8 +1088,8 @@
         m_status = error_status;
         return m_status;
       }
-      readRes = JpegModule::ProgressiveDecoder::ReadScanline(
-          m_pJpegContext.get(), m_pDecodeBuf.get());
+      readRes = JpegProgressiveDecoder::ReadScanline(m_pJpegContext.get(),
+                                                     m_pDecodeBuf.get());
     }
     if (m_SrcFormat == FXCodec_Rgb) {
       int src_Bpp = (m_SrcFormat & 0xff) >> 3;