| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <math.h> |
| 6 | 6 |
| 7 #include "base/gfx/png_encoder.h" | 7 #include "base/gfx/png_encoder.h" |
| 8 #include "base/gfx/png_decoder.h" | 8 #include "base/gfx/png_decoder.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 #include "third_party/skia/include/core/SkBitmap.h" |
| 10 | 11 |
| 11 static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) { | 12 static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) { |
| 12 dat->resize(w * h * 3); | 13 dat->resize(w * h * 3); |
| 13 for (int y = 0; y < h; y++) { | 14 for (int y = 0; y < h; y++) { |
| 14 for (int x = 0; x < w; x++) { | 15 for (int x = 0; x < w; x++) { |
| 15 unsigned char* org_px = &(*dat)[(y * w + x) * 3]; | 16 unsigned char* org_px = &(*dat)[(y * w + x) * 3]; |
| 16 org_px[0] = x * 3; // r | 17 org_px[0] = x * 3; // r |
| 17 org_px[1] = x * 3 + 1; // g | 18 org_px[1] = x * 3 + 1; // g |
| 18 org_px[2] = x * 3 + 2; // b | 19 org_px[2] = x * 3 + 2; // b |
| 19 } | 20 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 34 org_px[1] = x * 3 + 1; // g | 35 org_px[1] = x * 3 + 1; // g |
| 35 org_px[2] = x * 3 + 2; // b | 36 org_px[2] = x * 3 + 2; // b |
| 36 if (use_transparency) | 37 if (use_transparency) |
| 37 org_px[3] = x*3 + 3; // a | 38 org_px[3] = x*3 + 3; // a |
| 38 else | 39 else |
| 39 org_px[3] = 0xFF; // a (opaque) | 40 org_px[3] = 0xFF; // a (opaque) |
| 40 } | 41 } |
| 41 } | 42 } |
| 42 } | 43 } |
| 43 | 44 |
| 45 // Returns true if each channel of the given two colors are "close." This is |
| 46 // used for comparing colors where rounding errors may cause off-by-one. |
| 47 bool ColorsClose(uint32_t a, uint32_t b) { |
| 48 return abs(static_cast<int>(SkColorGetB(a) - SkColorGetB(b))) < 2 && |
| 49 abs(static_cast<int>(SkColorGetG(a) - SkColorGetG(b))) < 2 && |
| 50 abs(static_cast<int>(SkColorGetR(a) - SkColorGetR(b))) < 2 && |
| 51 abs(static_cast<int>(SkColorGetA(a) - SkColorGetA(b))) < 2; |
| 52 } |
| 53 |
| 54 void MakeTestSkBitmap(int w, int h, SkBitmap* bmp) { |
| 55 bmp->setConfig(SkBitmap::kARGB_8888_Config, w, h); |
| 56 bmp->allocPixels(); |
| 57 |
| 58 uint32_t* src_data = bmp->getAddr32(0, 0); |
| 59 for (int i = 0; i < w * h; i++) { |
| 60 src_data[i] = SkPreMultiplyARGB(i % 255, i % 250, i % 245, i % 240); |
| 61 } |
| 62 } |
| 63 |
| 44 TEST(PNGCodec, EncodeDecodeRGB) { | 64 TEST(PNGCodec, EncodeDecodeRGB) { |
| 45 const int w = 20, h = 20; | 65 const int w = 20, h = 20; |
| 46 | 66 |
| 47 // create an image with known values | 67 // create an image with known values |
| 48 std::vector<unsigned char> original; | 68 std::vector<unsigned char> original; |
| 49 MakeRGBImage(w, h, &original); | 69 MakeRGBImage(w, h, &original); |
| 50 | 70 |
| 51 // encode | 71 // encode |
| 52 std::vector<unsigned char> encoded; | 72 std::vector<unsigned char> encoded; |
| 53 EXPECT_TRUE(PNGEncoder::Encode(&original[0], PNGEncoder::FORMAT_RGB, w, h, | 73 EXPECT_TRUE(PNGEncoder::Encode(&original[0], PNGEncoder::FORMAT_RGB, w, h, |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(), | 213 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(), |
| 194 PNGDecoder::FORMAT_RGB, &decoded, | 214 PNGDecoder::FORMAT_RGB, &decoded, |
| 195 &outw, &outh)); | 215 &outw, &outh)); |
| 196 | 216 |
| 197 // It should be the same as our non-alpha-channel reference. | 217 // It should be the same as our non-alpha-channel reference. |
| 198 ASSERT_EQ(w, outw); | 218 ASSERT_EQ(w, outw); |
| 199 ASSERT_EQ(h, outh); | 219 ASSERT_EQ(h, outh); |
| 200 ASSERT_EQ(original_rgb.size(), decoded.size()); | 220 ASSERT_EQ(original_rgb.size(), decoded.size()); |
| 201 ASSERT_TRUE(original_rgb == decoded); | 221 ASSERT_TRUE(original_rgb == decoded); |
| 202 } | 222 } |
| 223 |
| 224 TEST(PNGCodec, EncodeBGRASkBitmap) { |
| 225 const int w = 20, h = 20; |
| 226 |
| 227 SkBitmap original_bitmap; |
| 228 MakeTestSkBitmap(w, h, &original_bitmap); |
| 229 |
| 230 // Encode the bitmap. |
| 231 std::vector<unsigned char> encoded; |
| 232 PNGEncoder::EncodeBGRASkBitmap(original_bitmap, false, &encoded); |
| 233 |
| 234 // Decode the encoded string. |
| 235 SkBitmap decoded_bitmap; |
| 236 EXPECT_TRUE(PNGDecoder::Decode(&encoded, &decoded_bitmap)); |
| 237 |
| 238 // Compare the original bitmap and the output bitmap. We use ColorsClose |
| 239 // as SkBitmaps are considered to be pre-multiplied, the unpremultiplication |
| 240 // (in Encode) and repremultiplication (in Decode) can be lossy. |
| 241 for (int x = 0; x < w; x++) { |
| 242 for (int y = 0; y < h; y++) { |
| 243 uint32_t original_pixel = original_bitmap.getAddr32(0, y)[x]; |
| 244 uint32_t decoded_pixel = decoded_bitmap.getAddr32(0, y)[x]; |
| 245 EXPECT_TRUE(ColorsClose(original_pixel, decoded_pixel)); |
| 246 } |
| 247 } |
| 248 } |
| 249 |
| OLD | NEW |