| OLD | NEW |
| 1 // Copyright (c) 2011 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 <math.h> |
| 6 #include <stddef.h> | 6 #include <stddef.h> |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 if (a.empty()) | 81 if (a.empty()) |
| 82 return 0; // prevent divide by 0 below | 82 return 0; // prevent divide by 0 below |
| 83 | 83 |
| 84 double acc = 0.0; | 84 double acc = 0.0; |
| 85 for (size_t i = 0; i < a.size(); i++) | 85 for (size_t i = 0; i < a.size(); i++) |
| 86 acc += fabs(static_cast<double>(a[i]) - static_cast<double>(b[i])); | 86 acc += fabs(static_cast<double>(a[i]) - static_cast<double>(b[i])); |
| 87 | 87 |
| 88 return acc / static_cast<double>(a.size()); | 88 return acc / static_cast<double>(a.size()); |
| 89 } | 89 } |
| 90 | 90 |
| 91 static void MakeRGBAImage(int w, int h, std::vector<unsigned char>* dat) { | 91 static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) { |
| 92 dat->resize(w * h * 4); | 92 dat->resize(w * h * 3); |
| 93 for (int y = 0; y < h; y++) { | 93 for (int y = 0; y < h; y++) { |
| 94 for (int x = 0; x < w; x++) { | 94 for (int x = 0; x < w; x++) { |
| 95 unsigned char* org_px = &(*dat)[(y * w + x) * 4]; | 95 unsigned char* org_px = &(*dat)[(y * w + x) * 3]; |
| 96 org_px[0] = x * 3; // r | 96 org_px[0] = x * 3; // r |
| 97 org_px[1] = x * 3 + 1; // g | 97 org_px[1] = x * 3 + 1; // g |
| 98 org_px[2] = x * 3 + 2; // b | 98 org_px[2] = x * 3 + 2; // b |
| 99 org_px[3] = 0xFF; // a | |
| 100 } | 99 } |
| 101 } | 100 } |
| 102 } | 101 } |
| 103 | 102 |
| 103 TEST(JPEGCodec, EncodeDecodeRGB) { |
| 104 int w = 20, h = 20; |
| 105 |
| 106 // create an image with known values |
| 107 std::vector<unsigned char> original; |
| 108 MakeRGBImage(w, h, &original); |
| 109 |
| 110 // encode, making sure it was compressed some |
| 111 std::vector<unsigned char> encoded; |
| 112 EXPECT_TRUE(JPEGCodec::Encode(&original[0], JPEGCodec::FORMAT_RGB, w, h, |
| 113 w * 3, jpeg_quality, &encoded)); |
| 114 EXPECT_GT(original.size(), encoded.size()); |
| 115 |
| 116 // decode, it should have the same size as the original |
| 117 std::vector<unsigned char> decoded; |
| 118 int outw, outh; |
| 119 EXPECT_TRUE(JPEGCodec::Decode(&encoded[0], encoded.size(), |
| 120 JPEGCodec::FORMAT_RGB, &decoded, |
| 121 &outw, &outh)); |
| 122 ASSERT_EQ(w, outw); |
| 123 ASSERT_EQ(h, outh); |
| 124 ASSERT_EQ(original.size(), decoded.size()); |
| 125 |
| 126 // Images must be approximately equal (compression will have introduced some |
| 127 // minor artifacts). |
| 128 ASSERT_GE(jpeg_equality_threshold, AveragePixelDelta(original, decoded)); |
| 129 } |
| 130 |
| 104 TEST(JPEGCodec, EncodeDecodeRGBA) { | 131 TEST(JPEGCodec, EncodeDecodeRGBA) { |
| 105 int w = 20, h = 20; | 132 int w = 20, h = 20; |
| 106 | 133 |
| 107 // create an image with known values, a must be opaque because it will be | 134 // create an image with known values, a must be opaque because it will be |
| 108 // lost during compression | 135 // lost during compression |
| 109 std::vector<unsigned char> original; | 136 std::vector<unsigned char> original; |
| 110 MakeRGBAImage(w, h, &original); | 137 original.resize(w * h * 4); |
| 138 for (int y = 0; y < h; y++) { |
| 139 for (int x = 0; x < w; x++) { |
| 140 unsigned char* org_px = &original[(y * w + x) * 4]; |
| 141 org_px[0] = x * 3; // r |
| 142 org_px[1] = x * 3 + 1; // g |
| 143 org_px[2] = x * 3 + 2; // b |
| 144 org_px[3] = 0xFF; // a (opaque) |
| 145 } |
| 146 } |
| 111 | 147 |
| 112 // encode, making sure it was compressed some | 148 // encode, making sure it was compressed some |
| 113 std::vector<unsigned char> encoded; | 149 std::vector<unsigned char> encoded; |
| 114 EXPECT_TRUE(JPEGCodec::Encode(&original[0], JPEGCodec::FORMAT_RGBA, w, h, | 150 EXPECT_TRUE(JPEGCodec::Encode(&original[0], JPEGCodec::FORMAT_RGBA, w, h, |
| 115 w * 4, jpeg_quality, &encoded)); | 151 w * 4, jpeg_quality, &encoded)); |
| 116 EXPECT_GT(original.size(), encoded.size()); | 152 EXPECT_GT(original.size(), encoded.size()); |
| 117 | 153 |
| 118 // decode, it should have the same size as the original | 154 // decode, it should have the same size as the original |
| 119 std::vector<unsigned char> decoded; | 155 std::vector<unsigned char> decoded; |
| 120 int outw, outh; | 156 int outw, outh; |
| 121 EXPECT_TRUE(JPEGCodec::Decode(&encoded[0], encoded.size(), | 157 EXPECT_TRUE(JPEGCodec::Decode(&encoded[0], encoded.size(), |
| 122 JPEGCodec::FORMAT_RGBA, &decoded, | 158 JPEGCodec::FORMAT_RGBA, &decoded, |
| 123 &outw, &outh)); | 159 &outw, &outh)); |
| 124 ASSERT_EQ(w, outw); | 160 ASSERT_EQ(w, outw); |
| 125 ASSERT_EQ(h, outh); | 161 ASSERT_EQ(h, outh); |
| 126 ASSERT_EQ(original.size(), decoded.size()); | 162 ASSERT_EQ(original.size(), decoded.size()); |
| 127 | 163 |
| 128 // Images must be approximately equal (compression will have introduced some | 164 // Images must be approximately equal (compression will have introduced some |
| 129 // minor artifacts). | 165 // minor artifacts). |
| 130 ASSERT_GE(jpeg_equality_threshold, AveragePixelDelta(original, decoded)); | 166 ASSERT_GE(jpeg_equality_threshold, AveragePixelDelta(original, decoded)); |
| 131 } | 167 } |
| 132 | 168 |
| 133 // Test that corrupted data decompression causes failures. | 169 // Test that corrupted data decompression causes failures. |
| 134 TEST(JPEGCodec, DecodeCorrupted) { | 170 TEST(JPEGCodec, DecodeCorrupted) { |
| 135 int w = 20, h = 20; | 171 int w = 20, h = 20; |
| 136 | 172 |
| 137 // some random data (an uncompressed image) | 173 // some random data (an uncompressed image) |
| 138 std::vector<unsigned char> original; | 174 std::vector<unsigned char> original; |
| 139 MakeRGBAImage(w, h, &original); | 175 MakeRGBImage(w, h, &original); |
| 140 | 176 |
| 141 // it should fail when given non-JPEG compressed data | 177 // it should fail when given non-JPEG compressed data |
| 142 std::vector<unsigned char> output; | 178 std::vector<unsigned char> output; |
| 143 int outw, outh; | 179 int outw, outh; |
| 144 ASSERT_FALSE(JPEGCodec::Decode(&original[0], original.size(), | 180 ASSERT_FALSE(JPEGCodec::Decode(&original[0], original.size(), |
| 145 JPEGCodec::FORMAT_RGBA, &output, &outw, | 181 JPEGCodec::FORMAT_RGB, &output, |
| 146 &outh)); | 182 &outw, &outh)); |
| 147 | 183 |
| 148 // make some compressed data | 184 // make some compressed data |
| 149 std::vector<unsigned char> compressed; | 185 std::vector<unsigned char> compressed; |
| 150 ASSERT_TRUE(JPEGCodec::Encode(&original[0], JPEGCodec::FORMAT_RGBA, w, h, | 186 ASSERT_TRUE(JPEGCodec::Encode(&original[0], JPEGCodec::FORMAT_RGB, w, h, |
| 151 w * 3, jpeg_quality, &compressed)); | 187 w * 3, jpeg_quality, &compressed)); |
| 152 | 188 |
| 153 // try decompressing a truncated version | 189 // try decompressing a truncated version |
| 154 ASSERT_FALSE(JPEGCodec::Decode(&compressed[0], compressed.size() / 2, | 190 ASSERT_FALSE(JPEGCodec::Decode(&compressed[0], compressed.size() / 2, |
| 155 JPEGCodec::FORMAT_RGBA, &output, &outw, | 191 JPEGCodec::FORMAT_RGB, &output, |
| 156 &outh)); | 192 &outw, &outh)); |
| 157 | 193 |
| 158 // corrupt it and try decompressing that | 194 // corrupt it and try decompressing that |
| 159 for (int i = 10; i < 30; i++) | 195 for (int i = 10; i < 30; i++) |
| 160 compressed[i] = i; | 196 compressed[i] = i; |
| 161 ASSERT_FALSE(JPEGCodec::Decode(&compressed[0], compressed.size(), | 197 ASSERT_FALSE(JPEGCodec::Decode(&compressed[0], compressed.size(), |
| 162 JPEGCodec::FORMAT_RGBA, &output, &outw, | 198 JPEGCodec::FORMAT_RGB, &output, |
| 163 &outh)); | 199 &outw, &outh)); |
| 164 } | 200 } |
| 165 | 201 |
| 166 // Test that we can decode JPEG images without invalid-read errors on valgrind. | 202 // Test that we can decode JPEG images without invalid-read errors on valgrind. |
| 167 // This test decodes a 1x1 JPEG image and writes the decoded RGB (or RGBA) pixel | 203 // This test decodes a 1x1 JPEG image and writes the decoded RGB (or RGBA) pixel |
| 168 // to the output buffer without OOB reads. | 204 // to the output buffer without OOB reads. |
| 169 TEST(JPEGCodec, InvalidRead) { | 205 TEST(JPEGCodec, InvalidRead) { |
| 170 std::vector<unsigned char> output; | 206 std::vector<unsigned char> output; |
| 171 int outw, outh; | 207 int outw, outh; |
| 172 JPEGCodec::Decode(kTopSitesMigrationTestImage, | 208 JPEGCodec::Decode(kTopSitesMigrationTestImage, |
| 173 arraysize(kTopSitesMigrationTestImage), | 209 arraysize(kTopSitesMigrationTestImage), |
| 210 JPEGCodec::FORMAT_RGB, &output, |
| 211 &outw, &outh); |
| 212 |
| 213 JPEGCodec::Decode(kTopSitesMigrationTestImage, |
| 214 arraysize(kTopSitesMigrationTestImage), |
| 174 JPEGCodec::FORMAT_RGBA, &output, | 215 JPEGCodec::FORMAT_RGBA, &output, |
| 175 &outw, &outh); | 216 &outw, &outh); |
| 176 } | 217 } |
| 177 | 218 |
| 178 } // namespace gfx | 219 } // namespace gfx |
| OLD | NEW |