| 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 |