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_transferfuncdib.cpp
Go to the documentation of this file.
1// Copyright 2016 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_transferfuncdib.h"
8
9#include <utility>
10
11#include "build/build_config.h"
12#include "core/fpdfapi/page/cpdf_transferfunc.h"
13#include "core/fxcrt/check.h"
14#include "core/fxcrt/zip.h"
15#include "core/fxge/calculate_pitch.h"
16
17#if defined(PDF_USE_SKIA)
18#include "core/fxcrt/notreached.h"
19#endif
20
21namespace {
22
23CFX_DIBBase::kPlatformRGBStruct MakePlatformRGBStruct(uint8_t red,
24 uint8_t green,
25 uint8_t blue) {
26 // Note that the return value may have an alpha value that will be set to 0.
27 return {
28 .blue = blue,
29 .green = green,
30 .red = red,
31 };
32}
33
34} // namespace
35
36CPDF_TransferFuncDIB::CPDF_TransferFuncDIB(
37 RetainPtr<const CFX_DIBBase> src,
38 RetainPtr<CPDF_TransferFunc> transfer_func)
39 : src_(std::move(src)),
40 transfer_func_(std::move(transfer_func)),
41 r_samples_(transfer_func_->GetSamplesR()),
42 g_samples_(transfer_func_->GetSamplesG()),
43 b_samples_(transfer_func_->GetSamplesB()) {
44 SetWidth(src_->GetWidth());
45 SetHeight(src_->GetHeight());
46 SetFormat(GetDestFormat());
48 scanline_.resize(GetPitch());
49 CHECK(!HasPalette());
50}
51
52CPDF_TransferFuncDIB::~CPDF_TransferFuncDIB() = default;
53
54FXDIB_Format CPDF_TransferFuncDIB::GetDestFormat() const {
55 if (src_->IsMaskFormat()) {
57 }
58
59 if (src_->IsAlphaFormat()) {
60 // TODO(crbug.com/355676038): Consider adding support for
61 // `FXDIB_Format::kBgraPremul`
63 }
64
66}
67
68void CPDF_TransferFuncDIB::TranslateScanline(
69 pdfium::span<const uint8_t> src_span) const {
70 auto scanline_span = pdfium::make_span(scanline_);
71 switch (src_->GetFormat()) {
72 case FXDIB_Format::kInvalid: {
73 break;
74 }
75 case FXDIB_Format::k1bppRgb: {
76 const auto color0 =
77 MakePlatformRGBStruct(r_samples_[0], g_samples_[0], b_samples_[0]);
78 const auto color1 = MakePlatformRGBStruct(
79 r_samples_[255], g_samples_[255], b_samples_[255]);
80 auto dest = fxcrt::reinterpret_span<kPlatformRGBStruct>(scanline_span);
81 for (int i = 0; i < GetWidth(); i++) {
82 const bool is_on = (src_span[i / 8] & (1 << (7 - i % 8)));
83 dest[i] = is_on ? color1 : color0;
84 }
85 break;
86 }
87 case FXDIB_Format::k1bppMask: {
88 const int m0 = r_samples_[0];
89 const int m1 = r_samples_[255];
90 for (int i = 0; i < GetWidth(); i++) {
91 const bool is_on = (src_span[i / 8] & (1 << (7 - i % 8)));
92 scanline_[i] = is_on ? m1 : m0;
93 }
94 break;
95 }
96 case FXDIB_Format::k8bppRgb: {
97 pdfium::span<const uint32_t> src_palette = src_->GetPaletteSpan();
98 auto dest = fxcrt::reinterpret_span<kPlatformRGBStruct>(scanline_span);
99 auto zip = fxcrt::Zip(src_span.first(GetWidth()), dest);
100 if (src_->HasPalette()) {
101 for (auto [input, output] : zip) {
102 const FX_ARGB src_argb = src_palette[input];
103 output = MakePlatformRGBStruct(r_samples_[FXARGB_B(src_argb)],
104 g_samples_[FXARGB_G(src_argb)],
105 b_samples_[FXARGB_R(src_argb)]);
106 }
107 } else {
108 for (auto [input, output] : zip) {
109 output = MakePlatformRGBStruct(r_samples_[input], g_samples_[input],
110 b_samples_[input]);
111 }
112 }
113 break;
114 }
115 case FXDIB_Format::k8bppMask: {
116 for (auto [input, output] :
117 fxcrt::Zip(src_span.first(GetWidth()), scanline_span)) {
118 output = r_samples_[input];
119 }
120 break;
121 }
122 case FXDIB_Format::kBgr: {
123 auto src =
124 fxcrt::reinterpret_span<const FX_BGR_STRUCT<uint8_t>>(src_span);
125 auto dest = fxcrt::reinterpret_span<kPlatformRGBStruct>(scanline_span);
126 for (auto [input, output] : fxcrt::Zip(src.first(GetWidth()), dest)) {
127 output = MakePlatformRGBStruct(r_samples_[input.red],
128 g_samples_[input.green],
129 b_samples_[input.blue]);
130 }
131 break;
132 }
133 case FXDIB_Format::kBgrx: {
134 auto src =
135 fxcrt::reinterpret_span<const FX_BGRA_STRUCT<uint8_t>>(src_span);
136 auto dest = fxcrt::reinterpret_span<kPlatformRGBStruct>(scanline_span);
137 for (auto [input, output] : fxcrt::Zip(src.first(GetWidth()), dest)) {
138 output = MakePlatformRGBStruct(r_samples_[input.red],
139 g_samples_[input.green],
140 b_samples_[input.blue]);
141 }
142 break;
143 }
144 case FXDIB_Format::kBgra: {
145 auto src =
146 fxcrt::reinterpret_span<const FX_BGRA_STRUCT<uint8_t>>(src_span);
147 auto dest =
148 fxcrt::reinterpret_span<FX_BGRA_STRUCT<uint8_t>>(scanline_span);
149 for (auto [input, output] : fxcrt::Zip(src.first(GetWidth()), dest)) {
150 output = {
151 .blue = b_samples_[input.blue],
152 .green = g_samples_[input.green],
153 .red = r_samples_[input.red],
154 .alpha = input.alpha,
155 };
156 }
157 break;
158 }
159#if defined(PDF_USE_SKIA)
160 case FXDIB_Format::kBgraPremul: {
161 // TODO(crbug.com/355676038): Consider adding support for
162 // `FXDIB_Format::kBgraPremul`
163 NOTREACHED_NORETURN();
164 }
165#endif
166 }
167}
168
169pdfium::span<const uint8_t> CPDF_TransferFuncDIB::GetScanline(int line) const {
170 TranslateScanline(src_->GetScanline(line));
171 return scanline_;
172}
FX_BGR_STRUCT< uint8_t > kPlatformRGBStruct
Definition cfx_dibbase.h:43
static constexpr FXDIB_Format kPlatformRGBFormat
Definition cfx_dibbase.h:42
bool HasPalette() const
Definition cfx_dibbase.h:78
int GetBPP() const
Definition cfx_dibbase.h:72
void SetFormat(FXDIB_Format format)
int GetWidth() const
Definition cfx_dibbase.h:65
void SetPitch(uint32_t pitch)
pdfium::span< const uint8_t > GetScanline(int line) const override
~CPDF_TransferFuncDIB() override
#define FXARGB_B(argb)
Definition fx_dib.h:199
#define FXARGB_G(argb)
Definition fx_dib.h:198
#define FXARGB_R(argb)
Definition fx_dib.h:197
FXDIB_Format
Definition fx_dib.h:21
uint32_t CalculatePitch32OrDie(int bits_per_pixel, int width_in_pixels)
#define CHECK(cvref)