OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <math.h> | 5 #include <algorithm> |
| 6 #include <cmath> |
6 | 7 |
7 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
8 #include "third_party/skia/include/core/SkBitmap.h" | 9 #include "third_party/skia/include/core/SkBitmap.h" |
9 #include "third_party/skia/include/core/SkUnPreMultiply.h" | 10 #include "third_party/skia/include/core/SkUnPreMultiply.h" |
10 #include "ui/gfx/codec/png_codec.h" | 11 #include "ui/gfx/codec/png_codec.h" |
| 12 #include "ui/gfx/size.h" |
11 | 13 |
12 namespace gfx { | 14 namespace gfx { |
13 | 15 |
14 static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) { | 16 static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) { |
15 dat->resize(w * h * 3); | 17 dat->resize(w * h * 3); |
16 for (int y = 0; y < h; y++) { | 18 for (int y = 0; y < h; y++) { |
17 for (int x = 0; x < w; x++) { | 19 for (int x = 0; x < w; x++) { |
18 unsigned char* org_px = &(*dat)[(y * w + x) * 3]; | 20 unsigned char* org_px = &(*dat)[(y * w + x) * 3]; |
19 org_px[0] = x * 3; // r | 21 org_px[0] = x * 3; // r |
20 org_px[1] = x * 3 + 1; // g | 22 org_px[1] = x * 3 + 1; // g |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 | 74 |
73 TEST(PNGCodec, EncodeDecodeRGB) { | 75 TEST(PNGCodec, EncodeDecodeRGB) { |
74 const int w = 20, h = 20; | 76 const int w = 20, h = 20; |
75 | 77 |
76 // create an image with known values | 78 // create an image with known values |
77 std::vector<unsigned char> original; | 79 std::vector<unsigned char> original; |
78 MakeRGBImage(w, h, &original); | 80 MakeRGBImage(w, h, &original); |
79 | 81 |
80 // encode | 82 // encode |
81 std::vector<unsigned char> encoded; | 83 std::vector<unsigned char> encoded; |
82 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, w, h, | 84 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, |
83 w * 3, false, &encoded)); | 85 Size(w, h), w * 3, false, |
| 86 std::vector<PNGCodec::Comment>(), |
| 87 &encoded)); |
84 | 88 |
85 // decode, it should have the same size as the original | 89 // decode, it should have the same size as the original |
86 std::vector<unsigned char> decoded; | 90 std::vector<unsigned char> decoded; |
87 int outw, outh; | 91 int outw, outh; |
88 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), | 92 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), |
89 PNGCodec::FORMAT_RGB, &decoded, | 93 PNGCodec::FORMAT_RGB, &decoded, |
90 &outw, &outh)); | 94 &outw, &outh)); |
91 ASSERT_EQ(w, outw); | 95 ASSERT_EQ(w, outw); |
92 ASSERT_EQ(h, outh); | 96 ASSERT_EQ(h, outh); |
93 ASSERT_EQ(original.size(), decoded.size()); | 97 ASSERT_EQ(original.size(), decoded.size()); |
94 | 98 |
95 // Images must be equal | 99 // Images must be equal |
96 ASSERT_TRUE(original == decoded); | 100 ASSERT_TRUE(original == decoded); |
97 } | 101 } |
98 | 102 |
99 TEST(PNGCodec, EncodeDecodeRGBA) { | 103 TEST(PNGCodec, EncodeDecodeRGBA) { |
100 const int w = 20, h = 20; | 104 const int w = 20, h = 20; |
101 | 105 |
102 // create an image with known values, a must be opaque because it will be | 106 // create an image with known values, a must be opaque because it will be |
103 // lost during encoding | 107 // lost during encoding |
104 std::vector<unsigned char> original; | 108 std::vector<unsigned char> original; |
105 MakeRGBAImage(w, h, true, &original); | 109 MakeRGBAImage(w, h, true, &original); |
106 | 110 |
107 // encode | 111 // encode |
108 std::vector<unsigned char> encoded; | 112 std::vector<unsigned char> encoded; |
109 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGBA, w, h, | 113 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGBA, |
110 w * 4, false, &encoded)); | 114 Size(w, h), w * 4, false, |
| 115 std::vector<PNGCodec::Comment>(), |
| 116 &encoded)); |
111 | 117 |
112 // decode, it should have the same size as the original | 118 // decode, it should have the same size as the original |
113 std::vector<unsigned char> decoded; | 119 std::vector<unsigned char> decoded; |
114 int outw, outh; | 120 int outw, outh; |
115 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), | 121 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), |
116 PNGCodec::FORMAT_RGBA, &decoded, | 122 PNGCodec::FORMAT_RGBA, &decoded, |
117 &outw, &outh)); | 123 &outw, &outh)); |
118 ASSERT_EQ(w, outw); | 124 ASSERT_EQ(w, outw); |
119 ASSERT_EQ(h, outh); | 125 ASSERT_EQ(h, outh); |
120 ASSERT_EQ(original.size(), decoded.size()); | 126 ASSERT_EQ(original.size(), decoded.size()); |
(...skipping 12 matching lines...) Expand all Loading... |
133 | 139 |
134 // It should fail when given non-JPEG compressed data. | 140 // It should fail when given non-JPEG compressed data. |
135 std::vector<unsigned char> output; | 141 std::vector<unsigned char> output; |
136 int outw, outh; | 142 int outw, outh; |
137 EXPECT_FALSE(PNGCodec::Decode(&original[0], original.size(), | 143 EXPECT_FALSE(PNGCodec::Decode(&original[0], original.size(), |
138 PNGCodec::FORMAT_RGB, &output, | 144 PNGCodec::FORMAT_RGB, &output, |
139 &outw, &outh)); | 145 &outw, &outh)); |
140 | 146 |
141 // Make some compressed data. | 147 // Make some compressed data. |
142 std::vector<unsigned char> compressed; | 148 std::vector<unsigned char> compressed; |
143 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, w, h, | 149 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, |
144 w * 3, false, &compressed)); | 150 Size(w, h), w * 3, false, |
| 151 std::vector<PNGCodec::Comment>(), |
| 152 &compressed)); |
145 | 153 |
146 // Try decompressing a truncated version. | 154 // Try decompressing a truncated version. |
147 EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size() / 2, | 155 EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size() / 2, |
148 PNGCodec::FORMAT_RGB, &output, | 156 PNGCodec::FORMAT_RGB, &output, |
149 &outw, &outh)); | 157 &outw, &outh)); |
150 | 158 |
151 // Corrupt it and try decompressing that. | 159 // Corrupt it and try decompressing that. |
152 for (int i = 10; i < 30; i++) | 160 for (int i = 10; i < 30; i++) |
153 compressed[i] = i; | 161 compressed[i] = i; |
154 EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size(), | 162 EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size(), |
155 PNGCodec::FORMAT_RGB, &output, | 163 PNGCodec::FORMAT_RGB, &output, |
156 &outw, &outh)); | 164 &outw, &outh)); |
157 } | 165 } |
158 | 166 |
159 TEST(PNGCodec, EncodeDecodeBGRA) { | 167 TEST(PNGCodec, EncodeDecodeBGRA) { |
160 const int w = 20, h = 20; | 168 const int w = 20, h = 20; |
161 | 169 |
162 // Create an image with known values, alpha must be opaque because it will be | 170 // Create an image with known values, alpha must be opaque because it will be |
163 // lost during encoding. | 171 // lost during encoding. |
164 std::vector<unsigned char> original; | 172 std::vector<unsigned char> original; |
165 MakeRGBAImage(w, h, true, &original); | 173 MakeRGBAImage(w, h, true, &original); |
166 | 174 |
167 // Encode. | 175 // Encode. |
168 std::vector<unsigned char> encoded; | 176 std::vector<unsigned char> encoded; |
169 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_BGRA, w, h, | 177 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_BGRA, |
170 w * 4, false, &encoded)); | 178 Size(w, h), w * 4, false, |
| 179 std::vector<PNGCodec::Comment>(), |
| 180 &encoded)); |
171 | 181 |
172 // Decode, it should have the same size as the original. | 182 // Decode, it should have the same size as the original. |
173 std::vector<unsigned char> decoded; | 183 std::vector<unsigned char> decoded; |
174 int outw, outh; | 184 int outw, outh; |
175 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), | 185 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), |
176 PNGCodec::FORMAT_BGRA, &decoded, | 186 PNGCodec::FORMAT_BGRA, &decoded, |
177 &outw, &outh)); | 187 &outw, &outh)); |
178 ASSERT_EQ(w, outw); | 188 ASSERT_EQ(w, outw); |
179 ASSERT_EQ(h, outh); | 189 ASSERT_EQ(h, outh); |
180 ASSERT_EQ(original.size(), decoded.size()); | 190 ASSERT_EQ(original.size(), decoded.size()); |
181 | 191 |
182 // Images must be exactly equal. | 192 // Images must be exactly equal. |
183 ASSERT_TRUE(original == decoded); | 193 ASSERT_TRUE(original == decoded); |
184 } | 194 } |
185 | 195 |
186 TEST(PNGCodec, StripAddAlpha) { | 196 TEST(PNGCodec, StripAddAlpha) { |
187 const int w = 20, h = 20; | 197 const int w = 20, h = 20; |
188 | 198 |
189 // These should be the same except one has a 0xff alpha channel. | 199 // These should be the same except one has a 0xff alpha channel. |
190 std::vector<unsigned char> original_rgb; | 200 std::vector<unsigned char> original_rgb; |
191 MakeRGBImage(w, h, &original_rgb); | 201 MakeRGBImage(w, h, &original_rgb); |
192 std::vector<unsigned char> original_rgba; | 202 std::vector<unsigned char> original_rgba; |
193 MakeRGBAImage(w, h, false, &original_rgba); | 203 MakeRGBAImage(w, h, false, &original_rgba); |
194 | 204 |
195 // Encode RGBA data as RGB. | 205 // Encode RGBA data as RGB. |
196 std::vector<unsigned char> encoded; | 206 std::vector<unsigned char> encoded; |
197 EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], | 207 EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], PNGCodec::FORMAT_RGBA, |
198 PNGCodec::FORMAT_RGBA, | 208 Size(w, h), w * 4, true, |
199 w, h, | 209 std::vector<PNGCodec::Comment>(), |
200 w * 4, true, &encoded)); | 210 &encoded)); |
201 | 211 |
202 // Decode the RGB to RGBA. | 212 // Decode the RGB to RGBA. |
203 std::vector<unsigned char> decoded; | 213 std::vector<unsigned char> decoded; |
204 int outw, outh; | 214 int outw, outh; |
205 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), | 215 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), |
206 PNGCodec::FORMAT_RGBA, &decoded, | 216 PNGCodec::FORMAT_RGBA, &decoded, |
207 &outw, &outh)); | 217 &outw, &outh)); |
208 | 218 |
209 // Decoded and reference should be the same (opaque alpha). | 219 // Decoded and reference should be the same (opaque alpha). |
210 ASSERT_EQ(w, outw); | 220 ASSERT_EQ(w, outw); |
211 ASSERT_EQ(h, outh); | 221 ASSERT_EQ(h, outh); |
212 ASSERT_EQ(original_rgba.size(), decoded.size()); | 222 ASSERT_EQ(original_rgba.size(), decoded.size()); |
213 ASSERT_TRUE(original_rgba == decoded); | 223 ASSERT_TRUE(original_rgba == decoded); |
214 | 224 |
215 // Encode RGBA to RGBA. | 225 // Encode RGBA to RGBA. |
216 EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], | 226 EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], PNGCodec::FORMAT_RGBA, |
217 PNGCodec::FORMAT_RGBA, | 227 Size(w, h), w * 4, false, |
218 w, h, | 228 std::vector<PNGCodec::Comment>(), |
219 w * 4, false, &encoded)); | 229 &encoded)); |
220 | 230 |
221 // Decode the RGBA to RGB. | 231 // Decode the RGBA to RGB. |
222 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), | 232 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), |
223 PNGCodec::FORMAT_RGB, &decoded, | 233 PNGCodec::FORMAT_RGB, &decoded, |
224 &outw, &outh)); | 234 &outw, &outh)); |
225 | 235 |
226 // It should be the same as our non-alpha-channel reference. | 236 // It should be the same as our non-alpha-channel reference. |
227 ASSERT_EQ(w, outw); | 237 ASSERT_EQ(w, outw); |
228 ASSERT_EQ(h, outh); | 238 ASSERT_EQ(h, outh); |
229 ASSERT_EQ(original_rgb.size(), decoded.size()); | 239 ASSERT_EQ(original_rgb.size(), decoded.size()); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 << SkColorGetG(unpremultiplied) << ", " | 297 << SkColorGetG(unpremultiplied) << ", " |
288 << SkColorGetB(unpremultiplied) << "), " | 298 << SkColorGetB(unpremultiplied) << "), " |
289 << "Decoded pixel: (" | 299 << "Decoded pixel: (" |
290 << SkColorGetR(decoded_pixel) << ", " | 300 << SkColorGetR(decoded_pixel) << ", " |
291 << SkColorGetG(decoded_pixel) << ", " | 301 << SkColorGetG(decoded_pixel) << ", " |
292 << SkColorGetB(decoded_pixel) << ")"; | 302 << SkColorGetB(decoded_pixel) << ")"; |
293 } | 303 } |
294 } | 304 } |
295 } | 305 } |
296 | 306 |
| 307 TEST(PNGCodec, EncodeWithComment) { |
| 308 const int w = 10, h = 10; |
| 309 |
| 310 std::vector<unsigned char> original; |
| 311 MakeRGBImage(w, h, &original); |
| 312 |
| 313 std::vector<unsigned char> encoded; |
| 314 std::vector<PNGCodec::Comment> comments; |
| 315 comments.push_back(PNGCodec::Comment("key", "text")); |
| 316 comments.push_back(PNGCodec::Comment("test", "something")); |
| 317 comments.push_back(PNGCodec::Comment("have some", "spaces in both")); |
| 318 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, |
| 319 Size(w, h), w * 3, false, comments, &encoded)); |
| 320 |
| 321 // Each chunk is of the form length (4 bytes), chunk type (tEXt), data, |
| 322 // checksum (4 bytes). Make sure we find all of them in the encoded |
| 323 // results. |
| 324 const unsigned char kExpected1[] = |
| 325 "\x00\x00\x00\x08tEXtkey\x00text\x9e\xe7\x66\x51"; |
| 326 const unsigned char kExpected2[] = |
| 327 "\x00\x00\x00\x0etEXttest\x00something\x29\xba\xef\xac"; |
| 328 const unsigned char kExpected3[] = |
| 329 "\x00\x00\x00\x18tEXthave some\x00spaces in both\x8d\x69\x34\x2d"; |
| 330 |
| 331 EXPECT_NE(search(encoded.begin(), encoded.end(), kExpected1, |
| 332 kExpected1 + arraysize(kExpected1)), |
| 333 encoded.end()); |
| 334 EXPECT_NE(search(encoded.begin(), encoded.end(), kExpected2, |
| 335 kExpected2 + arraysize(kExpected2)), |
| 336 encoded.end()); |
| 337 EXPECT_NE(search(encoded.begin(), encoded.end(), kExpected3, |
| 338 kExpected3 + arraysize(kExpected3)), |
| 339 encoded.end()); |
| 340 } |
| 341 |
297 } // namespace gfx | 342 } // namespace gfx |
OLD | NEW |