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
9#include "core/fpdfapi/page/cpdf_colorspace.h"
10#include "core/fpdfapi/page/cpdf_docpagedata.h"
11#include "core/fpdfapi/parser/cpdf_array.h"
12#include "core/fpdfapi/parser/cpdf_document.h"
13#include "core/fpdfapi/parser/cpdf_object.h"
14#include "core/fpdfapi/parser/cpdf_stream.h"
15#include "core/fpdfapi/parser/cpdf_stream_acc.h"
16#include "core/fpdfapi/parser/cpdf_string.h"
17#include "core/fxcrt/check_op.h"
18#include "core/fxcrt/data_vector.h"
19#include "core/fxcrt/fx_safe_types.h"
20#include "core/fxcrt/retain_ptr.h"
21#include "core/fxcrt/span.h"
22
23CPDF_IndexedCS::CPDF_IndexedCS() : CPDF_BasedCS(Family::kIndexed) {}
24
25CPDF_IndexedCS::~CPDF_IndexedCS() = default;
26
27const CPDF_IndexedCS* CPDF_IndexedCS::AsIndexedCS() const {
28 return this;
29}
30
31uint32_t CPDF_IndexedCS::v_Load(CPDF_Document* pDoc,
32 const CPDF_Array* pArray,
33 std::set<const CPDF_Object*>* pVisited) {
34 if (pArray->size() < 4) {
35 return 0;
36 }
37
38 RetainPtr<const CPDF_Object> pBaseObj = pArray->GetDirectObjectAt(1);
39 if (HasSameArray(pBaseObj.Get())) {
40 return 0;
41 }
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
50 // The base color space cannot be a Pattern or Indexed space, according to ISO
51 // 32000-1:2008 section 8.6.6.3.
52 Family family = m_pBaseCS->GetFamily();
53 if (family == Family::kIndexed || family == Family::kPattern) {
54 return 0;
55 }
56
57 uint32_t base_component_count = m_pBaseCS->ComponentCount();
58 DCHECK(base_component_count);
59 component_min_max_ = DataVector<IndexedColorMinMax>(base_component_count);
60 float defvalue;
61 for (uint32_t i = 0; i < component_min_max_.size(); i++) {
62 IndexedColorMinMax& comp = component_min_max_[i];
63 m_pBaseCS->GetDefaultValue(i, &defvalue, &comp.min, &comp.max);
64 comp.max -= comp.min;
65 }
66
67 // ISO 32000-1:2008 section 8.6.6.3 says the maximum value is 255.
68 max_index_ = pArray->GetIntegerAt(2);
69 if (max_index_ < 0 || max_index_ > 255) {
70 return 0;
71 }
72
73 RetainPtr<const CPDF_Object> pTableObj = pArray->GetDirectObjectAt(3);
74 if (!pTableObj) {
75 return 0;
76 }
77
78 if (const CPDF_String* str_obj = pTableObj->AsString()) {
79 ByteString str_data = str_obj->GetString();
80 pdfium::span<const uint8_t> str_span = str_data.unsigned_span();
81 lookup_table_ = DataVector<uint8_t>(str_span.begin(), str_span.end());
82 } else if (const CPDF_Stream* stream_obj = pTableObj->AsStream()) {
83 auto acc =
84 pdfium::MakeRetain<CPDF_StreamAcc>(pdfium::WrapRetain(stream_obj));
85 acc->LoadAllDataFiltered();
86 pdfium::span<const uint8_t> str_span = acc->GetSpan();
87 lookup_table_ = DataVector<uint8_t>(str_span.begin(), str_span.end());
88 }
89 return 1;
90}
91
92std::optional<FX_RGB_STRUCT<float>> CPDF_IndexedCS::GetRGB(
93 pdfium::span<const float> pBuf) const {
94 int32_t index = static_cast<int32_t>(pBuf[0]);
95 if (index < 0 || index > max_index_) {
96 return std::nullopt;
97 }
98
99 DCHECK(!component_min_max_.empty());
100 DCHECK_EQ(component_min_max_.size(), m_pBaseCS->ComponentCount());
101
102 FX_SAFE_SIZE_T length = index;
103 length += 1;
104 length *= component_min_max_.size();
105 if (!length.IsValid() || length.ValueOrDie() > lookup_table_.size()) {
106 return std::nullopt;
107 }
108
109 DataVector<float> comps(component_min_max_.size());
110 for (uint32_t i = 0; i < component_min_max_.size(); ++i) {
111 const IndexedColorMinMax& comp = component_min_max_[i];
112 comps[i] =
113 comp.min +
114 comp.max * lookup_table_[index * component_min_max_.size() + i] / 255;
115 }
116 return m_pBaseCS->GetRGB(comps);
117}
fxcrt::ByteString ByteString
Definition bytestring.h:180
#define DCHECK
Definition check.h:33
#define DCHECK_EQ(x, y)
Definition check_op.h:17
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
Definition cpdf_array.h:29
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
uint32_t v_Load(CPDF_Document *pDoc, const CPDF_Array *pArray, std::set< const CPDF_Object * > *pVisited) override
~CPDF_IndexedCS() override
std::optional< FX_RGB_STRUCT< float > > GetRGB(pdfium::span< const float > pBuf) const override
ByteString GetString() const override