5#include "core/fpdfapi/render/cpdf_docrenderdata.h"
11#include "core/fpdfapi/page/cpdf_transferfunc.h"
12#include "core/fpdfapi/parser/cpdf_array.h"
13#include "core/fpdfapi/parser/cpdf_dictionary.h"
14#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
15#include "core/fpdfapi/parser/cpdf_number.h"
16#include "core/fpdfapi/parser/cpdf_reference.h"
17#include "core/fpdfapi/parser/cpdf_stream.h"
18#include "core/fxcrt/data_vector.h"
19#include "testing/gmock/include/gmock/gmock.h"
20#include "testing/gtest/include/gtest/gtest.h"
22using ::testing::ElementsAreArray;
26constexpr uint8_t kExpectedType0FunctionSamples[] = {
27 0, 3, 6, 9, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43,
28 46, 49, 52, 55, 58, 60, 63, 66, 68, 71, 74, 76, 79, 81, 84,
29 86, 88, 90, 93, 95, 97, 99, 101, 103, 105, 106, 108, 110, 111, 113,
30 114, 115, 117, 118, 119, 120, 121, 122, 123, 124, 125, 125, 126, 126, 127,
31 127, 127, 127, 127, 127, 127, 127, 127, 127, 126, 126, 125, 125, 124, 123,
32 123, 122, 121, 120, 119, 117, 116, 115, 113, 112, 110, 109, 107, 105, 104,
33 102, 100, 98, 96, 94, 92, 89, 87, 85, 82, 80, 77, 75, 72, 70,
34 67, 64, 62, 59, 56, 53, 50, 48, 45, 42, 39, 36, 33, 30, 27,
35 23, 20, 17, 14, 11, 8, 5, 2, 254, 251, 248, 245, 242, 239, 236,
36 233, 229, 226, 223, 220, 217, 214, 211, 208, 206, 203, 200, 197, 194, 192,
37 189, 186, 184, 181, 179, 176, 174, 171, 169, 167, 164, 162, 160, 158, 156,
38 154, 152, 151, 149, 147, 146, 144, 143, 141, 140, 139, 137, 136, 135, 134,
39 133, 133, 132, 131, 131, 130, 130, 129, 129, 129, 129, 129, 129, 129, 129,
40 129, 129, 130, 130, 131, 131, 132, 133, 134, 135, 136, 137, 138, 139, 141,
41 142, 143, 145, 146, 148, 150, 151, 153, 155, 157, 159, 161, 163, 166, 168,
42 170, 172, 175, 177, 180, 182, 185, 188, 190, 193, 196, 198, 201, 204, 207,
43 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240, 243, 247, 250, 253,
46constexpr uint8_t kExpectedType2FunctionSamples[] = {
47 26, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
48 25, 25, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
49 24, 24, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
50 23, 23, 23, 23, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
51 22, 22, 22, 22, 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
52 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
53 20, 20, 20, 20, 20, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
54 19, 19, 19, 19, 19, 19, 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
55 18, 18, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
56 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
57 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15,
58 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14,
59 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13,
60 13, 13, 13, 13, 13, 13, 13, 13, 13};
62constexpr uint8_t kExpectedType4FunctionSamples[] = {
63 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
64 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
65 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
66 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
67 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
68 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
69 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
70 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
71 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26,
72 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
73 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
74 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
75 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
76 26, 26, 26, 26, 26, 26, 26, 26, 26};
78RetainPtr<CPDF_Reference> CreateType0FunctionStreamReference(
81 func_dict->SetNewFor<CPDF_Number>(
"FunctionType", 0);
82 func_dict->SetNewFor<CPDF_Number>(
"BitsPerSample", 8);
84 auto domain_array = func_dict->SetNewFor<
CPDF_Array>(
"Domain");
85 domain_array->AppendNew<CPDF_Number>(0);
86 domain_array->AppendNew<CPDF_Number>(1);
88 auto range_array = func_dict->SetNewFor<
CPDF_Array>(
"Range");
89 range_array->AppendNew<CPDF_Number>(0);
90 range_array->AppendNew<CPDF_Number>(0.5f);
92 auto size_array = func_dict->SetNewFor<
CPDF_Array>(
"Size");
93 size_array->AppendNew<CPDF_Number>(4);
95 static constexpr uint8_t kContents[] =
"1234";
96 auto stream = holder.NewIndirect<CPDF_Stream>(
97 DataVector<uint8_t>(
std::begin(kContents),
std::end(kContents)),
98 std::move(func_dict));
99 return pdfium::MakeRetain<CPDF_Reference>(&holder, stream->GetObjNum());
104 func_dict->SetNewFor<CPDF_Number>(
"FunctionType", 2);
105 func_dict->SetNewFor<CPDF_Number>(
"N", 1);
107 auto domain_array = func_dict->SetNewFor<
CPDF_Array>(
"Domain");
108 domain_array->AppendNew<CPDF_Number>(0);
109 domain_array->AppendNew<CPDF_Number>(1);
111 auto c0_array = func_dict->SetNewFor<
CPDF_Array>(
"C0");
112 c0_array->AppendNew<CPDF_Number>(0.1f);
113 c0_array->AppendNew<CPDF_Number>(0.2f);
114 c0_array->AppendNew<CPDF_Number>(0.8f);
116 auto c1_array = func_dict->SetNewFor<
CPDF_Array>(
"C1");
117 c1_array->AppendNew<CPDF_Number>(0.05f);
118 c1_array->AppendNew<CPDF_Number>(0.01f);
119 c1_array->AppendNew<CPDF_Number>(0.4f);
124RetainPtr<CPDF_Reference> CreateType4FunctionStreamReference(
127 func_dict->SetNewFor<CPDF_Number>(
"FunctionType", 4);
129 auto domain_array = func_dict->SetNewFor<
CPDF_Array>(
"Domain");
130 domain_array->AppendNew<CPDF_Number>(0);
131 domain_array->AppendNew<CPDF_Number>(1);
133 auto range_array = func_dict->SetNewFor<
CPDF_Array>(
"Range");
134 range_array->AppendNew<CPDF_Number>(-1);
135 range_array->AppendNew<CPDF_Number>(1);
137 static constexpr uint8_t kContents[] =
"{ 360 mul sin 2 div }";
138 auto stream = holder.NewIndirect<CPDF_Stream>(
139 DataVector<uint8_t>(
std::begin(kContents),
std::end(kContents)),
140 std::move(func_dict));
141 return pdfium::MakeRetain<CPDF_Reference>(&holder, stream->GetObjNum());
144RetainPtr<CPDF_Stream> CreateBadType4FunctionStream() {
146 func_dict->SetNewFor<CPDF_Number>(
"FunctionType", 4);
148 auto domain_array = func_dict->SetNewFor<
CPDF_Array>(
"Domain");
149 domain_array->AppendNew<CPDF_Number>(0);
150 domain_array->AppendNew<CPDF_Number>(1);
152 auto range_array = func_dict->SetNewFor<
CPDF_Array>(
"Range");
153 range_array->AppendNew<CPDF_Number>(-1);
154 range_array->AppendNew<CPDF_Number>(1);
156 static constexpr uint8_t kContents[] =
"garbage";
157 return pdfium::MakeRetain<CPDF_Stream>(
158 DataVector<uint8_t>(
std::begin(kContents),
std::end(kContents)),
159 std::move(func_dict));
164 TestDocRenderData() =
default;
166 RetainPtr<CPDF_TransferFunc> CreateTransferFuncForTesting(
172TEST(CPDF_DocRenderDataTest, TransferFunctionOne) {
175 TestDocRenderData render_data;
176 auto func = render_data.CreateTransferFuncForTesting(func_dict);
178 EXPECT_FALSE(func->GetIdentity());
179 EXPECT_THAT(func->GetSamplesR(),
180 ElementsAreArray(kExpectedType2FunctionSamples));
181 EXPECT_THAT(func->GetSamplesG(),
182 ElementsAreArray(kExpectedType2FunctionSamples));
183 EXPECT_THAT(func->GetSamplesB(),
184 ElementsAreArray(kExpectedType2FunctionSamples));
185 EXPECT_EQ(0x000d0d0du, func->TranslateColor(0x00ffffff));
186 EXPECT_EQ(0x000d1a1au, func->TranslateColor(0x00ff0000));
187 EXPECT_EQ(0x001a0d1au, func->TranslateColor(0x0000ff00));
188 EXPECT_EQ(0x001a1a0du, func->TranslateColor(0x000000ff));
189 EXPECT_EQ(0x000f0f0fu, func->TranslateColor(0x00cccccc));
190 EXPECT_EQ(0x00191715u, func->TranslateColor(0x00123456));
191 EXPECT_EQ(0x000d0d0du, func->TranslateColor(0xffffffff));
192 EXPECT_EQ(0x001a1a1au, func->TranslateColor(0xff000000));
193 EXPECT_EQ(0x000d0d0du, func->TranslateColor(0xccffffff));
194 EXPECT_EQ(0x001a1a1au, func->TranslateColor(0x99000000));
197TEST(CPDF_DocRenderDataTest, TransferFunctionArray) {
200 func_array->Append(CreateType0FunctionStreamReference(holder));
201 func_array->Append(CreateType2FunctionDict());
202 func_array->Append(CreateType4FunctionStreamReference(holder));
204 TestDocRenderData render_data;
205 auto func = render_data.CreateTransferFuncForTesting(func_array);
207 EXPECT_FALSE(func->GetIdentity());
208 EXPECT_THAT(func->GetSamplesR(),
209 ElementsAreArray(kExpectedType0FunctionSamples));
210 EXPECT_THAT(func->GetSamplesG(),
211 ElementsAreArray(kExpectedType2FunctionSamples));
212 EXPECT_THAT(func->GetSamplesB(),
213 ElementsAreArray(kExpectedType4FunctionSamples));
214 EXPECT_EQ(0x001a0d00u, func->TranslateColor(0x00ffffff));
215 EXPECT_EQ(0x001a1a00u, func->TranslateColor(0x00ff0000));
216 EXPECT_EQ(0x00190d00u, func->TranslateColor(0x0000ff00));
217 EXPECT_EQ(0x00191a00u, func->TranslateColor(0x000000ff));
218 EXPECT_EQ(0x001a0f87u, func->TranslateColor(0x00cccccc));
219 EXPECT_EQ(0x0019176du, func->TranslateColor(0x00123456));
220 EXPECT_EQ(0x001a0d00u, func->TranslateColor(0xffffffff));
221 EXPECT_EQ(0x00191a00u, func->TranslateColor(0xff000000));
222 EXPECT_EQ(0x001a0d00u, func->TranslateColor(0xccffffff));
223 EXPECT_EQ(0x00191a00u, func->TranslateColor(0x99000000));
226TEST(CPDF_DocRenderDataTest, BadTransferFunctions) {
228 auto func_stream = CreateBadType4FunctionStream();
230 TestDocRenderData render_data;
231 auto func = render_data.CreateTransferFuncForTesting(func_stream);
238 TestDocRenderData render_data;
239 auto func = render_data.CreateTransferFuncForTesting(func_array);
246 func_array->Append(CreateType0FunctionStreamReference(holder));
247 func_array->Append(CreateType2FunctionDict());
248 auto func_stream = CreateBadType4FunctionStream();
249 const int func_stream_object_number =
252 pdfium::MakeRetain<CPDF_Reference>(&holder, func_stream_object_number));
254 TestDocRenderData render_data;
255 auto func = render_data.CreateTransferFuncForTesting(func_array);
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
RetainPtr< CPDF_TransferFunc > CreateTransferFunc(RetainPtr< const CPDF_Object > pObj) const
uint32_t AddIndirectObject(RetainPtr< CPDF_Object > pObj)