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 "config.h" | 5 #include "config.h" |
6 | 6 |
7 #include "webkit/tools/test_shell/image_decoder_unittest.h" | 7 #include "webkit/tools/test_shell/image_decoder_unittest.h" |
8 | 8 |
9 #include "base/file_path.h" | |
10 #include "base/file_util.h" | 9 #include "base/file_util.h" |
11 #include "base/md5.h" | 10 #include "base/md5.h" |
12 #include "base/path_service.h" | 11 #include "base/path_service.h" |
13 #include "base/scoped_ptr.h" | 12 #include "base/scoped_ptr.h" |
14 #include "base/string_util.h" | 13 #include "base/string_util.h" |
15 #include "base/time.h" | 14 #include "base/time.h" |
16 | 15 |
17 using base::Time; | 16 using base::Time; |
18 | 17 |
19 namespace { | 18 namespace { |
20 | 19 |
21 // Determine if we should test with file specified by |path| based | 20 // Determine if we should test with file specified by |path| based |
22 // on |file_selection| and the |threshold| for the file size. | 21 // on |file_selection| and the |threshold| for the file size. |
23 bool ShouldSkipFile(const FilePath& path, | 22 bool ShouldSkipFile(const std::wstring& path, |
24 ImageDecoderTestFileSelection file_selection, | 23 ImageDecoderTestFileSelection file_selection, |
25 const int64 threshold) { | 24 const int64 threshold) { |
26 if (file_selection == TEST_ALL) | 25 if (file_selection == TEST_ALL) |
27 return false; | 26 return false; |
28 | 27 |
29 int64 image_size = 0; | 28 int64 image_size = 0; |
30 file_util::GetFileSize(path, &image_size); | 29 file_util::GetFileSize(path, &image_size); |
31 return (file_selection == TEST_SMALLER) == (image_size > threshold); | 30 return (file_selection == TEST_SMALLER) == (image_size > threshold); |
32 } | 31 } |
33 | 32 |
34 } // anonymous namespace | 33 } // anonymous namespace |
35 | 34 |
36 void ReadFileToVector(const FilePath& path, Vector<char>* contents) { | 35 void ReadFileToVector(const std::wstring& path, Vector<char>* contents) { |
37 std::string contents_str; | 36 std::string contents_str; |
38 file_util::ReadFileToString(path, &contents_str); | 37 file_util::ReadFileToString(path, &contents_str); |
39 contents->resize(contents_str.size()); | 38 contents->resize(contents_str.size()); |
40 memcpy(&contents->first(), contents_str.data(), contents_str.size()); | 39 memcpy(&contents->first(), contents_str.data(), contents_str.size()); |
41 } | 40 } |
42 | 41 |
43 FilePath GetMD5SumPath(const FilePath& path) { | 42 std::wstring GetMD5SumPath(const std::wstring& path) { |
44 static const FilePath::StringType kDecodedDataExtension( | 43 static const std::wstring kDecodedDataExtension(L".md5sum"); |
45 FILE_PATH_LITERAL(".md5sum")); | 44 return path + kDecodedDataExtension; |
46 return FilePath(path.value() + kDecodedDataExtension); | |
47 } | 45 } |
48 | 46 |
49 #ifdef CALCULATE_MD5_SUMS | 47 #ifdef CALCULATE_MD5_SUMS |
50 void SaveMD5Sum(const std::wstring& path, WebCore::RGBA32Buffer* buffer) { | 48 void SaveMD5Sum(const std::wstring& path, WebCore::RGBA32Buffer* buffer) { |
51 // Calculate MD5 sum. | 49 // Calculate MD5 sum. |
52 MD5Digest digest; | 50 MD5Digest digest; |
53 scoped_ptr<NativeImageSkia> image_data(buffer->asNewNativeImage()); | 51 scoped_ptr<NativeImageSkia> image_data(buffer->asNewNativeImage()); |
54 { | 52 { |
55 SkAutoLockPixels bmp_lock(*image_data); | 53 SkAutoLockPixels bmp_lock(*image_data); |
56 MD5Sum(image_data->getPixels(), | 54 MD5Sum(image_data->getPixels(), |
57 image_data->width() * image_data->height() * sizeof(uint32_t), | 55 image_data->width() * image_data->height() * sizeof(uint32_t), |
58 &digest); | 56 &digest); |
59 } | 57 } |
60 | 58 |
61 // Write sum to disk. | 59 // Write sum to disk. |
62 int bytes_written = file_util::WriteFile(path, | 60 int bytes_written = file_util::WriteFile(path, |
63 reinterpret_cast<const char*>(&digest), sizeof digest); | 61 reinterpret_cast<const char*>(&digest), sizeof digest); |
64 ASSERT_EQ(sizeof digest, bytes_written); | 62 ASSERT_EQ(sizeof digest, bytes_written); |
65 } | 63 } |
66 #else | 64 #else |
67 void VerifyImage(WebCore::ImageDecoder* decoder, | 65 void VerifyImage(WebCore::ImageDecoder* decoder, |
68 const FilePath& path, | 66 const std::wstring& path, |
69 const FilePath& md5_sum_path, | 67 const std::wstring& md5_sum_path, |
70 size_t frame_index) { | 68 size_t frame_index) { |
71 // Make sure decoding can complete successfully. | 69 // Make sure decoding can complete successfully. |
72 EXPECT_TRUE(decoder->isSizeAvailable()) << path.value(); | 70 EXPECT_TRUE(decoder->isSizeAvailable()) << path; |
73 EXPECT_GE(decoder->frameCount(), frame_index) << path.value(); | 71 EXPECT_GE(decoder->frameCount(), frame_index) << path; |
74 WebCore::RGBA32Buffer* image_buffer = | 72 WebCore::RGBA32Buffer* image_buffer = |
75 decoder->frameBufferAtIndex(frame_index); | 73 decoder->frameBufferAtIndex(frame_index); |
76 ASSERT_NE(static_cast<WebCore::RGBA32Buffer*>(NULL), image_buffer) << | 74 ASSERT_NE(static_cast<WebCore::RGBA32Buffer*>(NULL), image_buffer) << path; |
77 path.value(); | |
78 EXPECT_EQ(WebCore::RGBA32Buffer::FrameComplete, image_buffer->status()) << | 75 EXPECT_EQ(WebCore::RGBA32Buffer::FrameComplete, image_buffer->status()) << |
79 path.value(); | 76 path; |
80 EXPECT_FALSE(decoder->failed()) << path.value(); | 77 EXPECT_FALSE(decoder->failed()) << path; |
81 | 78 |
82 // Calculate MD5 sum. | 79 // Calculate MD5 sum. |
83 MD5Digest actual_digest; | 80 MD5Digest actual_digest; |
84 scoped_ptr<NativeImageSkia> image_data(image_buffer->asNewNativeImage()); | 81 scoped_ptr<NativeImageSkia> image_data(image_buffer->asNewNativeImage()); |
85 { | 82 { |
86 SkAutoLockPixels bmp_lock(*image_data); | 83 SkAutoLockPixels bmp_lock(*image_data); |
87 MD5Sum(image_data->getPixels(), | 84 MD5Sum(image_data->getPixels(), |
88 image_data->width() * image_data->height() * sizeof(uint32_t), | 85 image_data->width() * image_data->height() * sizeof(uint32_t), |
89 &actual_digest); | 86 &actual_digest); |
90 } | 87 } |
91 | 88 |
92 // Read the MD5 sum off disk. | 89 // Read the MD5 sum off disk. |
93 std::string file_bytes; | 90 std::string file_bytes; |
94 file_util::ReadFileToString(md5_sum_path, &file_bytes); | 91 file_util::ReadFileToString(md5_sum_path, &file_bytes); |
95 MD5Digest expected_digest; | 92 MD5Digest expected_digest; |
96 ASSERT_EQ(sizeof expected_digest, file_bytes.size()) << path.value(); | 93 ASSERT_EQ(sizeof expected_digest, file_bytes.size()) << path; |
97 memcpy(&expected_digest, file_bytes.data(), sizeof expected_digest); | 94 memcpy(&expected_digest, file_bytes.data(), sizeof expected_digest); |
98 | 95 |
99 // Verify that the sums are the same. | 96 // Verify that the sums are the same. |
100 EXPECT_EQ(0, memcmp(&expected_digest, &actual_digest, sizeof(MD5Digest))) << | 97 EXPECT_EQ(0, memcmp(&expected_digest, &actual_digest, sizeof(MD5Digest))) << |
101 path.value(); | 98 path; |
102 } | 99 } |
103 #endif | 100 #endif |
104 | 101 |
105 void ImageDecoderTest::SetUp() { | 102 void ImageDecoderTest::SetUp() { |
106 FilePath data_dir; | 103 FilePath data_dir; |
107 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir)); | 104 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir)); |
108 data_dir_ = data_dir.AppendASCII("webkit"). | 105 data_dir_ = data_dir.ToWStringHack(); |
109 AppendASCII("data"). | 106 file_util::AppendToPath(&data_dir_, L"webkit"); |
110 AppendASCII(format_ + "_decoder"); | 107 file_util::AppendToPath(&data_dir_, L"data"); |
111 ASSERT_TRUE(file_util::PathExists(data_dir_)) << data_dir_.value(); | 108 file_util::AppendToPath(&data_dir_, format_ + L"_decoder"); |
| 109 ASSERT_TRUE(file_util::PathExists(data_dir_)) << data_dir_; |
112 } | 110 } |
113 | 111 |
114 std::vector<FilePath> ImageDecoderTest::GetImageFiles() const { | 112 std::vector<std::wstring> ImageDecoderTest::GetImageFiles() const { |
115 #if defined(OS_WIN) | 113 std::wstring pattern = L"*." + format_; |
116 std::wstring pattern = ASCIIToWide("*." + format_); | |
117 #else | |
118 std::string pattern = "*." + format_; | |
119 #endif | |
120 | 114 |
121 file_util::FileEnumerator enumerator(data_dir_, | 115 file_util::FileEnumerator enumerator(FilePath::FromWStringHack(data_dir_), |
122 false, | 116 false, |
123 file_util::FileEnumerator::FILES); | 117 file_util::FileEnumerator::FILES); |
124 | 118 |
125 std::vector<FilePath> image_files; | 119 std::vector<std::wstring> image_files; |
126 FilePath next_file_name; | 120 std::wstring next_file_name; |
127 while (!(next_file_name = enumerator.Next()).empty()) { | 121 while ((next_file_name = enumerator.Next().ToWStringHack()) != L"") { |
128 if (!MatchPattern(next_file_name.value(), pattern)) { | 122 if (!MatchPattern(next_file_name, pattern)) { |
129 continue; | 123 continue; |
130 } | 124 } |
131 image_files.push_back(next_file_name); | 125 image_files.push_back(next_file_name); |
132 } | 126 } |
133 | 127 |
134 return image_files; | 128 return image_files; |
135 } | 129 } |
136 | 130 |
137 bool ImageDecoderTest::ShouldImageFail(const FilePath& path) const { | 131 bool ImageDecoderTest::ShouldImageFail(const std::wstring& path) const { |
138 static const FilePath::StringType kBadSuffix(FILE_PATH_LITERAL(".bad.")); | 132 static const std::wstring kBadSuffix(L".bad."); |
139 return (path.value().length() > (kBadSuffix.length() + format_.length()) && | 133 return (path.length() > (kBadSuffix.length() + format_.length()) && |
140 !path.value().compare(path.value().length() - format_.length() - | 134 !path.compare(path.length() - format_.length() - kBadSuffix.length(), |
141 kBadSuffix.length(), | 135 kBadSuffix.length(), kBadSuffix)); |
142 kBadSuffix.length(), kBadSuffix)); | |
143 } | 136 } |
144 | 137 |
145 WebCore::ImageDecoder* ImageDecoderTest::SetupDecoder( | 138 WebCore::ImageDecoder* ImageDecoderTest::SetupDecoder( |
146 const FilePath& path, | 139 const std::wstring& path, |
147 bool split_at_random) const { | 140 bool split_at_random) const { |
148 Vector<char> image_contents; | 141 Vector<char> image_contents; |
149 ReadFileToVector(path, &image_contents); | 142 ReadFileToVector(path, &image_contents); |
150 | 143 |
151 WebCore::ImageDecoder* decoder = CreateDecoder(); | 144 WebCore::ImageDecoder* decoder = CreateDecoder(); |
152 RefPtr<WebCore::SharedBuffer> shared_contents( | 145 RefPtr<WebCore::SharedBuffer> shared_contents( |
153 WebCore::SharedBuffer::create()); | 146 WebCore::SharedBuffer::create()); |
154 | 147 |
155 if (split_at_random) { | 148 if (split_at_random) { |
156 // Split the file at an arbitrary point. | 149 // Split the file at an arbitrary point. |
157 const int partial_size = static_cast<int>( | 150 const int partial_size = static_cast<int>( |
158 (static_cast<double>(rand()) / RAND_MAX) * image_contents.size()); | 151 (static_cast<double>(rand()) / RAND_MAX) * image_contents.size()); |
159 shared_contents->append(image_contents.data(), partial_size); | 152 shared_contents->append(image_contents.data(), partial_size); |
160 | 153 |
161 // Make sure the image decoder doesn't fail when we ask for the frame buffer | 154 // Make sure the image decoder doesn't fail when we ask for the frame buffer |
162 // for this partial image. | 155 // for this partial image. |
163 decoder->setData(shared_contents.get(), false); | 156 decoder->setData(shared_contents.get(), false); |
164 EXPECT_FALSE(decoder->failed()) << path.value(); | 157 EXPECT_FALSE(decoder->failed()) << path; |
165 // NOTE: We can't check that frame 0 is non-NULL, because if this is an ICO | 158 // NOTE: We can't check that frame 0 is non-NULL, because if this is an ICO |
166 // and we haven't yet supplied enough data to read the directory, there is | 159 // and we haven't yet supplied enough data to read the directory, there is |
167 // no framecount and thus no first frame. | 160 // no framecount and thus no first frame. |
168 | 161 |
169 // Make sure passing the complete image results in successful decoding. | 162 // Make sure passing the complete image results in successful decoding. |
170 shared_contents->append( | 163 shared_contents->append( |
171 &image_contents.data()[partial_size], | 164 &image_contents.data()[partial_size], |
172 static_cast<int>(image_contents.size() - partial_size)); | 165 static_cast<int>(image_contents.size() - partial_size)); |
173 } else { | 166 } else { |
174 shared_contents->append(image_contents.data(), | 167 shared_contents->append(image_contents.data(), |
175 static_cast<int>(image_contents.size())); | 168 static_cast<int>(image_contents.size())); |
176 } | 169 } |
177 | 170 |
178 decoder->setData(shared_contents.get(), true); | 171 decoder->setData(shared_contents.get(), true); |
179 return decoder; | 172 return decoder; |
180 } | 173 } |
181 | 174 |
182 void ImageDecoderTest::TestDecoding( | 175 void ImageDecoderTest::TestDecoding( |
183 ImageDecoderTestFileSelection file_selection, | 176 ImageDecoderTestFileSelection file_selection, |
184 const int64 threshold) const { | 177 const int64 threshold) const { |
185 const std::vector<FilePath> image_files(GetImageFiles()); | 178 const std::vector<std::wstring> image_files(GetImageFiles()); |
186 for (std::vector<FilePath>::const_iterator i = image_files.begin(); | 179 for (std::vector<std::wstring>::const_iterator i(image_files.begin()); |
187 i != image_files.end(); ++i) { | 180 i != image_files.end(); ++i) { |
188 if (ShouldSkipFile(*i, file_selection, threshold)) | 181 if (ShouldSkipFile(*i, file_selection, threshold)) |
189 continue; | 182 continue; |
190 | 183 |
191 scoped_ptr<WebCore::ImageDecoder> decoder(SetupDecoder(*i, false)); | 184 scoped_ptr<WebCore::ImageDecoder> decoder(SetupDecoder(*i, false)); |
192 if (ShouldImageFail(*i)) { | 185 if (ShouldImageFail(*i)) { |
193 // We may get a non-NULL frame buffer, but it should be incomplete, and | 186 // We may get a non-NULL frame buffer, but it should be incomplete, and |
194 // the decoder should have failed. | 187 // the decoder should have failed. |
195 WebCore::RGBA32Buffer* const image_buffer = | 188 WebCore::RGBA32Buffer* const image_buffer = |
196 decoder->frameBufferAtIndex(0); | 189 decoder->frameBufferAtIndex(0); |
197 if (image_buffer) { | 190 if (image_buffer) { |
198 EXPECT_NE(image_buffer->status(), | 191 EXPECT_NE(image_buffer->status(), |
199 WebCore::RGBA32Buffer::FrameComplete) << i->value(); | 192 WebCore::RGBA32Buffer::FrameComplete) << (*i); |
200 } | 193 } |
201 EXPECT_TRUE(decoder->failed()) << i->value(); | 194 EXPECT_TRUE(decoder->failed()) << (*i); |
202 continue; | 195 continue; |
203 } | 196 } |
204 | 197 |
205 #ifdef CALCULATE_MD5_SUMS | 198 #ifdef CALCULATE_MD5_SUMS |
206 SaveMD5Sum(GetMD5SumPath(*i), decoder->frameBufferAtIndex(0)); | 199 SaveMD5Sum(GetMD5SumPath(*i), decoder->frameBufferAtIndex(0)); |
207 #else | 200 #else |
208 VerifyImage(decoder.get(), *i, GetMD5SumPath(*i), 0); | 201 VerifyImage(decoder.get(), *i, GetMD5SumPath(*i), 0); |
209 #endif | 202 #endif |
210 } | 203 } |
211 } | 204 } |
212 | 205 |
213 #ifndef CALCULATE_MD5_SUMS | 206 #ifndef CALCULATE_MD5_SUMS |
214 void ImageDecoderTest::TestChunkedDecoding( | 207 void ImageDecoderTest::TestChunkedDecoding( |
215 ImageDecoderTestFileSelection file_selection, | 208 ImageDecoderTestFileSelection file_selection, |
216 const int64 threshold) const { | 209 const int64 threshold) const { |
217 // Init random number generator with current day, so a failing case will fail | 210 // Init random number generator with current day, so a failing case will fail |
218 // consistently over the course of a whole day. | 211 // consistently over the course of a whole day. |
219 const Time today = Time::Now().LocalMidnight(); | 212 const Time today = Time::Now().LocalMidnight(); |
220 srand(static_cast<unsigned int>(today.ToInternalValue())); | 213 srand(static_cast<unsigned int>(today.ToInternalValue())); |
221 | 214 |
222 const std::vector<FilePath> image_files(GetImageFiles()); | 215 const std::vector<std::wstring> image_files(GetImageFiles()); |
223 for (std::vector<FilePath>::const_iterator i = image_files.begin(); | 216 for (std::vector<std::wstring>::const_iterator i(image_files.begin()); |
224 i != image_files.end(); ++i) { | 217 i != image_files.end(); ++i) { |
225 if (ShouldSkipFile(*i, file_selection, threshold)) | 218 if (ShouldSkipFile(*i, file_selection, threshold)) |
226 continue; | 219 continue; |
227 | 220 |
228 if (ShouldImageFail(*i)) | 221 if (ShouldImageFail(*i)) |
229 continue; | 222 continue; |
230 | 223 |
231 scoped_ptr<WebCore::ImageDecoder> decoder(SetupDecoder(*i, true)); | 224 scoped_ptr<WebCore::ImageDecoder> decoder(SetupDecoder(*i, true)); |
232 VerifyImage(decoder.get(), *i, GetMD5SumPath(*i), 0); | 225 VerifyImage(decoder.get(), *i, GetMD5SumPath(*i), 0); |
233 } | 226 } |
234 } | 227 } |
235 #endif | 228 #endif |
OLD | NEW |