1 // Copyright 2016 PDFium Authors. All rights reserved.
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/render/cpdf_dibtransferfunc.h"
8 
9 #include <vector>
10 
11 #include "core/fpdfapi/parser/cpdf_dictionary.h"
12 #include "core/fpdfapi/render/cpdf_transferfunc.h"
13 
CPDF_DIBTransferFunc(const CPDF_TransferFunc * pTransferFunc)14 CPDF_DIBTransferFunc::CPDF_DIBTransferFunc(
15     const CPDF_TransferFunc* pTransferFunc) {
16   m_RampR = pTransferFunc->m_Samples;
17   m_RampG = &pTransferFunc->m_Samples[256];
18   m_RampB = &pTransferFunc->m_Samples[512];
19 }
20 
~CPDF_DIBTransferFunc()21 CPDF_DIBTransferFunc::~CPDF_DIBTransferFunc() {}
22 
GetDestFormat()23 FXDIB_Format CPDF_DIBTransferFunc::GetDestFormat() {
24   if (m_pSrc->IsAlphaMask())
25     return FXDIB_8bppMask;
26 
27 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
28   return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb32;
29 #else
30   return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb;
31 #endif
32 }
33 
GetDestPalette()34 FX_ARGB* CPDF_DIBTransferFunc::GetDestPalette() {
35   return nullptr;
36 }
37 
TranslateScanline(const uint8_t * src_buf,std::vector<uint8_t> * dest_buf) const38 void CPDF_DIBTransferFunc::TranslateScanline(
39     const uint8_t* src_buf,
40     std::vector<uint8_t>* dest_buf) const {
41   bool bSkip = false;
42   switch (m_pSrc->GetFormat()) {
43     case FXDIB_1bppRgb: {
44       int r0 = m_RampR[0];
45       int g0 = m_RampG[0];
46       int b0 = m_RampB[0];
47       int r1 = m_RampR[255];
48       int g1 = m_RampG[255];
49       int b1 = m_RampB[255];
50       int index = 0;
51       for (int i = 0; i < m_Width; i++) {
52         if (src_buf[i / 8] & (1 << (7 - i % 8))) {
53           (*dest_buf)[index++] = b1;
54           (*dest_buf)[index++] = g1;
55           (*dest_buf)[index++] = r1;
56         } else {
57           (*dest_buf)[index++] = b0;
58           (*dest_buf)[index++] = g0;
59           (*dest_buf)[index++] = r0;
60         }
61 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
62         index++;
63 #endif
64       }
65       break;
66     }
67     case FXDIB_1bppMask: {
68       int m0 = m_RampR[0];
69       int m1 = m_RampR[255];
70       int index = 0;
71       for (int i = 0; i < m_Width; i++) {
72         if (src_buf[i / 8] & (1 << (7 - i % 8)))
73           (*dest_buf)[index++] = m1;
74         else
75           (*dest_buf)[index++] = m0;
76       }
77       break;
78     }
79     case FXDIB_8bppRgb: {
80       FX_ARGB* pPal = m_pSrc->GetPalette();
81       int index = 0;
82       for (int i = 0; i < m_Width; i++) {
83         if (pPal) {
84           FX_ARGB src_argb = pPal[*src_buf];
85           (*dest_buf)[index++] = m_RampB[FXARGB_R(src_argb)];
86           (*dest_buf)[index++] = m_RampG[FXARGB_G(src_argb)];
87           (*dest_buf)[index++] = m_RampR[FXARGB_B(src_argb)];
88         } else {
89           uint32_t src_byte = *src_buf;
90           (*dest_buf)[index++] = m_RampB[src_byte];
91           (*dest_buf)[index++] = m_RampG[src_byte];
92           (*dest_buf)[index++] = m_RampR[src_byte];
93         }
94         src_buf++;
95 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
96         index++;
97 #endif
98       }
99       break;
100     }
101     case FXDIB_8bppMask: {
102       int index = 0;
103       for (int i = 0; i < m_Width; i++)
104         (*dest_buf)[index++] = m_RampR[*(src_buf++)];
105       break;
106     }
107     case FXDIB_Rgb: {
108       int index = 0;
109       for (int i = 0; i < m_Width; i++) {
110         (*dest_buf)[index++] = m_RampB[*(src_buf++)];
111         (*dest_buf)[index++] = m_RampG[*(src_buf++)];
112         (*dest_buf)[index++] = m_RampR[*(src_buf++)];
113 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
114         index++;
115 #endif
116       }
117       break;
118     }
119     case FXDIB_Rgb32:
120       bSkip = true;
121     case FXDIB_Argb: {
122       int index = 0;
123       for (int i = 0; i < m_Width; i++) {
124         (*dest_buf)[index++] = m_RampB[*(src_buf++)];
125         (*dest_buf)[index++] = m_RampG[*(src_buf++)];
126         (*dest_buf)[index++] = m_RampR[*(src_buf++)];
127         if (!bSkip) {
128           (*dest_buf)[index++] = *src_buf;
129 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
130         } else {
131           index++;
132 #endif
133         }
134         src_buf++;
135       }
136       break;
137     }
138     default:
139       break;
140   }
141 }
142 
TranslateDownSamples(uint8_t * dest_buf,const uint8_t * src_buf,int pixels,int Bpp) const143 void CPDF_DIBTransferFunc::TranslateDownSamples(uint8_t* dest_buf,
144                                                 const uint8_t* src_buf,
145                                                 int pixels,
146                                                 int Bpp) const {
147   if (Bpp == 8) {
148     for (int i = 0; i < pixels; i++)
149       *dest_buf++ = m_RampR[*(src_buf++)];
150   } else if (Bpp == 24) {
151     for (int i = 0; i < pixels; i++) {
152       *dest_buf++ = m_RampB[*(src_buf++)];
153       *dest_buf++ = m_RampG[*(src_buf++)];
154       *dest_buf++ = m_RampR[*(src_buf++)];
155     }
156   } else {
157 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
158     if (!m_pSrc->HasAlpha()) {
159       for (int i = 0; i < pixels; i++) {
160         *dest_buf++ = m_RampB[*(src_buf++)];
161         *dest_buf++ = m_RampG[*(src_buf++)];
162         *dest_buf++ = m_RampR[*(src_buf++)];
163         dest_buf++;
164         src_buf++;
165       }
166     } else {
167 #endif
168       for (int i = 0; i < pixels; i++) {
169         *dest_buf++ = m_RampB[*(src_buf++)];
170         *dest_buf++ = m_RampG[*(src_buf++)];
171         *dest_buf++ = m_RampR[*(src_buf++)];
172         *dest_buf++ = *(src_buf++);
173       }
174 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
175     }
176 #endif
177   }
178 }
179