// Copyright 2016 The PDFium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "core/fpdfapi/page/cpdf_transferfuncdib.h" #include #include "build/build_config.h" #include "core/fpdfapi/page/cpdf_transferfunc.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fxge/calculate_pitch.h" #include "third_party/base/check.h" CPDF_TransferFuncDIB::CPDF_TransferFuncDIB( RetainPtr pSrc, RetainPtr pTransferFunc) : m_pSrc(std::move(pSrc)), m_pTransferFunc(std::move(pTransferFunc)), m_RampR(m_pTransferFunc->GetSamplesR()), m_RampG(m_pTransferFunc->GetSamplesG()), m_RampB(m_pTransferFunc->GetSamplesB()) { m_Width = m_pSrc->GetWidth(); m_Height = m_pSrc->GetHeight(); m_Format = GetDestFormat(); m_Pitch = fxge::CalculatePitch32OrDie(GetBppFromFormat(m_Format), m_Width); m_Scanline.resize(m_Pitch); DCHECK(m_palette.empty()); } CPDF_TransferFuncDIB::~CPDF_TransferFuncDIB() = default; FXDIB_Format CPDF_TransferFuncDIB::GetDestFormat() const { if (m_pSrc->IsMaskFormat()) return FXDIB_Format::k8bppMask; if (m_pSrc->IsAlphaFormat()) return FXDIB_Format::kArgb; return CFX_DIBBase::kPlatformRGBFormat; } void CPDF_TransferFuncDIB::TranslateScanline( pdfium::span src_span) const { const uint8_t* src_buf = src_span.data(); bool bSkip = false; switch (m_pSrc->GetFormat()) { case FXDIB_Format::k1bppRgb: { int r0 = m_RampR[0]; int g0 = m_RampG[0]; int b0 = m_RampB[0]; int r1 = m_RampR[255]; int g1 = m_RampG[255]; int b1 = m_RampB[255]; int index = 0; for (int i = 0; i < m_Width; i++) { if (src_buf[i / 8] & (1 << (7 - i % 8))) { m_Scanline[index++] = b1; m_Scanline[index++] = g1; m_Scanline[index++] = r1; } else { m_Scanline[index++] = b0; m_Scanline[index++] = g0; m_Scanline[index++] = r0; } #if BUILDFLAG(IS_APPLE) index++; #endif } break; } case FXDIB_Format::k1bppMask: { int m0 = m_RampR[0]; int m1 = m_RampR[255]; int index = 0; for (int i = 0; i < m_Width; i++) { if (src_buf[i / 8] & (1 << (7 - i % 8))) m_Scanline[index++] = m1; else m_Scanline[index++] = m0; } break; } case FXDIB_Format::k8bppRgb: { pdfium::span src_palette = m_pSrc->GetPaletteSpan(); int index = 0; for (int i = 0; i < m_Width; i++) { if (m_pSrc->HasPalette()) { FX_ARGB src_argb = src_palette[*src_buf]; m_Scanline[index++] = m_RampB[FXARGB_R(src_argb)]; m_Scanline[index++] = m_RampG[FXARGB_G(src_argb)]; m_Scanline[index++] = m_RampR[FXARGB_B(src_argb)]; } else { uint32_t src_byte = *src_buf; m_Scanline[index++] = m_RampB[src_byte]; m_Scanline[index++] = m_RampG[src_byte]; m_Scanline[index++] = m_RampR[src_byte]; } src_buf++; #if BUILDFLAG(IS_APPLE) index++; #endif } break; } case FXDIB_Format::k8bppMask: { int index = 0; for (int i = 0; i < m_Width; i++) m_Scanline[index++] = m_RampR[*(src_buf++)]; break; } case FXDIB_Format::kRgb: { int index = 0; for (int i = 0; i < m_Width; i++) { m_Scanline[index++] = m_RampB[*(src_buf++)]; m_Scanline[index++] = m_RampG[*(src_buf++)]; m_Scanline[index++] = m_RampR[*(src_buf++)]; #if BUILDFLAG(IS_APPLE) index++; #endif } break; } case FXDIB_Format::kRgb32: bSkip = true; [[fallthrough]]; case FXDIB_Format::kArgb: { int index = 0; for (int i = 0; i < m_Width; i++) { m_Scanline[index++] = m_RampB[*(src_buf++)]; m_Scanline[index++] = m_RampG[*(src_buf++)]; m_Scanline[index++] = m_RampR[*(src_buf++)]; if (!bSkip) { m_Scanline[index++] = *src_buf; #if BUILDFLAG(IS_APPLE) } else { index++; #endif } src_buf++; } break; } default: break; } } pdfium::span CPDF_TransferFuncDIB::GetScanline(int line) const { TranslateScanline(m_pSrc->GetScanline(line)); return m_Scanline; }