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
14CPDF_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
21CPDF_DIBTransferFunc::~CPDF_DIBTransferFunc() {}
22
23FXDIB_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
34FX_ARGB* CPDF_DIBTransferFunc::GetDestPalette() {
35  return nullptr;
36}
37
38void 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
143void 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