From f8bf9c650656be247ed8d791073025ad2105e912 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Tue, 24 Oct 2023 10:26:20 -0700 Subject: [PATCH] LibPDF: Sketch out DeviceN color spaces a bit Documents using them now show render-time diagnostics instead of asserting that number of parameters passed to a color don't match whatever number of channels the previously-set color space had. Fixes two asserts on the `-n 500` 0000.zip test set. --- Userland/Libraries/LibPDF/ColorSpace.cpp | 48 ++++++++++++++++++++++++ Userland/Libraries/LibPDF/ColorSpace.h | 17 +++++++++ Userland/Libraries/LibPDF/CommonNames.h | 1 + 3 files changed, 66 insertions(+) diff --git a/Userland/Libraries/LibPDF/ColorSpace.cpp b/Userland/Libraries/LibPDF/ColorSpace.cpp index e4401a6739..58f30c3987 100644 --- a/Userland/Libraries/LibPDF/ColorSpace.cpp +++ b/Userland/Libraries/LibPDF/ColorSpace.cpp @@ -56,6 +56,9 @@ PDFErrorOr> ColorSpace::create(Document* document, Non if (color_space_name == CommonNames::CalRGB) return TRY(CalRGBColorSpace::create(document, move(parameters))); + if (color_space_name == CommonNames::DeviceN) + return TRY(DeviceNColorSpace::create(document, move(parameters))); + if (color_space_name == CommonNames::ICCBased) return TRY(ICCBasedColorSpace::create(document, move(parameters))); @@ -134,6 +137,51 @@ Vector DeviceCMYKColorSpace::default_decode() const return { 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }; } +PDFErrorOr> DeviceNColorSpace::create(Document*, Vector&& parameters) +{ + // "[ /DeviceN names alternateSpace tintTransform ] + // or + // [ /DeviceN names alternateSpace tintTransform attributes ]" + if (parameters.size() != 4 && parameters.size() != 5) + return Error { Error::Type::MalformedPDF, "DevicN color space expects 4 or 5 parameters" }; + + // "The names parameter is an array of name objects specifying the individual color components. + // The length of the array determines the number of components in the DeviceN color space" + auto names = parameters[0].get>()->cast(); + + // "The alternateSpace parameter is an array or name object that can be any device or CIE-based color space + // but not another special color space (Pattern, Indexed, Separation, or DeviceN)." + + // FIXME: Implement. + + return adopt_ref(*new DeviceNColorSpace(names->size())); +} + +PDFErrorOr DeviceNColorSpace::color(ReadonlySpan) const +{ + return Error::rendering_unsupported_error("DeviceN color spaces not yet implemented"); +} + +int DeviceNColorSpace::number_of_components() const +{ + return m_number_of_components; +} + +Vector DeviceNColorSpace::default_decode() const +{ + Vector decoding_ranges; + for (u8 i = 0; i < number_of_components(); i++) { + decoding_ranges.append(0.0); + decoding_ranges.append(1.0); + } + return decoding_ranges; +} + +DeviceNColorSpace::DeviceNColorSpace(size_t number_of_components) + : m_number_of_components(number_of_components) +{ +} + PDFErrorOr> CalRGBColorSpace::create(Document* document, Vector&& parameters) { if (parameters.size() != 1) diff --git a/Userland/Libraries/LibPDF/ColorSpace.h b/Userland/Libraries/LibPDF/ColorSpace.h index 066c9b8040..59696649fb 100644 --- a/Userland/Libraries/LibPDF/ColorSpace.h +++ b/Userland/Libraries/LibPDF/ColorSpace.h @@ -106,6 +106,23 @@ private: DeviceCMYKColorSpace() = default; }; +class DeviceNColorSpace final : public ColorSpace { +public: + static PDFErrorOr> create(Document*, Vector&& parameters); + + ~DeviceNColorSpace() override = default; + + PDFErrorOr color(ReadonlySpan arguments) const override; + int number_of_components() const override; + Vector default_decode() const override; + ColorSpaceFamily const& family() const override { return ColorSpaceFamily::DeviceN; } + +private: + DeviceNColorSpace(size_t number_of_components); + + size_t m_number_of_components { 0 }; +}; + class CalRGBColorSpace final : public ColorSpace { public: static PDFErrorOr> create(Document*, Vector&& parameters); diff --git a/Userland/Libraries/LibPDF/CommonNames.h b/Userland/Libraries/LibPDF/CommonNames.h index a9b6fab62f..87f1f71827 100644 --- a/Userland/Libraries/LibPDF/CommonNames.h +++ b/Userland/Libraries/LibPDF/CommonNames.h @@ -51,6 +51,7 @@ X(Dests) \ X(DeviceCMYK) \ X(DeviceGray) \ + X(DeviceN) \ X(DeviceRGB) \ X(Differences) \ X(E) \