Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cpdf_devicecs.cpp
Go to the documentation of this file.
1// Copyright 2014 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "core/fpdfapi/page/cpdf_devicecs.h"
8
9#include <algorithm>
10
11#include "core/fpdfapi/parser/cpdf_array.h"
12#include "core/fpdfapi/parser/cpdf_dictionary.h"
13#include "core/fpdfapi/parser/cpdf_document.h"
14#include "core/fpdfapi/parser/cpdf_stream_acc.h"
15#include "core/fpdfapi/parser/cpdf_string.h"
16#include "core/fxcodec/fx_codec.h"
17#include "core/fxcrt/check.h"
18#include "core/fxcrt/compiler_specific.h"
19#include "core/fxcrt/notreached.h"
20#include "core/fxge/dib/cfx_cmyk_to_srgb.h"
21
22namespace {
23
24float NormalizeChannel(float fVal) {
25 return std::clamp(fVal, 0.0f, 1.0f);
26}
27
28} // namespace
29
30CPDF_DeviceCS::CPDF_DeviceCS(Family family) : CPDF_ColorSpace(family) {
31 DCHECK(family == Family::kDeviceGray || family == Family::kDeviceRGB ||
32 family == Family::kDeviceCMYK);
34}
35
36CPDF_DeviceCS::~CPDF_DeviceCS() = default;
37
38uint32_t CPDF_DeviceCS::v_Load(CPDF_Document* pDoc,
39 const CPDF_Array* pArray,
40 std::set<const CPDF_Object*>* pVisited) {
41 // Unlike other classes that inherit from CPDF_ColorSpace, CPDF_DeviceCS is
42 // never loaded by CPDF_ColorSpace.
44}
45
46std::optional<FX_RGB_STRUCT<float>> CPDF_DeviceCS::GetRGB(
47 pdfium::span<const float> pBuf) const {
48 switch (GetFamily()) {
50 const float pix = NormalizeChannel(pBuf.front());
51 return FX_RGB_STRUCT<float>{pix, pix, pix};
52 }
53 case Family::kDeviceRGB: {
54 const auto& rgb =
55 fxcrt::reinterpret_span<const FX_RGB_STRUCT<float>>(pBuf).front();
56 return FX_RGB_STRUCT<float>{
57 NormalizeChannel(rgb.red),
58 NormalizeChannel(rgb.green),
59 NormalizeChannel(rgb.blue),
60 };
61 }
63 const auto& cmyk =
64 fxcrt::reinterpret_span<const FX_CMYK_STRUCT<float>>(pBuf).front();
66 return FX_RGB_STRUCT<float>{
67 1.0f - std::min(1.0f, cmyk.cyan + cmyk.key),
68 1.0f - std::min(1.0f, cmyk.magenta + cmyk.key),
69 1.0f - std::min(1.0f, cmyk.yellow + cmyk.key),
70 };
71 }
72 return AdobeCMYK_to_sRGB(
73 NormalizeChannel(cmyk.cyan), NormalizeChannel(cmyk.magenta),
74 NormalizeChannel(cmyk.yellow), NormalizeChannel(cmyk.key));
75 }
76 default:
78 }
79}
80
81void CPDF_DeviceCS::TranslateImageLine(pdfium::span<uint8_t> dest_span,
82 pdfium::span<const uint8_t> src_span,
83 int pixels,
84 int image_width,
85 int image_height,
86 bool bTransMask) const {
87 auto rgb_out = fxcrt::reinterpret_span<FX_RGB_STRUCT<uint8_t>>(dest_span);
88 switch (GetFamily()) {
90 CHECK(!bTransMask); // bTransMask only allowed for CMYK colorspaces.
91 // Compiler can't conclude src/dest don't overlap, avoid interleaved
92 // loads and stores by not using an auto& reference here.
93 for (const auto pix : src_span.first(pixels)) {
94 rgb_out.front().red = pix;
95 rgb_out.front().green = pix;
96 rgb_out.front().blue = pix;
97 rgb_out = rgb_out.subspan(1);
98 }
99 break;
101 CHECK(!bTransMask); // bTransMask only allowed for CMYK colorspaces.
102 fxcodec::ReverseRGB(dest_span, src_span, pixels);
103 break;
104 case Family::kDeviceCMYK: {
105 auto cmyk_in =
106 fxcrt::reinterpret_span<const FX_CMYK_STRUCT<uint8_t>>(src_span);
107 if (bTransMask) {
108 // Compiler can't conclude src/dest don't overlap, avoid interleaved
109 // loads and stores by not using an auto& reference here.
110 for (const auto cmyk : cmyk_in.first(pixels)) {
111 const int k = 255 - cmyk.key;
112 rgb_out.front().red = ((255 - cmyk.cyan) * k) / 255;
113 rgb_out.front().green = ((255 - cmyk.magenta) * k) / 255;
114 rgb_out.front().blue = ((255 - cmyk.yellow) * k) / 255;
115 rgb_out = rgb_out.subspan(1);
116 }
117 break;
118 }
120 // Compiler can't conclude src/dest don't overlap, avoid interleaved
121 // loads and stores by not using am auto& reference here,
122 for (const auto cmyk : cmyk_in.first(pixels)) {
123 const uint8_t k = cmyk.key;
124 rgb_out.front().blue = 255 - std::min(255, cmyk.cyan + k);
125 rgb_out.front().green = 255 - std::min(255, cmyk.magenta + k);
126 rgb_out.front().red = 255 - std::min(255, cmyk.yellow + k);
127 rgb_out = rgb_out.subspan(1);
128 }
129 break;
130 }
131 for (const auto& cmyk : cmyk_in.first(pixels)) {
132 // TODO(tsepez): maybe this is a FX_BGR_STRUCT in reality?
133 FX_RGB_STRUCT<uint8_t> rgb =
134 AdobeCMYK_to_sRGB1(cmyk.cyan, cmyk.magenta, cmyk.yellow, cmyk.key);
135 rgb_out.front().red = rgb.blue;
136 rgb_out.front().green = rgb.green;
137 rgb_out.front().blue = rgb.red;
138 rgb_out = rgb_out.subspan(1);
139 }
140 break;
141 }
142 default:
144 }
145}
#define DCHECK
Definition check.h:33
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
Definition cpdf_array.h:29
Family GetFamily() const
CPDF_ColorSpace(Family family)
static uint32_t ComponentsForFamily(Family family)
bool IsStdConversionEnabled() const
void SetComponentsForStockCS(uint32_t nComponents)
~CPDF_DeviceCS() override
std::optional< FX_RGB_STRUCT< float > > GetRGB(pdfium::span< const float > pBuf) const override
void TranslateImageLine(pdfium::span< uint8_t > dest_span, pdfium::span< const uint8_t > src_span, int pixels, int image_width, int image_height, bool bTransMask) const override
uint32_t v_Load(CPDF_Document *pDoc, const CPDF_Array *pArray, std::set< const CPDF_Object * > *pVisited) override
void ReverseRGB(pdfium::span< uint8_t > pDestBuf, pdfium::span< const uint8_t > pSrcBuf, int pixels)
Definition fx_codec.cpp:23
#define NOTREACHED_NORETURN()
Definition notreached.h:22
#define CHECK(cvref)