OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "platform/image-decoders/ImageDecoderTestHelpers.h" | 5 #include "platform/image-decoders/ImageDecoderTestHelpers.h" |
6 | 6 |
7 #include "platform/SharedBuffer.h" | 7 #include "platform/SharedBuffer.h" |
8 #include "platform/image-decoders/ImageDecoder.h" | 8 #include "platform/image-decoders/ImageDecoder.h" |
9 #include "platform/image-decoders/ImageFrame.h" | 9 #include "platform/image-decoders/ImageFrame.h" |
10 #include "platform/testing/UnitTestHelpers.h" | 10 #include "platform/testing/UnitTestHelpers.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
12 #include "wtf/StringHasher.h" | 12 #include "wtf/StringHasher.h" |
13 #include "wtf/text/StringBuilder.h" | 13 #include "wtf/text/StringBuilder.h" |
14 #include <memory> | 14 #include <memory> |
15 #include <string> | |
15 | 16 |
16 namespace blink { | 17 namespace blink { |
17 | 18 |
19 const char* concatDirAndFile(const char* dir, const char* file) { | |
20 std::string dirStr(dir); | |
scroggo_chromium
2016/11/09 14:38:37
Elsewhere in the file, we use String. For consiste
joostouwerling
2016/11/10 17:15:13
Done.
| |
21 std::string fileStr(file); | |
22 return (dirStr + "/" + fileStr).c_str(); | |
23 } | |
24 | |
18 PassRefPtr<SharedBuffer> readFile(const char* fileName) { | 25 PassRefPtr<SharedBuffer> readFile(const char* fileName) { |
19 String filePath = testing::blinkRootDir(); | 26 String filePath = testing::blinkRootDir(); |
20 filePath.append(fileName); | 27 filePath.append(fileName); |
21 return testing::readFromFile(filePath); | 28 return testing::readFromFile(filePath); |
22 } | 29 } |
23 | 30 |
24 PassRefPtr<SharedBuffer> readFile(const char* dir, const char* fileName) { | 31 PassRefPtr<SharedBuffer> readFile(const char* dir, const char* fileName) { |
25 StringBuilder filePath; | 32 StringBuilder filePath; |
26 filePath.append(testing::blinkRootDir()); | 33 filePath.append(testing::blinkRootDir()); |
27 filePath.append('/'); | 34 filePath.append('/'); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
141 // segments into the contiguous buffer. If the ImageDecoder was pointing to | 148 // segments into the contiguous buffer. If the ImageDecoder was pointing to |
142 // data in a segment, its pointer would no longer be valid. | 149 // data in a segment, its pointer would no longer be valid. |
143 segmentedData->data(); | 150 segmentedData->data(); |
144 | 151 |
145 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 152 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
146 ASSERT_FALSE(decoder->failed()); | 153 ASSERT_FALSE(decoder->failed()); |
147 EXPECT_EQ(frame->getStatus(), ImageFrame::FrameComplete); | 154 EXPECT_EQ(frame->getStatus(), ImageFrame::FrameComplete); |
148 EXPECT_EQ(hashBitmap(frame->bitmap()), hash); | 155 EXPECT_EQ(hashBitmap(frame->bitmap()), hash); |
149 } | 156 } |
150 | 157 |
158 void testRandomFrameDecode(DecoderCreator createDecoder, const char* file, | |
159 size_t skippingStep) { | |
160 SCOPED_TRACE(file); | |
161 | |
162 RefPtr<SharedBuffer> fullData = readFile(file); | |
163 ASSERT_TRUE(fullData.get()); | |
164 Vector<unsigned> baselineHashes; | |
165 createDecodingBaseline(createDecoder, fullData.get(), &baselineHashes); | |
166 size_t frameCount = baselineHashes.size(); | |
167 | |
168 // Random decoding should get the same results as sequential decoding. | |
169 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | |
170 decoder->setData(fullData.get(), true); | |
171 for (size_t i = 0; i < skippingStep; ++i) { | |
172 for (size_t j = i; j < frameCount; j += skippingStep) { | |
173 SCOPED_TRACE(::testing::Message() << "Random i:" << i << " j:" << j); | |
174 ImageFrame* frame = decoder->frameBufferAtIndex(j); | |
175 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap())); | |
176 } | |
177 } | |
178 | |
179 // Decoding in reverse order. | |
180 decoder = createDecoder(); | |
181 decoder->setData(fullData.get(), true); | |
182 for (size_t i = frameCount; i; --i) { | |
183 SCOPED_TRACE(::testing::Message() << "Reverse i:" << i); | |
184 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); | |
185 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->bitmap())); | |
186 } | |
187 } | |
188 | |
189 void testRandomDecodeAfterClearFrameBufferCache(DecoderCreator createDecoder, | |
190 const char* file, | |
191 size_t skippingStep) { | |
192 SCOPED_TRACE(file); | |
193 | |
194 RefPtr<SharedBuffer> data = readFile(file); | |
195 ASSERT_TRUE(data.get()); | |
196 Vector<unsigned> baselineHashes; | |
197 createDecodingBaseline(createDecoder, data.get(), &baselineHashes); | |
198 size_t frameCount = baselineHashes.size(); | |
199 | |
200 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | |
201 decoder->setData(data.get(), true); | |
202 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; | |
203 ++clearExceptFrame) { | |
204 decoder->clearCacheExceptFrame(clearExceptFrame); | |
205 for (size_t i = 0; i < skippingStep; ++i) { | |
206 for (size_t j = 0; j < frameCount; j += skippingStep) { | |
207 SCOPED_TRACE(::testing::Message() << "Random i:" << i << " j:" << j); | |
208 ImageFrame* frame = decoder->frameBufferAtIndex(j); | |
209 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap())); | |
210 } | |
211 } | |
212 } | |
213 } | |
214 | |
215 void testDecodeAfterReallocatingData(DecoderCreator createDecoder, | |
216 const char* file) { | |
217 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | |
218 RefPtr<SharedBuffer> data = readFile(file); | |
219 ASSERT_TRUE(data.get()); | |
220 | |
221 // Parse from 'data'. | |
222 decoder->setData(data.get(), true); | |
223 size_t frameCount = decoder->frameCount(); | |
224 | |
225 // ... and then decode frames from 'reallocatedData'. | |
226 RefPtr<SharedBuffer> reallocatedData = data.get()->copy(); | |
227 ASSERT_TRUE(reallocatedData.get()); | |
228 data.clear(); | |
229 decoder->setData(reallocatedData.get(), true); | |
230 | |
231 for (size_t i = 0; i < frameCount; ++i) { | |
232 const ImageFrame* const frame = decoder->frameBufferAtIndex(i); | |
233 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus()); | |
234 } | |
235 } | |
236 | |
237 void testByteByByteSizeAvailable(DecoderCreator createDecoder, | |
238 const char* file, | |
239 size_t frameOffset, | |
240 bool hasColorSpace, | |
241 int expectedRepetitionCount) { | |
242 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | |
243 RefPtr<SharedBuffer> data = readFile(file); | |
244 ASSERT_TRUE(data.get()); | |
245 EXPECT_LT(frameOffset, data->size()); | |
246 | |
247 // Send data to the decoder byte-by-byte and use the provided frame offset in | |
248 // the data to check that isSizeAvailable() changes state only when that | |
249 // offset is reached. Also check other decoder state. | |
250 for (size_t length = 1; length <= frameOffset; ++length) { | |
251 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), length); | |
252 decoder->setData(tempData.get(), false); | |
253 | |
254 if (length < frameOffset) { | |
255 EXPECT_FALSE(decoder->isSizeAvailable()); | |
256 EXPECT_TRUE(decoder->size().isEmpty()); | |
257 EXPECT_FALSE(decoder->hasEmbeddedColorSpace()); | |
258 EXPECT_EQ(0u, decoder->frameCount()); | |
259 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | |
260 EXPECT_FALSE(decoder->frameBufferAtIndex(0)); | |
261 } else { | |
262 EXPECT_TRUE(decoder->isSizeAvailable()); | |
263 EXPECT_FALSE(decoder->size().isEmpty()); | |
264 EXPECT_EQ(decoder->hasEmbeddedColorSpace(), hasColorSpace); | |
265 EXPECT_EQ(1u, decoder->frameCount()); | |
266 EXPECT_EQ(expectedRepetitionCount, decoder->repetitionCount()); | |
267 } | |
268 | |
269 EXPECT_FALSE(decoder->failed()); | |
270 if (decoder->failed()) | |
scroggo_chromium
2016/11/09 14:38:37
If you change EXPECT_FALSE to ASSERT_FALSE, this c
joostouwerling
2016/11/10 17:15:13
Done.
| |
271 return; | |
272 } | |
273 } | |
274 | |
275 void testProgressiveDecoding(DecoderCreator createDecoder, const char *file, | |
276 size_t increment) | |
277 { | |
278 RefPtr<SharedBuffer> fullData = readFile(file); | |
279 ASSERT_TRUE(fullData.get()); | |
280 const size_t fullLength = fullData->size(); | |
281 | |
282 std::unique_ptr<ImageDecoder> decoder; | |
283 ImageFrame* frame; | |
scroggo_chromium
2016/11/09 14:38:37
Please move this to where it's used. No need for i
joostouwerling
2016/11/10 17:15:13
Done.
| |
284 | |
285 Vector<unsigned> truncatedHashes; | |
286 Vector<unsigned> progressiveHashes; | |
287 | |
288 // Compute hashes when the file is truncated. | |
289 for (size_t i = 1; i <= fullLength; i += increment) { | |
290 decoder = createDecoder(); | |
291 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); | |
292 decoder->setData(data.get(), i == fullLength); | |
293 frame = decoder->frameBufferAtIndex(0); | |
294 if (!frame) { | |
295 truncatedHashes.append(0); | |
296 continue; | |
297 } | |
298 truncatedHashes.append(hashBitmap(frame->bitmap())); | |
299 } | |
300 | |
301 // Compute hashes when the file is progressively decoded. | |
302 decoder = createDecoder(); | |
303 for (size_t i = 1; i <= fullLength; i += increment) { | |
304 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); | |
305 decoder->setData(data.get(), i == fullLength); | |
306 frame = decoder->frameBufferAtIndex(0); | |
307 if (!frame) { | |
308 progressiveHashes.append(0); | |
309 continue; | |
310 } | |
311 progressiveHashes.append(hashBitmap(frame->bitmap())); | |
312 } | |
313 | |
314 bool match = true; | |
315 for (size_t i = 0; i < truncatedHashes.size(); ++i) { | |
316 if (truncatedHashes[i] != progressiveHashes[i]) { | |
scroggo_chromium
2016/11/09 14:38:37
I think this came up in your CL for APNG - this ca
joostouwerling
2016/11/10 17:15:13
Done.
| |
317 match = false; | |
318 break; | |
319 } | |
320 } | |
321 EXPECT_TRUE(match); | |
322 } | |
323 | |
151 } // namespace blink | 324 } // namespace blink |
OLD | NEW |