xref: /aosp_15_r20/external/pdfium/core/fxge/dib/cstretchengine_unittest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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