xref: /aosp_15_r20/external/pdfium/core/fpdfapi/page/cpdf_transferfuncdib.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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/fpdfapi/parser/cpdf_dictionary.h"
14 #include "core/fxge/calculate_pitch.h"
15 #include "third_party/base/check.h"
16 
CPDF_TransferFuncDIB(RetainPtr<CFX_DIBBase> pSrc,RetainPtr<CPDF_TransferFunc> pTransferFunc)17 CPDF_TransferFuncDIB::CPDF_TransferFuncDIB(
18     RetainPtr<CFX_DIBBase> pSrc,
19     RetainPtr<CPDF_TransferFunc> pTransferFunc)
20     : m_pSrc(std::move(pSrc)),
21       m_pTransferFunc(std::move(pTransferFunc)),
22       m_RampR(m_pTransferFunc->GetSamplesR()),
23       m_RampG(m_pTransferFunc->GetSamplesG()),
24       m_RampB(m_pTransferFunc->GetSamplesB()) {
25   m_Width = m_pSrc->GetWidth();
26   m_Height = m_pSrc->GetHeight();
27   m_Format = GetDestFormat();
28   m_Pitch = fxge::CalculatePitch32OrDie(GetBppFromFormat(m_Format), m_Width);
29   m_Scanline.resize(m_Pitch);
30   DCHECK(m_palette.empty());
31 }
32 
33 CPDF_TransferFuncDIB::~CPDF_TransferFuncDIB() = default;
34 
GetDestFormat() const35 FXDIB_Format CPDF_TransferFuncDIB::GetDestFormat() const {
36   if (m_pSrc->IsMaskFormat())
37     return FXDIB_Format::k8bppMask;
38 
39   if (m_pSrc->IsAlphaFormat())
40     return FXDIB_Format::kArgb;
41 
42   return CFX_DIBBase::kPlatformRGBFormat;
43 }
44 
TranslateScanline(pdfium::span<const uint8_t> src_span) const45 void CPDF_TransferFuncDIB::TranslateScanline(
46     pdfium::span<const uint8_t> src_span) const {
47   const uint8_t* src_buf = src_span.data();
48   bool bSkip = false;
49   switch (m_pSrc->GetFormat()) {
50     case FXDIB_Format::k1bppRgb: {
51       int r0 = m_RampR[0];
52       int g0 = m_RampG[0];
53       int b0 = m_RampB[0];
54       int r1 = m_RampR[255];
55       int g1 = m_RampG[255];
56       int b1 = m_RampB[255];
57       int index = 0;
58       for (int i = 0; i < m_Width; i++) {
59         if (src_buf[i / 8] & (1 << (7 - i % 8))) {
60           m_Scanline[index++] = b1;
61           m_Scanline[index++] = g1;
62           m_Scanline[index++] = r1;
63         } else {
64           m_Scanline[index++] = b0;
65           m_Scanline[index++] = g0;
66           m_Scanline[index++] = r0;
67         }
68 #if BUILDFLAG(IS_APPLE)
69         index++;
70 #endif
71       }
72       break;
73     }
74     case FXDIB_Format::k1bppMask: {
75       int m0 = m_RampR[0];
76       int m1 = m_RampR[255];
77       int index = 0;
78       for (int i = 0; i < m_Width; i++) {
79         if (src_buf[i / 8] & (1 << (7 - i % 8)))
80           m_Scanline[index++] = m1;
81         else
82           m_Scanline[index++] = m0;
83       }
84       break;
85     }
86     case FXDIB_Format::k8bppRgb: {
87       pdfium::span<const uint32_t> src_palette = m_pSrc->GetPaletteSpan();
88       int index = 0;
89       for (int i = 0; i < m_Width; i++) {
90         if (m_pSrc->HasPalette()) {
91           FX_ARGB src_argb = src_palette[*src_buf];
92           m_Scanline[index++] = m_RampB[FXARGB_R(src_argb)];
93           m_Scanline[index++] = m_RampG[FXARGB_G(src_argb)];
94           m_Scanline[index++] = m_RampR[FXARGB_B(src_argb)];
95         } else {
96           uint32_t src_byte = *src_buf;
97           m_Scanline[index++] = m_RampB[src_byte];
98           m_Scanline[index++] = m_RampG[src_byte];
99           m_Scanline[index++] = m_RampR[src_byte];
100         }
101         src_buf++;
102 #if BUILDFLAG(IS_APPLE)
103         index++;
104 #endif
105       }
106       break;
107     }
108     case FXDIB_Format::k8bppMask: {
109       int index = 0;
110       for (int i = 0; i < m_Width; i++)
111         m_Scanline[index++] = m_RampR[*(src_buf++)];
112       break;
113     }
114     case FXDIB_Format::kRgb: {
115       int index = 0;
116       for (int i = 0; i < m_Width; i++) {
117         m_Scanline[index++] = m_RampB[*(src_buf++)];
118         m_Scanline[index++] = m_RampG[*(src_buf++)];
119         m_Scanline[index++] = m_RampR[*(src_buf++)];
120 #if BUILDFLAG(IS_APPLE)
121         index++;
122 #endif
123       }
124       break;
125     }
126     case FXDIB_Format::kRgb32:
127       bSkip = true;
128       [[fallthrough]];
129     case FXDIB_Format::kArgb: {
130       int index = 0;
131       for (int i = 0; i < m_Width; i++) {
132         m_Scanline[index++] = m_RampB[*(src_buf++)];
133         m_Scanline[index++] = m_RampG[*(src_buf++)];
134         m_Scanline[index++] = m_RampR[*(src_buf++)];
135         if (!bSkip) {
136           m_Scanline[index++] = *src_buf;
137 #if BUILDFLAG(IS_APPLE)
138         } else {
139           index++;
140 #endif
141         }
142         src_buf++;
143       }
144       break;
145     }
146     default:
147       break;
148   }
149 }
150 
GetScanline(int line) const151 pdfium::span<const uint8_t> CPDF_TransferFuncDIB::GetScanline(int line) const {
152   TranslateScanline(m_pSrc->GetScanline(line));
153   return m_Scanline;
154 }
155