Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cpdf_indexedcs.cpp
Go to the documentation of this file.
1// Copyright 2022 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#include "core/fpdfapi/page/cpdf_indexedcs.h"
6
7#include <set>
8#include <vector>
9
10#include "core/fpdfapi/page/cpdf_colorspace.h"
11#include "core/fpdfapi/page/cpdf_docpagedata.h"
12#include "core/fpdfapi/parser/cpdf_array.h"
13#include "core/fpdfapi/parser/cpdf_document.h"
14#include "core/fpdfapi/parser/cpdf_object.h"
15#include "core/fpdfapi/parser/cpdf_stream.h"
16#include "core/fpdfapi/parser/cpdf_stream_acc.h"
17#include "core/fpdfapi/parser/cpdf_string.h"
18#include "core/fxcrt/data_vector.h"
19#include "core/fxcrt/fx_2d_size.h"
20#include "core/fxcrt/fx_safe_types.h"
21#include "core/fxcrt/retain_ptr.h"
22#include "third_party/base/check_op.h"
23#include "third_party/base/containers/span.h"
24
25CPDF_IndexedCS::CPDF_IndexedCS() : CPDF_BasedCS(Family::kIndexed) {}
26
27CPDF_IndexedCS::~CPDF_IndexedCS() = default;
28
29const CPDF_IndexedCS* CPDF_IndexedCS::AsIndexedCS() const {
30 return this;
31}
32
33uint32_t CPDF_IndexedCS::v_Load(CPDF_Document* pDoc,
34 const CPDF_Array* pArray,
35 std::set<const CPDF_Object*>* pVisited) {
36 if (pArray->size() < 4)
37 return 0;
38
39 RetainPtr<const CPDF_Object> pBaseObj = pArray->GetDirectObjectAt(1);
40 if (HasSameArray(pBaseObj.Get()))
41 return 0;
42
43 auto* pDocPageData = CPDF_DocPageData::FromDocument(pDoc);
44 m_pBaseCS =
45 pDocPageData->GetColorSpaceGuarded(pBaseObj.Get(), nullptr, pVisited);
46 if (!m_pBaseCS)
47 return 0;
48
49 // The base color space cannot be a Pattern or Indexed space, according to the
50 // PDF 1.7 spec, page 263.
51 Family family = m_pBaseCS->GetFamily();
52 if (family == Family::kIndexed || family == Family::kPattern)
53 return 0;
54
55 m_nBaseComponents = m_pBaseCS->CountComponents();
56 DCHECK(m_nBaseComponents);
57 m_pCompMinMax = DataVector<float>(Fx2DSizeOrDie(m_nBaseComponents, 2));
58 float defvalue;
59 for (uint32_t i = 0; i < m_nBaseComponents; i++) {
60 m_pBaseCS->GetDefaultValue(i, &defvalue, &m_pCompMinMax[i * 2],
61 &m_pCompMinMax[i * 2 + 1]);
62 m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2];
63 }
64 m_MaxIndex = pArray->GetIntegerAt(2);
65
66 RetainPtr<const CPDF_Object> pTableObj = pArray->GetDirectObjectAt(3);
67 if (!pTableObj)
68 return 0;
69
70 if (const CPDF_String* pString = pTableObj->AsString()) {
71 m_Table = pString->GetString();
72 } else if (const CPDF_Stream* pStream = pTableObj->AsStream()) {
73 auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pdfium::WrapRetain(pStream));
74 pAcc->LoadAllDataFiltered();
75 m_Table = ByteStringView(pAcc->GetSpan());
76 }
77 return 1;
78}
79
80bool CPDF_IndexedCS::GetRGB(pdfium::span<const float> pBuf,
81 float* R,
82 float* G,
83 float* B) const {
84 int32_t index = static_cast<int32_t>(pBuf[0]);
85 if (index < 0 || index > m_MaxIndex)
86 return false;
87
88 DCHECK(m_nBaseComponents);
89 DCHECK_EQ(m_nBaseComponents, m_pBaseCS->CountComponents());
90
91 FX_SAFE_SIZE_T length = index;
92 length += 1;
93 length *= m_nBaseComponents;
94 if (!length.IsValid() || length.ValueOrDie() > m_Table.GetLength()) {
95 *R = 0;
96 *G = 0;
97 *B = 0;
98 return false;
99 }
100
101 std::vector<float> comps(m_nBaseComponents);
102 const uint8_t* pTable = m_Table.raw_str();
103 for (uint32_t i = 0; i < m_nBaseComponents; ++i) {
104 comps[i] =
105 m_pCompMinMax[i * 2] +
106 m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255;
107 }
108 return m_pBaseCS->GetRGB(comps, R, G, B);
109}
CPDF_BasedCS(Family family)
bool HasSameArray(const CPDF_Object *pObj) const
static CPDF_DocPageData * FromDocument(const CPDF_Document *pDoc)
const CPDF_IndexedCS * AsIndexedCS() const override
bool GetRGB(pdfium::span< const float > pBuf, float *R, float *G, float *B) const override
uint32_t v_Load(CPDF_Document *pDoc, const CPDF_Array *pArray, std::set< const CPDF_Object * > *pVisited) override
~CPDF_IndexedCS() override