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)17CPDF_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() const35FXDIB_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) const45void 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) const151pdfium::span<const uint8_t> CPDF_TransferFuncDIB::GetScanline(int line) const { 152 TranslateScanline(m_pSrc->GetScanline(line)); 153 return m_Scanline; 154 } 155