1591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch/* 2591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * Copyright (C) 2013 Google Inc. All rights reserved. 3591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * 4591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * Redistribution and use in source and binary forms, with or without 5591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * modification, are permitted provided that the following conditions are 6591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * met: 7591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * 8591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * * Redistributions of source code must retain the above copyright 9591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * notice, this list of conditions and the following disclaimer. 10591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * * Redistributions in binary form must reproduce the above 11591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * copyright notice, this list of conditions and the following disclaimer 12591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * in the documentation and/or other materials provided with the 13591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * distribution. 14591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * * Neither the name of Google Inc. nor the names of its 15591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * contributors may be used to endorse or promote products derived from 16591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * this software without specific prior written permission. 17591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * 18591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch */ 30591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 31591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "config.h" 32591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 33591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/platform/image-decoders/webp/WEBPImageDecoder.h" 34591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 35591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "RuntimeEnabledFeatures.h" 36591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/platform/SharedBuffer.h" 37591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "public/platform/Platform.h" 38591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "public/platform/WebData.h" 39591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "public/platform/WebSize.h" 40591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "public/platform/WebUnitTestSupport.h" 41591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/OwnPtr.h" 42591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/PassOwnPtr.h" 43591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/StringHasher.h" 44591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/Vector.h" 45591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/dtoa/utils.h" 46591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include <gtest/gtest.h> 47591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 48591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochusing namespace WebCore; 49591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochusing namespace WebKit; 50591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 51591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#if !OS(ANDROID) 52591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 53591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochnamespace { 54591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 55591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochPassRefPtr<SharedBuffer> readFile(const char* fileName) 56591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 57591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch String filePath = Platform::current()->unitTestSupport()->webKitRootDir(); 58591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch filePath.append(fileName); 59591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 600474e3614ae9be9fbf4fd50d825fd6e7c3d30b63Ben Murdoch return Platform::current()->unitTestSupport()->readFromFile(filePath); 61591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 62591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 63591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochPassOwnPtr<WEBPImageDecoder> createDecoder() 64591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 65591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return adoptPtr(new WEBPImageDecoder(ImageSource::AlphaNotPremultiplied, ImageSource::GammaAndColorProfileApplied)); 66591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 67591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 68591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochunsigned hashSkBitmap(const SkBitmap& bitmap) 69591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 70591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize()); 71591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 72591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 73591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid createDecodingBaseline(SharedBuffer* data, Vector<unsigned>* baselineHashes) 74591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 75591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder = createDecoder(); 76591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(data, true); 77591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch size_t frameCount = decoder->frameCount(); 78591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < frameCount; ++i) { 79591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame* frame = decoder->frameBufferAtIndex(i); 80591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch baselineHashes->append(hashSkBitmap(frame->getSkBitmap())); 81591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 82591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 83591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 84591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid testRandomFrameDecode(const char* webpFile) 85591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 86591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SCOPED_TRACE(webpFile); 87591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 88591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> fullData = readFile(webpFile); 89591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_TRUE(fullData.get()); 90591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch Vector<unsigned> baselineHashes; 91591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch createDecodingBaseline(fullData.get(), &baselineHashes); 92591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch size_t frameCount = baselineHashes.size(); 93591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 94591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Random decoding should get the same results as sequential decoding. 95591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder = createDecoder(); 96591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(fullData.get(), true); 97591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const size_t skippingStep = 5; 98591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < skippingStep; ++i) { 99591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t j = i; j < frameCount; j += skippingStep) { 100591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); 101591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame* frame = decoder->frameBufferAtIndex(j); 102591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())); 103591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 104591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 105591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 106591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Decoding in reverse order. 107591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder = createDecoder(); 108591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(fullData.get(), true); 109591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = frameCount; i; --i) { 110591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SCOPED_TRACE(testing::Message() << "Reverse i:" << i); 111591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); 112591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(baselineHashes[i - 1], hashSkBitmap(frame->getSkBitmap())); 113591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 114591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 115591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 116591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid testRandomDecodeAfterClearFrameBufferCache(const char* webpFile) 117591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 118591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SCOPED_TRACE(webpFile); 119591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 120591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> data = readFile(webpFile); 121591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_TRUE(data.get()); 122591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch Vector<unsigned> baselineHashes; 123591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch createDecodingBaseline(data.get(), &baselineHashes); 124591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch size_t frameCount = baselineHashes.size(); 125591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 126591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder = createDecoder(); 127591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(data.get(), true); 128591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExceptFrame) { 129591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->clearCacheExceptFrame(clearExceptFrame); 130591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const size_t skippingStep = 5; 131591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < skippingStep; ++i) { 132591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t j = 0; j < frameCount; j += skippingStep) { 133591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); 134591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame* frame = decoder->frameBufferAtIndex(j); 135591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())); 136591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 137591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 138591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 139591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 140591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 141591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} // namespace 142591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 143591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochclass AnimatedWebPTests : public ::testing::Test { 144591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochprotected: 145591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch virtual void SetUp() 146591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { 147591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Enable animated WebP for all the tests. 148591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch WebCore::RuntimeEnabledFeatures::setAnimatedWebPEnabled(true); 149591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 150591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch}; 151591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 152591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochTEST_F(AnimatedWebPTests, verifyAnimationParametersTransparentImage) 153591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 154591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder = createDecoder(); 155591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 156591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 157591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/webp-animated.webp"); 158591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_TRUE(data.get()); 159591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(data.get(), true); 160591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 161591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const int canvasWidth = 11; 162591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const int canvasHeight = 29; 163591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const struct AnimParam { 164591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int xOffset, yOffset, width, height; 165591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame::FrameDisposalMethod dispose; 166591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch unsigned duration; 167591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch bool hasAlpha; 168591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } frameParameters[] = { 169591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { 0, 0, 11, 29, ImageFrame::DisposeKeep, 1000u, true }, 170591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { 2, 10, 7, 17, ImageFrame::DisposeKeep, 500u, true }, 171591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { 2, 2, 7, 16, ImageFrame::DisposeKeep, 1000u, true }, 172591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch }; 173591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 174591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < ARRAY_SIZE(frameParameters); ++i) { 175591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const ImageFrame* const frame = decoder->frameBufferAtIndex(i); 176591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 177591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(canvasWidth, frame->getSkBitmap().width()); 178591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(canvasHeight, frame->getSkBitmap().height()); 179591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].xOffset, frame->originalFrameRect().x()); 180591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].yOffset, frame->originalFrameRect().y()); 181591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].width, frame->originalFrameRect().width()); 182591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].height, frame->originalFrameRect().height()); 183591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].dispose, frame->disposalMethod()); 184591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].duration, frame->duration()); 185591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].hasAlpha, frame->hasAlpha()); 186591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 187591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 188591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(ARRAY_SIZE(frameParameters), decoder->frameCount()); 189591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 190591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 191591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 192591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochTEST_F(AnimatedWebPTests, verifyAnimationParametersOpaqueFramesTransparentBackground) 193591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 194591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder = createDecoder(); 195591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 196591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 197591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/webp-animated-opaque.webp"); 198591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_TRUE(data.get()); 199591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(data.get(), true); 200591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 201591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const int canvasWidth = 94; 202591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const int canvasHeight = 87; 203591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const struct AnimParam { 204591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int xOffset, yOffset, width, height; 205591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame::FrameDisposalMethod dispose; 206591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch unsigned duration; 207591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch bool hasAlpha; 208591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } frameParameters[] = { 209591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { 4, 10, 33, 32, ImageFrame::DisposeOverwriteBgcolor, 1000u, true }, 210591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { 34, 30, 33, 32, ImageFrame::DisposeOverwriteBgcolor, 1000u, true }, 211591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { 62, 50, 32, 32, ImageFrame::DisposeOverwriteBgcolor, 1000u, true }, 212591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { 10, 54, 32, 33, ImageFrame::DisposeOverwriteBgcolor, 1000u, true }, 213591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch }; 214591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 215591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < ARRAY_SIZE(frameParameters); ++i) { 216591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const ImageFrame* const frame = decoder->frameBufferAtIndex(i); 217591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 218591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(canvasWidth, frame->getSkBitmap().width()); 219591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(canvasHeight, frame->getSkBitmap().height()); 220591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].xOffset, frame->originalFrameRect().x()); 221591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].yOffset, frame->originalFrameRect().y()); 222591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].width, frame->originalFrameRect().width()); 223591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].height, frame->originalFrameRect().height()); 224591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].dispose, frame->disposalMethod()); 225591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].duration, frame->duration()); 226591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameParameters[i].hasAlpha, frame->hasAlpha()); 227591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 228591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 229591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(ARRAY_SIZE(frameParameters), decoder->frameCount()); 230591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 231591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 232591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 233591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochTEST_F(AnimatedWebPTests, parseAndDecodeByteByByte) 234591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 235591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const struct TestImage { 236591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const char* filename; 237591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch unsigned frameCount; 238591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int repetitionCount; 239591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } testImages[] = { 240591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { "/LayoutTests/fast/images/resources/webp-animated.webp", 3u, cAnimationLoopInfinite }, 241591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp", 13u, 32000 }, 242591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch }; 243591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 244591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < ARRAY_SIZE(testImages); ++i) { 245591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder = createDecoder(); 246591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> data = readFile(testImages[i].filename); 247591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_TRUE(data.get()); 248591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 249591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch size_t frameCount = 0; 250591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch size_t framesDecoded = 0; 251591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 252591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Pass data to decoder byte by byte. 253591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t length = 1; length <= data->size(); ++length) { 254591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), length); 255591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(tempData.get(), length == data->size()); 256591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 257591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_LE(frameCount, decoder->frameCount()); 258591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch frameCount = decoder->frameCount(); 259591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 260591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); 261591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (frame && frame->status() == ImageFrame::FrameComplete && framesDecoded < frameCount) 262591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ++framesDecoded; 263591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 264591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 265591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(testImages[i].frameCount, decoder->frameCount()); 266591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(testImages[i].frameCount, framesDecoded); 267591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(testImages[i].repetitionCount, decoder->repetitionCount()); 268591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 269591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 270591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 271591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochTEST_F(AnimatedWebPTests, invalidImage) 272591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 273591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder = createDecoder(); 274591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 275591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/invalid-animated-webp.webp"); 276591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_TRUE(data.get()); 277591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(data.get(), true); 278591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 279591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(0u, decoder->frameCount()); 280591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame* frame = decoder->frameBufferAtIndex(0); 281591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_FALSE(frame); 282591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 283591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 284591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 285591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochTEST_F(AnimatedWebPTests, progressiveDecode) 286591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 287591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources/webp-animated.webp"); 288591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_TRUE(fullData.get()); 289591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const size_t fullLength = fullData->size(); 290591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 291591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder; 292591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame* frame; 293591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 294591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch Vector<unsigned> truncatedHashes; 295591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch Vector<unsigned> progressiveHashes; 296591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 297591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Compute hashes when the file is truncated. 298591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const size_t increment = 1; 299591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 1; i <= fullLength; i += increment) { 300591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder = createDecoder(); 301591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); 302591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(data.get(), i == fullLength); 303591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch frame = decoder->frameBufferAtIndex(0); 304591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!frame) { 305591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch truncatedHashes.append(0); 306591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch continue; 307591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 308591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch truncatedHashes.append(hashSkBitmap(frame->getSkBitmap())); 309591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 310591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 311591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Compute hashes when the file is progressively decoded. 312591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder = createDecoder(); 313591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 1; i <= fullLength; i += increment) { 314591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); 315591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(data.get(), i == fullLength); 316591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch frame = decoder->frameBufferAtIndex(0); 317591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!frame) { 318591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch progressiveHashes.append(0); 319591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch continue; 320591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 321591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch progressiveHashes.append(hashSkBitmap(frame->getSkBitmap())); 322591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 323591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 324591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch bool match = true; 325591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < truncatedHashes.size(); ++i) { 326591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (truncatedHashes[i] != progressiveHashes[i]) { 327591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch match = false; 328591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch break; 329591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 330591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 331591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_TRUE(match); 332591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 333591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 334591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochTEST_F(AnimatedWebPTests, frameIsCompleteAndDuration) 335591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 336591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder = createDecoder(); 337591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 338591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/webp-animated.webp"); 339591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_TRUE(data.get()); 340591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 341591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_GE(data->size(), 10u); 342591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->size() - 10); 343591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(tempData.get(), false); 344591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 345591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(2u, decoder->frameCount()); 346591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_FALSE(decoder->failed()); 347591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 348591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(1000, decoder->frameDurationAtIndex(0)); 349591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); 350591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(500, decoder->frameDurationAtIndex(1)); 351591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 352591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(data.get(), true); 353591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(3u, decoder->frameCount()); 354591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 355591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(1000, decoder->frameDurationAtIndex(0)); 356591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); 357591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(500, decoder->frameDurationAtIndex(1)); 358591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_TRUE(decoder->frameIsCompleteAtIndex(2)); 359591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(1000.0, decoder->frameDurationAtIndex(2)); 360591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 361591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 362591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochTEST_F(AnimatedWebPTests, updateRequiredPreviousFrameAfterFirstDecode) 363591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 364591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder = createDecoder(); 365591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 366591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources/webp-animated.webp"); 367591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_TRUE(fullData.get()); 368591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 369591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Give it data that is enough to parse but not decode in order to check the status 370591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // of requiredPreviousFrameIndex before decoding. 371591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch size_t partialSize = 1; 372591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch do { 373591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), partialSize); 374591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(data.get(), false); 375591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ++partialSize; 376591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty); 377591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 378591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(notFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameIndex()); 379591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch unsigned frameCount = decoder->frameCount(); 380591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 1; i < frameCount; ++i) 381591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIndex()); 382591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 383591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(fullData.get(), true); 384591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < frameCount; ++i) 385591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(notFound, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIndex()); 386591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 387591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 388591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochTEST_F(AnimatedWebPTests, randomFrameDecode) 389591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 390591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch testRandomFrameDecode("/LayoutTests/fast/images/resources/webp-animated.webp"); 391591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch testRandomFrameDecode("/LayoutTests/fast/images/resources/webp-animated-opaque.webp"); 392591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch testRandomFrameDecode("/LayoutTests/fast/images/resources/webp-animated-large.webp"); 393591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch testRandomFrameDecode("/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp"); 394591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 395591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 396591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochTEST_F(AnimatedWebPTests, randomDecodeAfterClearFrameBufferCache) 397591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 398591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resources/webp-animated.webp"); 399591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resources/webp-animated-opaque.webp"); 400591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resources/webp-animated-large.webp"); 401591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp"); 402591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 403591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 404591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochTEST_F(AnimatedWebPTests, resumePartialDecodeAfterClearFrameBufferCache) 405591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 406591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources/webp-animated-large.webp"); 407591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_TRUE(fullData.get()); 408591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch Vector<unsigned> baselineHashes; 409591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch createDecodingBaseline(fullData.get(), &baselineHashes); 410591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch size_t frameCount = baselineHashes.size(); 411591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 412591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch OwnPtr<WEBPImageDecoder> decoder = createDecoder(); 413591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 414591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Let frame 0 be partially decoded. 415591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch size_t partialSize = 1; 416591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch do { 417591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), partialSize); 418591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(data.get(), false); 419591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ++partialSize; 420591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty); 421591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 422591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Skip to the last frame and clear. 423591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->setData(fullData.get(), true); 424591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(frameCount, decoder->frameCount()); 425591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1); 426591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(baselineHashes[frameCount - 1], hashSkBitmap(lastFrame->getSkBitmap())); 427591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch decoder->clearCacheExceptFrame(notFound); 428591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 429591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // Resume decoding of the first frame. 430591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ImageFrame* firstFrame = decoder->frameBufferAtIndex(0); 431591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status()); 432591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch EXPECT_EQ(baselineHashes[0], hashSkBitmap(firstFrame->getSkBitmap())); 433591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 434591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 435591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#endif 436