1 // Copyright 2017 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/fxge/dib/cstretchengine.h"
6
7 #include <utility>
8
9 #include "core/fpdfapi/page/cpdf_dib.h"
10 #include "core/fpdfapi/parser/cpdf_dictionary.h"
11 #include "core/fpdfapi/parser/cpdf_number.h"
12 #include "core/fpdfapi/parser/cpdf_stream.h"
13 #include "core/fxge/dib/fx_dib.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace {
17
18 // Discovered experimentally
19 constexpr uint32_t kTooBigSrcLen = 20;
20 constexpr uint32_t kTooBigDestLen = 32 * 1024 * 1024 + 1;
21
PixelWeightSum(const CStretchEngine::PixelWeight * weights)22 uint32_t PixelWeightSum(const CStretchEngine::PixelWeight* weights) {
23 uint32_t sum = 0;
24 for (int i = weights->m_SrcStart; i <= weights->m_SrcEnd; ++i) {
25 sum += weights->GetWeightForPosition(i);
26 }
27 return sum;
28 }
29
ExecuteOneStretchTest(int32_t dest_width,int32_t src_width,const FXDIB_ResampleOptions & options)30 void ExecuteOneStretchTest(int32_t dest_width,
31 int32_t src_width,
32 const FXDIB_ResampleOptions& options) {
33 constexpr uint32_t kExpectedSum = CStretchEngine::kFixedPointOne;
34 CStretchEngine::WeightTable table;
35 ASSERT_TRUE(table.CalculateWeights(dest_width, 0, dest_width, src_width, 0,
36 src_width, options));
37 for (int32_t i = 0; i < dest_width; ++i) {
38 EXPECT_EQ(kExpectedSum, PixelWeightSum(table.GetPixelWeight(i)))
39 << "for { " << src_width << ", " << dest_width << " } at " << i;
40 }
41 }
42
ExecuteOneReversedStretchTest(int32_t dest_width,int32_t src_width,const FXDIB_ResampleOptions & options)43 void ExecuteOneReversedStretchTest(int32_t dest_width,
44 int32_t src_width,
45 const FXDIB_ResampleOptions& options) {
46 constexpr uint32_t kExpectedSum = CStretchEngine::kFixedPointOne;
47 CStretchEngine::WeightTable table;
48 ASSERT_TRUE(table.CalculateWeights(-dest_width, 0, dest_width, src_width, 0,
49 src_width, options));
50 for (int32_t i = 0; i < dest_width; ++i) {
51 EXPECT_EQ(kExpectedSum, PixelWeightSum(table.GetPixelWeight(i)))
52 << "for { " << src_width << ", " << dest_width << " } at " << i
53 << " (reversed)";
54 }
55 }
56
ExecuteStretchTests(const FXDIB_ResampleOptions & options)57 void ExecuteStretchTests(const FXDIB_ResampleOptions& options) {
58 // Can't test everything, few random values chosen.
59 constexpr int32_t kDestWidths[] = {1, 2, 337, 512, 808, 2550};
60 constexpr int32_t kSrcWidths[] = {1, 2, 187, 256, 809, 1110};
61 for (int32_t src_width : kSrcWidths) {
62 for (int32_t dest_width : kDestWidths) {
63 ExecuteOneStretchTest(dest_width, src_width, options);
64 ExecuteOneReversedStretchTest(dest_width, src_width, options);
65 }
66 }
67 }
68
69 } // namespace
70
TEST(CStretchEngine,OverflowInCtor)71 TEST(CStretchEngine, OverflowInCtor) {
72 FX_RECT clip_rect;
73 RetainPtr<CPDF_Dictionary> dict_obj = pdfium::MakeRetain<CPDF_Dictionary>();
74 dict_obj->SetNewFor<CPDF_Number>("Width", 71000);
75 dict_obj->SetNewFor<CPDF_Number>("Height", 12500);
76 RetainPtr<CPDF_Stream> stream =
77 pdfium::MakeRetain<CPDF_Stream>(std::move(dict_obj));
78 auto dib_source = pdfium::MakeRetain<CPDF_DIB>(nullptr, stream);
79 dib_source->Load();
80 CStretchEngine engine(nullptr, FXDIB_Format::k8bppRgb, 500, 500, clip_rect,
81 dib_source, FXDIB_ResampleOptions());
82 EXPECT_TRUE(engine.GetResampleOptionsForTest().bInterpolateBilinear);
83 EXPECT_FALSE(engine.GetResampleOptionsForTest().bHalftone);
84 EXPECT_FALSE(engine.GetResampleOptionsForTest().bNoSmoothing);
85 EXPECT_FALSE(engine.GetResampleOptionsForTest().bLossy);
86 }
87
TEST(CStretchEngine,WeightRounding)88 TEST(CStretchEngine, WeightRounding) {
89 FXDIB_ResampleOptions options;
90 ExecuteStretchTests(options);
91 }
92
TEST(CStretchEngine,WeightRoundingNoSmoothing)93 TEST(CStretchEngine, WeightRoundingNoSmoothing) {
94 FXDIB_ResampleOptions options;
95 options.bNoSmoothing = true;
96 ExecuteStretchTests(options);
97 }
98
TEST(CStretchEngine,WeightRoundingBilinear)99 TEST(CStretchEngine, WeightRoundingBilinear) {
100 FXDIB_ResampleOptions options;
101 options.bInterpolateBilinear = true;
102 ExecuteStretchTests(options);
103 }
104
TEST(CStretchEngine,WeightRoundingNoSmoothingBilinear)105 TEST(CStretchEngine, WeightRoundingNoSmoothingBilinear) {
106 FXDIB_ResampleOptions options;
107 options.bNoSmoothing = true;
108 options.bInterpolateBilinear = true;
109 ExecuteStretchTests(options);
110 }
111
TEST(CStretchEngine,ZeroLengthSrc)112 TEST(CStretchEngine, ZeroLengthSrc) {
113 FXDIB_ResampleOptions options;
114 CStretchEngine::WeightTable table;
115 ASSERT_TRUE(table.CalculateWeights(100, 0, 100, 0, 0, 0, options));
116 }
117
TEST(CStretchEngine,ZeroLengthSrcNoSmoothing)118 TEST(CStretchEngine, ZeroLengthSrcNoSmoothing) {
119 FXDIB_ResampleOptions options;
120 options.bNoSmoothing = true;
121 CStretchEngine::WeightTable table;
122 ASSERT_TRUE(table.CalculateWeights(100, 0, 100, 0, 0, 0, options));
123 }
124
TEST(CStretchEngine,ZeroLengthSrcBilinear)125 TEST(CStretchEngine, ZeroLengthSrcBilinear) {
126 FXDIB_ResampleOptions options;
127 options.bInterpolateBilinear = true;
128 CStretchEngine::WeightTable table;
129 ASSERT_TRUE(table.CalculateWeights(100, 0, 100, 0, 0, 0, options));
130 }
131
TEST(CStretchEngine,ZeroLengthSrcNoSmoothingBilinear)132 TEST(CStretchEngine, ZeroLengthSrcNoSmoothingBilinear) {
133 FXDIB_ResampleOptions options;
134 options.bNoSmoothing = true;
135 options.bInterpolateBilinear = true;
136 CStretchEngine::WeightTable table;
137 ASSERT_TRUE(table.CalculateWeights(100, 0, 100, 0, 0, 0, options));
138 }
139
TEST(CStretchEngine,ZeroLengthDest)140 TEST(CStretchEngine, ZeroLengthDest) {
141 FXDIB_ResampleOptions options;
142 CStretchEngine::WeightTable table;
143 ASSERT_TRUE(table.CalculateWeights(0, 0, 0, 100, 0, 100, options));
144 }
145
TEST(CStretchEngine,TooManyWeights)146 TEST(CStretchEngine, TooManyWeights) {
147 FXDIB_ResampleOptions options;
148 CStretchEngine::WeightTable table;
149 ASSERT_FALSE(table.CalculateWeights(kTooBigDestLen, 0, kTooBigDestLen,
150 kTooBigSrcLen, 0, kTooBigSrcLen,
151 options));
152 }
153