1 // Copyright 2018 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/cfx_dibitmap.h"
6
7 #include <stdint.h>
8
9 #include "core/fxcrt/fx_coordinates.h"
10 #include "core/fxge/dib/fx_dib.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/base/span.h"
14
15 namespace {
16
17 using ::testing::ElementsAre;
18
19 } // namespace
20
TEST(CFX_DIBitmap,Create)21 TEST(CFX_DIBitmap, Create) {
22 auto pBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
23 EXPECT_FALSE(pBitmap->Create(400, 300, FXDIB_Format::kInvalid));
24
25 pBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
26 EXPECT_TRUE(pBitmap->Create(400, 300, FXDIB_Format::k1bppRgb));
27 }
28
TEST(CFX_DIBitmap,CalculatePitchAndSizeGood)29 TEST(CFX_DIBitmap, CalculatePitchAndSizeGood) {
30 // Simple case with no provided pitch.
31 absl::optional<CFX_DIBitmap::PitchAndSize> result =
32 CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::kArgb, 0);
33 ASSERT_TRUE(result.has_value());
34 EXPECT_EQ(400u, result.value().pitch);
35 EXPECT_EQ(80000u, result.value().size);
36
37 // Simple case with no provided pitch and different format.
38 result =
39 CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::k8bppRgb, 0);
40 ASSERT_TRUE(result.has_value());
41 EXPECT_EQ(100u, result.value().pitch);
42 EXPECT_EQ(20000u, result.value().size);
43
44 // Simple case with provided pitch.
45 result =
46 CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::kArgb, 400);
47 ASSERT_TRUE(result.has_value());
48 EXPECT_EQ(400u, result.value().pitch);
49 EXPECT_EQ(80000u, result.value().size);
50
51 // Simple case with provided pitch, but pitch does not match width * bpp.
52 result =
53 CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::kArgb, 355);
54 ASSERT_TRUE(result.has_value());
55 EXPECT_EQ(355u, result.value().pitch);
56 EXPECT_EQ(71000u, result.value().size);
57 }
58
TEST(CFX_DIBitmap,CalculatePitchAndSizeBad)59 TEST(CFX_DIBitmap, CalculatePitchAndSizeBad) {
60 // Bad width / height.
61 static const CFX_Size kBadDimensions[] = {
62 {0, 0}, {-1, -1}, {-1, 0}, {0, -1},
63 {0, 200}, {100, 0}, {-1, 200}, {100, -1},
64 };
65 for (const auto& dimension : kBadDimensions) {
66 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(
67 dimension.width, dimension.height, FXDIB_Format::kArgb, 0));
68 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(
69 dimension.width, dimension.height, FXDIB_Format::kArgb, 1));
70 }
71
72 // Bad format.
73 EXPECT_FALSE(
74 CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::kInvalid, 0));
75 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(
76 100, 200, FXDIB_Format::kInvalid, 800));
77
78 // Overflow cases with calculated pitch.
79 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(1073747000, 1,
80 FXDIB_Format::kArgb, 0));
81 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(1048576, 1024,
82 FXDIB_Format::kArgb, 0));
83 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(4194304, 1024,
84 FXDIB_Format::k8bppRgb, 0));
85
86 // Overflow cases with provided pitch.
87 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(
88 2147484000u, 1, FXDIB_Format::kArgb, 2147484000u));
89 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(
90 1048576, 1024, FXDIB_Format::kArgb, 4194304));
91 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(
92 4194304, 1024, FXDIB_Format::k8bppRgb, 4194304));
93 }
94
TEST(CFX_DIBitmap,CalculatePitchAndSizeBoundary)95 TEST(CFX_DIBitmap, CalculatePitchAndSizeBoundary) {
96 // Test boundary condition for pitch overflow.
97 absl::optional<CFX_DIBitmap::PitchAndSize> result =
98 CFX_DIBitmap::CalculatePitchAndSize(536870908, 4, FXDIB_Format::k8bppRgb,
99 0);
100 ASSERT_TRUE(result);
101 EXPECT_EQ(536870908u, result.value().pitch);
102 EXPECT_EQ(2147483632u, result.value().size);
103 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(536870909, 4,
104 FXDIB_Format::k8bppRgb, 0));
105
106 // Test boundary condition for size overflow.
107 result = CFX_DIBitmap::CalculatePitchAndSize(68174084, 63,
108 FXDIB_Format::k8bppRgb, 0);
109 ASSERT_TRUE(result);
110 EXPECT_EQ(68174084u, result.value().pitch);
111 EXPECT_EQ(4294967292u, result.value().size);
112 EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(68174085, 63,
113 FXDIB_Format::k8bppRgb, 0));
114 }
115
116 #if defined(_SKIA_SUPPORT_)
TEST(CFX_DIBitmap,PreMultiply_FromCleared)117 TEST(CFX_DIBitmap, PreMultiply_FromCleared) {
118 auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
119 ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
120 FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'ff'ff'ff);
121
122 bitmap->PreMultiply();
123
124 EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0x7f, 0x7f, 0x7f, 0x7f));
125 }
126
TEST(CFX_DIBitmap,UnPreMultiply_FromCleared)127 TEST(CFX_DIBitmap, UnPreMultiply_FromCleared) {
128 auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
129 ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
130 FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'7f'7f'7f);
131
132 bitmap->UnPreMultiply();
133
134 EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0xff, 0xff, 0xff, 0x7f));
135 }
136
TEST(CFX_DIBitmap,PreMultiply_FromPreMultiplied)137 TEST(CFX_DIBitmap, PreMultiply_FromPreMultiplied) {
138 auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
139 ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
140 bitmap->PreMultiply();
141 FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'7f'7f'7f);
142
143 bitmap->PreMultiply();
144
145 EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0x7f, 0x7f, 0x7f, 0x7f));
146 }
147
TEST(CFX_DIBitmap,UnPreMultiply_FromPreMultiplied)148 TEST(CFX_DIBitmap, UnPreMultiply_FromPreMultiplied) {
149 auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
150 ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
151 bitmap->PreMultiply();
152 FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'7f'7f'7f);
153
154 bitmap->UnPreMultiply();
155
156 EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0xff, 0xff, 0xff, 0x7f));
157 }
158
TEST(CFX_DIBitmap,PreMultiply_FromUnPreMultiplied)159 TEST(CFX_DIBitmap, PreMultiply_FromUnPreMultiplied) {
160 auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
161 ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
162 bitmap->UnPreMultiply();
163 FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'ff'ff'ff);
164
165 bitmap->PreMultiply();
166
167 EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0x7f, 0x7f, 0x7f, 0x7f));
168 }
169
TEST(CFX_DIBitmap,UnPreMultiply_FromUnPreMultiplied)170 TEST(CFX_DIBitmap, UnPreMultiply_FromUnPreMultiplied) {
171 auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
172 ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
173 bitmap->UnPreMultiply();
174 FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'ff'ff'ff);
175
176 bitmap->UnPreMultiply();
177
178 EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0xff, 0xff, 0xff, 0x7f));
179 }
180
TEST(CFX_DIBitmap,ForcePreMultiply)181 TEST(CFX_DIBitmap, ForcePreMultiply) {
182 auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
183 ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
184 FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'7f'7f'7f);
185
186 bitmap->ForcePreMultiply();
187
188 bitmap->PreMultiply();
189 EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0x7f, 0x7f, 0x7f, 0x7f));
190 }
191
TEST(CFX_DIBitmap,ForceUnPreMultiply)192 TEST(CFX_DIBitmap, ForceUnPreMultiply) {
193 auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
194 ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
195 FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'ff'ff'ff);
196
197 bitmap->ForceUnPreMultiply();
198
199 bitmap->UnPreMultiply();
200 EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0xff, 0xff, 0xff, 0x7f));
201 }
202 #endif // defined(_SKIA_SUPPORT_)
203