Avoid exposing JpxDecodeAction
Move JpxDecodeAction out of jpx_decode_conversion.h, and replace JpxDecodeConversion::action() with the set of getters that returns the information CPDF_DIB::LoadJpxBitmap() needs. This encapsulates more JPX-specific decoding logic in JpxDecodeConversion and reduces the size of LoadJpxBitmap().
Change-Id: If05b600f411c5ff8fffb2d5799fe76b16673a137
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/135391
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_dib.cpp b/core/fpdfapi/page/cpdf_dib.cpp
index 940497a..dbc9a8e 100644
--- a/core/fpdfapi/page/cpdf_dib.cpp
+++ b/core/fpdfapi/page/cpdf_dib.cpp
@@ -626,26 +626,11 @@
DCHECK_NE(0u, components_);
}
- FXDIB_Format format;
- if (conversion.action() == JpxDecodeAction::kUseGray ||
- conversion.action() == JpxDecodeAction::kUseIndexed) {
- format = FXDIB_Format::k8bppRgb;
- } else if (conversion.action() == JpxDecodeAction::kUseRgb &&
- image_info.channels == 3) {
- format = FXDIB_Format::kBgr;
- } else if (conversion.action() == JpxDecodeAction::kUseRgb &&
- image_info.channels == 4) {
- format = FXDIB_Format::kBgrx;
- } else if (conversion.action() == JpxDecodeAction::kConvertArgbToRgb) {
- CHECK_GE(image_info.channels, 4);
- format = FXDIB_Format::kBgrx;
- } else {
- image_info.width = (image_info.width * image_info.channels + 2) / 3;
- format = FXDIB_Format::kBgr;
- }
+ image_info.width = conversion.width();
auto result_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
- if (!result_bitmap->Create(image_info.width, image_info.height, format)) {
+ if (!result_bitmap->Create(image_info.width, image_info.height,
+ conversion.format())) {
return nullptr;
}
@@ -656,7 +641,7 @@
return nullptr;
}
- if (conversion.action() == JpxDecodeAction::kConvertArgbToRgb) {
+ if (conversion.convert_argb_to_rgb()) {
result_bitmap = ConvertArgbJpxBitmapToRgb(result_bitmap, image_info.width,
image_info.height);
if (!result_bitmap) {
diff --git a/core/fpdfapi/page/jpx_decode_conversion.cpp b/core/fpdfapi/page/jpx_decode_conversion.cpp
index 10773ad..ca4aa91 100644
--- a/core/fpdfapi/page/jpx_decode_conversion.cpp
+++ b/core/fpdfapi/page/jpx_decode_conversion.cpp
@@ -11,9 +11,19 @@
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/notreached.h"
#include "core/fxcrt/retain_ptr.h"
+#include "core/fxge/dib/fx_dib.h"
namespace {
+enum class JpxDecodeAction {
+ kDoNothing,
+ kUseGray,
+ kUseIndexed,
+ kUseRgb,
+ kUseCmyk,
+ kConvertArgbToRgb,
+};
+
// ISO 32000-1:2008 section 7.4.9 says the PDF and JPX colorspaces should have
// the same number of color channels. This helper function checks the
// colorspaces match, but also tolerates unknowns.
@@ -123,6 +133,26 @@
NOTREACHED();
}
+std::optional<FXDIB_Format> GetFormatFromJpxDecodeActionAndImageInfo(
+ JpxDecodeAction action,
+ uint32_t channels) {
+ if (action == JpxDecodeAction::kUseGray ||
+ action == JpxDecodeAction::kUseIndexed) {
+ return FXDIB_Format::k8bppRgb;
+ }
+ if (action == JpxDecodeAction::kUseRgb && channels == 3) {
+ return FXDIB_Format::kBgr;
+ }
+ if (action == JpxDecodeAction::kUseRgb && channels == 4) {
+ return FXDIB_Format::kBgrx;
+ }
+ if (action == JpxDecodeAction::kConvertArgbToRgb) {
+ CHECK_GE(channels, 4);
+ return FXDIB_Format::kBgrx;
+ }
+ return std::nullopt;
+}
+
} // namespace
// static
@@ -139,8 +169,7 @@
}
JpxDecodeConversion conversion;
- conversion.action_ = maybe_action.value();
- switch (conversion.action_) {
+ switch (maybe_action.value()) {
case JpxDecodeAction::kDoNothing:
break;
@@ -154,6 +183,7 @@
case JpxDecodeAction::kUseRgb:
DCHECK_GE(jpx_info.channels, 3);
+ conversion.swap_rgb_ = true;
conversion.override_colorspace_ = nullptr;
break;
@@ -163,6 +193,8 @@
break;
case JpxDecodeAction::kConvertArgbToRgb:
+ conversion.swap_rgb_ = true;
+ conversion.convert_argb_to_rgb_ = true;
conversion.override_colorspace_ = nullptr;
break;
}
@@ -173,6 +205,18 @@
conversion.jpx_components_count_ =
GetComponentCountFromJpxImageInfo(jpx_info);
}
+
+ std::optional<FXDIB_Format> maybe_format =
+ GetFormatFromJpxDecodeActionAndImageInfo(maybe_action.value(),
+ jpx_info.channels);
+ if (maybe_format.has_value()) {
+ conversion.format_ = maybe_format.value();
+ conversion.width_ = jpx_info.width;
+ } else {
+ conversion.format_ = FXDIB_Format::kBgr;
+ conversion.width_ = (jpx_info.width * jpx_info.channels + 2) / 3;
+ }
+
return conversion;
}
diff --git a/core/fpdfapi/page/jpx_decode_conversion.h b/core/fpdfapi/page/jpx_decode_conversion.h
index ea2bbb1..0a2feb9 100644
--- a/core/fpdfapi/page/jpx_decode_conversion.h
+++ b/core/fpdfapi/page/jpx_decode_conversion.h
@@ -9,18 +9,10 @@
#include "core/fxcodec/jpx/cjpx_decoder.h"
#include "core/fxcrt/retain_ptr.h"
+#include "core/fxge/dib/fx_dib.h"
class CPDF_ColorSpace;
-enum class JpxDecodeAction {
- kDoNothing,
- kUseGray,
- kUseIndexed,
- kUseRgb,
- kUseCmyk,
- kConvertArgbToRgb,
-};
-
class JpxDecodeConversion {
public:
static std::optional<JpxDecodeConversion> Create(
@@ -33,8 +25,6 @@
JpxDecodeConversion& operator=(JpxDecodeConversion&&) noexcept;
~JpxDecodeConversion();
- JpxDecodeAction action() const { return action_; }
-
const std::optional<RetainPtr<CPDF_ColorSpace>>& override_colorspace() const {
return override_colorspace_;
}
@@ -43,15 +33,18 @@
return jpx_components_count_;
}
- bool swap_rgb() const {
- return action_ == JpxDecodeAction::kUseRgb ||
- action_ == JpxDecodeAction::kConvertArgbToRgb;
- }
+ bool swap_rgb() const { return swap_rgb_; }
+ bool convert_argb_to_rgb() const { return convert_argb_to_rgb_; }
+ FXDIB_Format format() const { return format_; }
+ uint32_t width() const { return width_; }
private:
JpxDecodeConversion();
- JpxDecodeAction action_;
+ bool swap_rgb_ = false;
+ bool convert_argb_to_rgb_ = false;
+ FXDIB_Format format_ = FXDIB_Format::kInvalid;
+ uint32_t width_ = 0;
// The colorspace to override the existing colorspace.
//