| 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 "app/gfx/codec/png_codec.h" |
| 8 #include "base/gfx/png_decoder.h" | |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
| 10 #include "third_party/skia/include/core/SkBitmap.h" | 9 #include "third_party/skia/include/core/SkBitmap.h" |
| 11 | 10 |
| 11 namespace gfx { |
| 12 |
| 12 static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) { | 13 static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) { |
| 13 dat->resize(w * h * 3); | 14 dat->resize(w * h * 3); |
| 14 for (int y = 0; y < h; y++) { | 15 for (int y = 0; y < h; y++) { |
| 15 for (int x = 0; x < w; x++) { | 16 for (int x = 0; x < w; x++) { |
| 16 unsigned char* org_px = &(*dat)[(y * w + x) * 3]; | 17 unsigned char* org_px = &(*dat)[(y * w + x) * 3]; |
| 17 org_px[0] = x * 3; // r | 18 org_px[0] = x * 3; // r |
| 18 org_px[1] = x * 3 + 1; // g | 19 org_px[1] = x * 3 + 1; // g |
| 19 org_px[2] = x * 3 + 2; // b | 20 org_px[2] = x * 3 + 2; // b |
| 20 } | 21 } |
| 21 } | 22 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 | 64 |
| 64 TEST(PNGCodec, EncodeDecodeRGB) { | 65 TEST(PNGCodec, EncodeDecodeRGB) { |
| 65 const int w = 20, h = 20; | 66 const int w = 20, h = 20; |
| 66 | 67 |
| 67 // create an image with known values | 68 // create an image with known values |
| 68 std::vector<unsigned char> original; | 69 std::vector<unsigned char> original; |
| 69 MakeRGBImage(w, h, &original); | 70 MakeRGBImage(w, h, &original); |
| 70 | 71 |
| 71 // encode | 72 // encode |
| 72 std::vector<unsigned char> encoded; | 73 std::vector<unsigned char> encoded; |
| 73 EXPECT_TRUE(PNGEncoder::Encode(&original[0], PNGEncoder::FORMAT_RGB, w, h, | 74 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, w, h, |
| 74 w * 3, false, &encoded)); | 75 w * 3, false, &encoded)); |
| 75 | 76 |
| 76 // decode, it should have the same size as the original | 77 // decode, it should have the same size as the original |
| 77 std::vector<unsigned char> decoded; | 78 std::vector<unsigned char> decoded; |
| 78 int outw, outh; | 79 int outw, outh; |
| 79 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(), | 80 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), |
| 80 PNGDecoder::FORMAT_RGB, &decoded, | 81 PNGCodec::FORMAT_RGB, &decoded, |
| 81 &outw, &outh)); | 82 &outw, &outh)); |
| 82 ASSERT_EQ(w, outw); | 83 ASSERT_EQ(w, outw); |
| 83 ASSERT_EQ(h, outh); | 84 ASSERT_EQ(h, outh); |
| 84 ASSERT_EQ(original.size(), decoded.size()); | 85 ASSERT_EQ(original.size(), decoded.size()); |
| 85 | 86 |
| 86 // Images must be equal | 87 // Images must be equal |
| 87 ASSERT_TRUE(original == decoded); | 88 ASSERT_TRUE(original == decoded); |
| 88 } | 89 } |
| 89 | 90 |
| 90 TEST(PNGCodec, EncodeDecodeRGBA) { | 91 TEST(PNGCodec, EncodeDecodeRGBA) { |
| 91 const int w = 20, h = 20; | 92 const int w = 20, h = 20; |
| 92 | 93 |
| 93 // create an image with known values, a must be opaque because it will be | 94 // create an image with known values, a must be opaque because it will be |
| 94 // lost during encoding | 95 // lost during encoding |
| 95 std::vector<unsigned char> original; | 96 std::vector<unsigned char> original; |
| 96 MakeRGBAImage(w, h, true, &original); | 97 MakeRGBAImage(w, h, true, &original); |
| 97 | 98 |
| 98 // encode | 99 // encode |
| 99 std::vector<unsigned char> encoded; | 100 std::vector<unsigned char> encoded; |
| 100 EXPECT_TRUE(PNGEncoder::Encode(&original[0], PNGEncoder::FORMAT_RGBA, w, h, | 101 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGBA, w, h, |
| 101 w * 4, false, &encoded)); | 102 w * 4, false, &encoded)); |
| 102 | 103 |
| 103 // decode, it should have the same size as the original | 104 // decode, it should have the same size as the original |
| 104 std::vector<unsigned char> decoded; | 105 std::vector<unsigned char> decoded; |
| 105 int outw, outh; | 106 int outw, outh; |
| 106 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(), | 107 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), |
| 107 PNGDecoder::FORMAT_RGBA, &decoded, | 108 PNGCodec::FORMAT_RGBA, &decoded, |
| 108 &outw, &outh)); | 109 &outw, &outh)); |
| 109 ASSERT_EQ(w, outw); | 110 ASSERT_EQ(w, outw); |
| 110 ASSERT_EQ(h, outh); | 111 ASSERT_EQ(h, outh); |
| 111 ASSERT_EQ(original.size(), decoded.size()); | 112 ASSERT_EQ(original.size(), decoded.size()); |
| 112 | 113 |
| 113 // Images must be exactly equal | 114 // Images must be exactly equal |
| 114 ASSERT_TRUE(original == decoded); | 115 ASSERT_TRUE(original == decoded); |
| 115 } | 116 } |
| 116 | 117 |
| 117 // Test that corrupted data decompression causes failures. | 118 // Test that corrupted data decompression causes failures. |
| 118 TEST(PNGCodec, DecodeCorrupted) { | 119 TEST(PNGCodec, DecodeCorrupted) { |
| 119 int w = 20, h = 20; | 120 int w = 20, h = 20; |
| 120 | 121 |
| 121 // Make some random data (an uncompressed image). | 122 // Make some random data (an uncompressed image). |
| 122 std::vector<unsigned char> original; | 123 std::vector<unsigned char> original; |
| 123 MakeRGBImage(w, h, &original); | 124 MakeRGBImage(w, h, &original); |
| 124 | 125 |
| 125 // It should fail when given non-JPEG compressed data. | 126 // It should fail when given non-JPEG compressed data. |
| 126 std::vector<unsigned char> output; | 127 std::vector<unsigned char> output; |
| 127 int outw, outh; | 128 int outw, outh; |
| 128 EXPECT_FALSE(PNGDecoder::Decode(&original[0], original.size(), | 129 EXPECT_FALSE(PNGCodec::Decode(&original[0], original.size(), |
| 129 PNGDecoder::FORMAT_RGB, &output, | 130 PNGCodec::FORMAT_RGB, &output, |
| 130 &outw, &outh)); | 131 &outw, &outh)); |
| 131 | 132 |
| 132 // Make some compressed data. | 133 // Make some compressed data. |
| 133 std::vector<unsigned char> compressed; | 134 std::vector<unsigned char> compressed; |
| 134 EXPECT_TRUE(PNGEncoder::Encode(&original[0], PNGEncoder::FORMAT_RGB, w, h, | 135 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, w, h, |
| 135 w * 3, false, &compressed)); | 136 w * 3, false, &compressed)); |
| 136 | 137 |
| 137 // Try decompressing a truncated version. | 138 // Try decompressing a truncated version. |
| 138 EXPECT_FALSE(PNGDecoder::Decode(&compressed[0], compressed.size() / 2, | 139 EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size() / 2, |
| 139 PNGDecoder::FORMAT_RGB, &output, | 140 PNGCodec::FORMAT_RGB, &output, |
| 140 &outw, &outh)); | 141 &outw, &outh)); |
| 141 | 142 |
| 142 // Corrupt it and try decompressing that. | 143 // Corrupt it and try decompressing that. |
| 143 for (int i = 10; i < 30; i++) | 144 for (int i = 10; i < 30; i++) |
| 144 compressed[i] = i; | 145 compressed[i] = i; |
| 145 EXPECT_FALSE(PNGDecoder::Decode(&compressed[0], compressed.size(), | 146 EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size(), |
| 146 PNGDecoder::FORMAT_RGB, &output, | 147 PNGCodec::FORMAT_RGB, &output, |
| 147 &outw, &outh)); | 148 &outw, &outh)); |
| 148 } | 149 } |
| 149 | 150 |
| 150 TEST(PNGCodec, EncodeDecodeBGRA) { | 151 TEST(PNGCodec, EncodeDecodeBGRA) { |
| 151 const int w = 20, h = 20; | 152 const int w = 20, h = 20; |
| 152 | 153 |
| 153 // Create an image with known values, alpha must be opaque because it will be | 154 // Create an image with known values, alpha must be opaque because it will be |
| 154 // lost during encoding. | 155 // lost during encoding. |
| 155 std::vector<unsigned char> original; | 156 std::vector<unsigned char> original; |
| 156 MakeRGBAImage(w, h, true, &original); | 157 MakeRGBAImage(w, h, true, &original); |
| 157 | 158 |
| 158 // Encode. | 159 // Encode. |
| 159 std::vector<unsigned char> encoded; | 160 std::vector<unsigned char> encoded; |
| 160 EXPECT_TRUE(PNGEncoder::Encode(&original[0], PNGEncoder::FORMAT_BGRA, w, h, | 161 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_BGRA, w, h, |
| 161 w * 4, false, &encoded)); | 162 w * 4, false, &encoded)); |
| 162 | 163 |
| 163 // Decode, it should have the same size as the original. | 164 // Decode, it should have the same size as the original. |
| 164 std::vector<unsigned char> decoded; | 165 std::vector<unsigned char> decoded; |
| 165 int outw, outh; | 166 int outw, outh; |
| 166 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(), | 167 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), |
| 167 PNGDecoder::FORMAT_BGRA, &decoded, | 168 PNGCodec::FORMAT_BGRA, &decoded, |
| 168 &outw, &outh)); | 169 &outw, &outh)); |
| 169 ASSERT_EQ(w, outw); | 170 ASSERT_EQ(w, outw); |
| 170 ASSERT_EQ(h, outh); | 171 ASSERT_EQ(h, outh); |
| 171 ASSERT_EQ(original.size(), decoded.size()); | 172 ASSERT_EQ(original.size(), decoded.size()); |
| 172 | 173 |
| 173 // Images must be exactly equal. | 174 // Images must be exactly equal. |
| 174 ASSERT_TRUE(original == decoded); | 175 ASSERT_TRUE(original == decoded); |
| 175 } | 176 } |
| 176 | 177 |
| 177 TEST(PNGCodec, StripAddAlpha) { | 178 TEST(PNGCodec, StripAddAlpha) { |
| 178 const int w = 20, h = 20; | 179 const int w = 20, h = 20; |
| 179 | 180 |
| 180 // These should be the same except one has a 0xff alpha channel. | 181 // These should be the same except one has a 0xff alpha channel. |
| 181 std::vector<unsigned char> original_rgb; | 182 std::vector<unsigned char> original_rgb; |
| 182 MakeRGBImage(w, h, &original_rgb); | 183 MakeRGBImage(w, h, &original_rgb); |
| 183 std::vector<unsigned char> original_rgba; | 184 std::vector<unsigned char> original_rgba; |
| 184 MakeRGBAImage(w, h, false, &original_rgba); | 185 MakeRGBAImage(w, h, false, &original_rgba); |
| 185 | 186 |
| 186 // Encode RGBA data as RGB. | 187 // Encode RGBA data as RGB. |
| 187 std::vector<unsigned char> encoded; | 188 std::vector<unsigned char> encoded; |
| 188 EXPECT_TRUE(PNGEncoder::Encode(&original_rgba[0], | 189 EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], |
| 189 PNGEncoder::FORMAT_RGBA, | 190 PNGCodec::FORMAT_RGBA, |
| 190 w, h, | 191 w, h, |
| 191 w * 4, true, &encoded)); | 192 w * 4, true, &encoded)); |
| 192 | 193 |
| 193 // Decode the RGB to RGBA. | 194 // Decode the RGB to RGBA. |
| 194 std::vector<unsigned char> decoded; | 195 std::vector<unsigned char> decoded; |
| 195 int outw, outh; | 196 int outw, outh; |
| 196 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(), | 197 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), |
| 197 PNGDecoder::FORMAT_RGBA, &decoded, | 198 PNGCodec::FORMAT_RGBA, &decoded, |
| 198 &outw, &outh)); | 199 &outw, &outh)); |
| 199 | 200 |
| 200 // Decoded and reference should be the same (opaque alpha). | 201 // Decoded and reference should be the same (opaque alpha). |
| 201 ASSERT_EQ(w, outw); | 202 ASSERT_EQ(w, outw); |
| 202 ASSERT_EQ(h, outh); | 203 ASSERT_EQ(h, outh); |
| 203 ASSERT_EQ(original_rgba.size(), decoded.size()); | 204 ASSERT_EQ(original_rgba.size(), decoded.size()); |
| 204 ASSERT_TRUE(original_rgba == decoded); | 205 ASSERT_TRUE(original_rgba == decoded); |
| 205 | 206 |
| 206 // Encode RGBA to RGBA. | 207 // Encode RGBA to RGBA. |
| 207 EXPECT_TRUE(PNGEncoder::Encode(&original_rgba[0], | 208 EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], |
| 208 PNGEncoder::FORMAT_RGBA, | 209 PNGCodec::FORMAT_RGBA, |
| 209 w, h, | 210 w, h, |
| 210 w * 4, false, &encoded)); | 211 w * 4, false, &encoded)); |
| 211 | 212 |
| 212 // Decode the RGBA to RGB. | 213 // Decode the RGBA to RGB. |
| 213 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(), | 214 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), |
| 214 PNGDecoder::FORMAT_RGB, &decoded, | 215 PNGCodec::FORMAT_RGB, &decoded, |
| 215 &outw, &outh)); | 216 &outw, &outh)); |
| 216 | 217 |
| 217 // It should be the same as our non-alpha-channel reference. | 218 // It should be the same as our non-alpha-channel reference. |
| 218 ASSERT_EQ(w, outw); | 219 ASSERT_EQ(w, outw); |
| 219 ASSERT_EQ(h, outh); | 220 ASSERT_EQ(h, outh); |
| 220 ASSERT_EQ(original_rgb.size(), decoded.size()); | 221 ASSERT_EQ(original_rgb.size(), decoded.size()); |
| 221 ASSERT_TRUE(original_rgb == decoded); | 222 ASSERT_TRUE(original_rgb == decoded); |
| 222 } | 223 } |
| 223 | 224 |
| 224 TEST(PNGCodec, EncodeBGRASkBitmap) { | 225 TEST(PNGCodec, EncodeBGRASkBitmap) { |
| 225 const int w = 20, h = 20; | 226 const int w = 20, h = 20; |
| 226 | 227 |
| 227 SkBitmap original_bitmap; | 228 SkBitmap original_bitmap; |
| 228 MakeTestSkBitmap(w, h, &original_bitmap); | 229 MakeTestSkBitmap(w, h, &original_bitmap); |
| 229 | 230 |
| 230 // Encode the bitmap. | 231 // Encode the bitmap. |
| 231 std::vector<unsigned char> encoded; | 232 std::vector<unsigned char> encoded; |
| 232 PNGEncoder::EncodeBGRASkBitmap(original_bitmap, false, &encoded); | 233 PNGCodec::EncodeBGRASkBitmap(original_bitmap, false, &encoded); |
| 233 | 234 |
| 234 // Decode the encoded string. | 235 // Decode the encoded string. |
| 235 SkBitmap decoded_bitmap; | 236 SkBitmap decoded_bitmap; |
| 236 EXPECT_TRUE(PNGDecoder::Decode(&encoded, &decoded_bitmap)); | 237 EXPECT_TRUE(PNGCodec::Decode(&encoded, &decoded_bitmap)); |
| 237 | 238 |
| 238 // Compare the original bitmap and the output bitmap. We use ColorsClose | 239 // Compare the original bitmap and the output bitmap. We use ColorsClose |
| 239 // as SkBitmaps are considered to be pre-multiplied, the unpremultiplication | 240 // as SkBitmaps are considered to be pre-multiplied, the unpremultiplication |
| 240 // (in Encode) and repremultiplication (in Decode) can be lossy. | 241 // (in Encode) and repremultiplication (in Decode) can be lossy. |
| 241 for (int x = 0; x < w; x++) { | 242 for (int x = 0; x < w; x++) { |
| 242 for (int y = 0; y < h; y++) { | 243 for (int y = 0; y < h; y++) { |
| 243 uint32_t original_pixel = original_bitmap.getAddr32(0, y)[x]; | 244 uint32_t original_pixel = original_bitmap.getAddr32(0, y)[x]; |
| 244 uint32_t decoded_pixel = decoded_bitmap.getAddr32(0, y)[x]; | 245 uint32_t decoded_pixel = decoded_bitmap.getAddr32(0, y)[x]; |
| 245 EXPECT_TRUE(ColorsClose(original_pixel, decoded_pixel)); | 246 EXPECT_TRUE(ColorsClose(original_pixel, decoded_pixel)); |
| 246 } | 247 } |
| 247 } | 248 } |
| 248 } | 249 } |
| 249 | 250 |
| 251 } // namespace gfx |
| OLD | NEW |