Remove circular include from fxcodec to fpdfapi/page

Extract the small amount of information needed from the colorspace
in the callers rather than passing it down directly. The family
is a const member of the colorspace, so it can't change between
the time we extract the information and then use it.

Change-Id: If874e625f5f367aaf9442a475e61148960c42a7b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/55251
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/BUILD.gn b/core/fpdfapi/page/BUILD.gn
index ed9f1fb..4fdc543 100644
--- a/core/fpdfapi/page/BUILD.gn
+++ b/core/fpdfapi/page/BUILD.gn
@@ -103,7 +103,6 @@
   allow_circular_includes_from = [
     "../font",
     "../parser",
-    "../../fxcodec",
   ]
   if (pdf_use_skia || pdf_use_skia_paths) {
     allow_circular_includes_from += [ "../../fxge" ]
diff --git a/core/fpdfapi/render/cpdf_dibbase.cpp b/core/fpdfapi/render/cpdf_dibbase.cpp
index 4f1d7e5..dc5d1e6 100644
--- a/core/fpdfapi/render/cpdf_dibbase.cpp
+++ b/core/fpdfapi/render/cpdf_dibbase.cpp
@@ -85,6 +85,15 @@
   return false;
 }
 
+CJPX_Decoder::ColorSpaceOption ColorSpaceOptionFromColorSpace(
+    CPDF_ColorSpace* pCS) {
+  if (!pCS)
+    return CJPX_Decoder::kNoColorSpace;
+  if (pCS->GetFamily() == PDFCS_INDEXED)
+    return CJPX_Decoder::kIndexedColorSpace;
+  return CJPX_Decoder::kNormalColorSpace;
+}
+
 }  // namespace
 
 CPDF_DIBBase::CPDF_DIBBase() = default;
