Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp

Issue 2490473005: Pull up equivalent image decoding tests (Closed)
Patch Set: Add repetition count test for radient.gif Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698