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