@@ -562,8 +571,9 @@
 }
 
 RetainPtr<CFX_DIBitmap> CPDF_DIBBase::LoadJpxBitmap() {
-  std::unique_ptr<CJPX_Decoder> decoder =
-      CCodec_JpxModule::CreateDecoder(m_pStreamAcc->GetSpan(), m_pColorSpace);
+  std::unique_ptr<CJPX_Decoder> decoder = CCodec_JpxModule::CreateDecoder(
+      m_pStreamAcc->GetSpan(),
+      ColorSpaceOptionFromColorSpace(m_pColorSpace.Get()));
   if (!decoder)
     return nullptr;
 
diff --git a/core/fxcodec/codec/ccodec_jpxmodule.cpp b/core/fxcodec/codec/ccodec_jpxmodule.cpp
index 1df09d0..dc1575a 100644
--- a/core/fxcodec/codec/ccodec_jpxmodule.cpp
+++ b/core/fxcodec/codec/ccodec_jpxmodule.cpp
@@ -6,14 +6,13 @@
 
 #include "core/fxcodec/codec/ccodec_jpxmodule.h"
 
-#include "core/fxcodec/codec/cjpx_decoder.h"
 #include "third_party/base/ptr_util.h"
 
 // static
 std::unique_ptr<CJPX_Decoder> CCodec_JpxModule::CreateDecoder(
     pdfium::span<const uint8_t> src_span,
-    const RetainPtr<CPDF_ColorSpace>& cs) {
-  auto decoder = pdfium::MakeUnique<CJPX_Decoder>(cs);
+    CJPX_Decoder::ColorSpaceOption option) {
+  auto decoder = pdfium::MakeUnique<CJPX_Decoder>(option);
   if (!decoder->Init(src_span))
     return nullptr;
 
diff --git a/core/fxcodec/codec/ccodec_jpxmodule.h b/core/fxcodec/codec/ccodec_jpxmodule.h
index 7d02c69..b9d487d 100644
--- a/core/fxcodec/codec/ccodec_jpxmodule.h
+++ b/core/fxcodec/codec/ccodec_jpxmodule.h
@@ -10,18 +10,15 @@
 #include <memory>
 #include <vector>
 
+#include "core/fxcodec/codec/cjpx_decoder.h"
 #include "core/fxcrt/fx_system.h"
-#include "core/fxcrt/retain_ptr.h"
 #include "third_party/base/span.h"
 
-class CJPX_Decoder;
-class CPDF_ColorSpace;
-
 class CCodec_JpxModule {
  public:
   static std::unique_ptr<CJPX_Decoder> CreateDecoder(
       pdfium::span<const uint8_t> src_span,
-      const RetainPtr<CPDF_ColorSpace>& cs);
+      CJPX_Decoder::ColorSpaceOption option);
 
   CCodec_JpxModule() = delete;
   CCodec_JpxModule(const CCodec_JpxModule&) = delete;
diff --git a/core/fxcodec/codec/cjpx_decoder.cpp b/core/fxcodec/codec/cjpx_decoder.cpp
index 3614141..9367b6c 100644
--- a/core/fxcodec/codec/cjpx_decoder.cpp
+++ b/core/fxcodec/codec/cjpx_decoder.cpp
@@ -13,7 +13,6 @@
 #include <utility>
 #include <vector>
 
-#include "core/fpdfapi/page/cpdf_colorspace.h"
 #include "core/fxcrt/fx_safe_types.h"
 #include "third_party/base/optional.h"
 #include "third_party/base/ptr_util.h"
@@ -461,12 +460,8 @@
   img->comps[2].dy = img->comps[0].dy;
 }
 
-CJPX_Decoder::CJPX_Decoder(const RetainPtr<CPDF_ColorSpace>& cs)
-    : m_Image(nullptr),
-      m_Codec(nullptr),
-      m_DecodeData(nullptr),
-      m_Stream(nullptr),
-      m_ColorSpace(cs) {}
+CJPX_Decoder::CJPX_Decoder(ColorSpaceOption option)
+    : m_ColorSpaceOption(option) {}
 
 CJPX_Decoder::~CJPX_Decoder() {
   if (m_Codec)
@@ -503,7 +498,7 @@
   if (!m_Codec)
     return false;
 
-  if (m_ColorSpace && m_ColorSpace->GetFamily() == PDFCS_INDEXED)
+  if (m_ColorSpaceOption == kIndexedColorSpace)
     m_Parameters.flags |= OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
   opj_set_info_handler(m_Codec.Get(), fx_ignore_callback, nullptr);
   opj_set_warning_handler(m_Codec.Get(), fx_ignore_callback, nullptr);
@@ -518,7 +513,7 @@
 
   m_Image = pTempImage;
 #ifndef USE_SYSTEM_LIBOPENJPEG2
-  m_Image->pdfium_use_colorspace = !!m_ColorSpace;
+  m_Image->pdfium_use_colorspace = (m_ColorSpaceOption != kNoColorSpace);
 #endif
   return true;
 }
diff --git a/core/fxcodec/codec/cjpx_decoder.h b/core/fxcodec/codec/cjpx_decoder.h
index 95334b6..3b3889e 100644
--- a/core/fxcodec/codec/cjpx_decoder.h
+++ b/core/fxcodec/codec/cjpx_decoder.h
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "core/fxcodec/codec/codec_int.h"
-#include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "third_party/base/span.h"
 
@@ -21,11 +20,15 @@
 #include "third_party/libopenjpeg20/openjpeg.h"
 #endif
 
-class CPDF_ColorSpace;
-
 class CJPX_Decoder {
  public:
-  explicit CJPX_Decoder(const RetainPtr<CPDF_ColorSpace>& cs);
+  enum ColorSpaceOption {
+    kNoColorSpace,
+    kNormalColorSpace,
+    kIndexedColorSpace
+  };
+
+  explicit CJPX_Decoder(ColorSpaceOption option);
   ~CJPX_Decoder();
 
   bool Init(pdfium::span<const uint8_t> src_data);
@@ -36,13 +39,13 @@
               const std::vector<uint8_t>& offsets);
 
  private:
+  const ColorSpaceOption m_ColorSpaceOption;
   pdfium::span<const uint8_t> m_SrcData;
   UnownedPtr<opj_image_t> m_Image;
   UnownedPtr<opj_codec_t> m_Codec;
   std::unique_ptr<DecodeData> m_DecodeData;
   UnownedPtr<opj_stream_t> m_Stream;
   opj_dparameters_t m_Parameters;
-  RetainPtr<CPDF_ColorSpace> const m_ColorSpace;
 };
 
 #endif  // CORE_FXCODEC_CODEC_CJPX_DECODER_H_
diff --git a/core/fxcodec/codec/codec_int.h b/core/fxcodec/codec/codec_int.h
index 484d92e..e5f75d5 100644
--- a/core/fxcodec/codec/codec_int.h
+++ b/core/fxcodec/codec/codec_int.h
@@ -17,8 +17,6 @@
 #include "third_party/libopenjpeg20/openjpeg.h"
 #endif
 
-class CPDF_ColorSpace;
-
 struct DecodeData {
   DecodeData(const uint8_t* data, OPJ_SIZE_T size)
       : src_data(data), src_size(size), offset(0) {}
diff --git a/testing/fuzzers/pdf_jpx_fuzzer.cc b/testing/fuzzers/pdf_jpx_fuzzer.cc
index 6cf3320..2d5e7d4 100644
--- a/testing/fuzzers/pdf_jpx_fuzzer.cc
+++ b/testing/fuzzers/pdf_jpx_fuzzer.cc
@@ -28,8 +28,8 @@
 }  // namespace
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  std::unique_ptr<CJPX_Decoder> decoder =
-      CCodec_JpxModule::CreateDecoder({data, size}, nullptr);
+  std::unique_ptr<CJPX_Decoder> decoder = CCodec_JpxModule::CreateDecoder(
+      {data, size}, CJPX_Decoder::kNoColorSpace);
   if (!decoder)
     return 0;