Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / image-decoders / ImageDecoderTest.cpp
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32
33 #include "platform/image-decoders/ImageDecoder.h"
34
35 #include "platform/image-decoders/ImageFrame.h"
36 #include "wtf/OwnPtr.h"
37 #include "wtf/PassOwnPtr.h"
38 #include "wtf/Vector.h"
39 #include <gtest/gtest.h>
40
41 using namespace blink;
42
43 class TestImageDecoder : public ImageDecoder {
44 public:
45     TestImageDecoder()
46         : ImageDecoder(ImageSource::AlphaNotPremultiplied, ImageSource::GammaAndColorProfileApplied, noDecodedImageByteLimit)
47     {
48     }
49
50     virtual String filenameExtension() const override { return ""; }
51     virtual ImageFrame* frameBufferAtIndex(size_t) override { return 0; }
52
53     Vector<ImageFrame, 1>& frameBufferCache()
54     {
55         return m_frameBufferCache;
56     }
57
58     void resetRequiredPreviousFrames(bool knownOpaque = false)
59     {
60         for (size_t i = 0; i < m_frameBufferCache.size(); ++i)
61             m_frameBufferCache[i].setRequiredPreviousFrameIndex(findRequiredPreviousFrame(i, knownOpaque));
62     }
63
64     void initFrames(size_t numFrames, unsigned width = 100, unsigned height = 100)
65     {
66         setSize(width, height);
67         m_frameBufferCache.resize(numFrames);
68         for (size_t i = 0; i < numFrames; ++i)
69             m_frameBufferCache[i].setOriginalFrameRect(IntRect(0, 0, width, height));
70     }
71 };
72
73 TEST(ImageDecoderTest, sizeCalculationMayOverflow)
74 {
75     OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
76     EXPECT_FALSE(decoder->setSize(1 << 29, 1));
77     EXPECT_FALSE(decoder->setSize(1, 1 << 29));
78     EXPECT_FALSE(decoder->setSize(1 << 15, 1 << 15));
79     EXPECT_TRUE(decoder->setSize(1 << 28, 1));
80     EXPECT_TRUE(decoder->setSize(1, 1 << 28));
81     EXPECT_TRUE(decoder->setSize(1 << 14, 1 << 14));
82 }
83
84 TEST(ImageDecoderTest, requiredPreviousFrameIndex)
85 {
86     OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
87     decoder->initFrames(6);
88     Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
89
90     frameBuffers[1].setDisposalMethod(ImageFrame::DisposeKeep);
91     frameBuffers[2].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
92     frameBuffers[3].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
93     frameBuffers[4].setDisposalMethod(ImageFrame::DisposeKeep);
94
95     decoder->resetRequiredPreviousFrames();
96
97     // The first frame doesn't require any previous frame.
98     EXPECT_EQ(kNotFound, frameBuffers[0].requiredPreviousFrameIndex());
99     // The previous DisposeNotSpecified frame is required.
100     EXPECT_EQ(0u, frameBuffers[1].requiredPreviousFrameIndex());
101     // DisposeKeep is treated as DisposeNotSpecified.
102     EXPECT_EQ(1u, frameBuffers[2].requiredPreviousFrameIndex());
103     // Previous DisposeOverwritePrevious frames are skipped.
104     EXPECT_EQ(1u, frameBuffers[3].requiredPreviousFrameIndex());
105     EXPECT_EQ(1u, frameBuffers[4].requiredPreviousFrameIndex());
106     EXPECT_EQ(4u, frameBuffers[5].requiredPreviousFrameIndex());
107 }
108
109 TEST(ImageDecoderTest, requiredPreviousFrameIndexDisposeOverwriteBgcolor)
110 {
111     OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
112     decoder->initFrames(3);
113     Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
114
115     // Fully covering DisposeOverwriteBgcolor previous frame resets the starting state.
116     frameBuffers[1].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
117     decoder->resetRequiredPreviousFrames();
118     EXPECT_EQ(kNotFound, frameBuffers[2].requiredPreviousFrameIndex());
119
120     // Partially covering DisposeOverwriteBgcolor previous frame is required by this frame.
121     frameBuffers[1].setOriginalFrameRect(IntRect(50, 50, 50, 50));
122     decoder->resetRequiredPreviousFrames();
123     EXPECT_EQ(1u, frameBuffers[2].requiredPreviousFrameIndex());
124 }
125
126 TEST(ImageDecoderTest, requiredPreviousFrameIndexForFrame1)
127 {
128     OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
129     decoder->initFrames(2);
130     Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
131
132     decoder->resetRequiredPreviousFrames();
133     EXPECT_EQ(0u, frameBuffers[1].requiredPreviousFrameIndex());
134
135     // The first frame with DisposeOverwritePrevious or DisposeOverwriteBgcolor
136     // resets the starting state.
137     frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
138     decoder->resetRequiredPreviousFrames();
139     EXPECT_EQ(kNotFound, frameBuffers[1].requiredPreviousFrameIndex());
140     frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
141     decoder->resetRequiredPreviousFrames();
142     EXPECT_EQ(kNotFound, frameBuffers[1].requiredPreviousFrameIndex());
143
144     // ... even if it partially covers.
145     frameBuffers[0].setOriginalFrameRect(IntRect(50, 50, 50, 50));
146
147     frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
148     decoder->resetRequiredPreviousFrames();
149     EXPECT_EQ(kNotFound, frameBuffers[1].requiredPreviousFrameIndex());
150     frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
151     decoder->resetRequiredPreviousFrames();
152     EXPECT_EQ(kNotFound, frameBuffers[1].requiredPreviousFrameIndex());
153 }
154
155 TEST(ImageDecoderTest, requiredPreviousFrameIndexBlendAtopBgcolor)
156 {
157     OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
158     decoder->initFrames(3);
159     Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
160
161     frameBuffers[1].setOriginalFrameRect(IntRect(25, 25, 50, 50));
162     frameBuffers[2].setAlphaBlendSource(ImageFrame::BlendAtopBgcolor);
163
164     // A full frame with 'blending method == BlendAtopBgcolor' doesn't depend on any prior frames.
165     for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= ImageFrame::DisposeOverwritePrevious; ++disposeMethod) {
166         frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod>(disposeMethod));
167         decoder->resetRequiredPreviousFrames();
168         EXPECT_EQ(kNotFound, frameBuffers[2].requiredPreviousFrameIndex());
169     }
170
171     // A non-full frame with 'blending method == BlendAtopBgcolor' does depend on a prior frame.
172     frameBuffers[2].setOriginalFrameRect(IntRect(50, 50, 50, 50));
173     for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= ImageFrame::DisposeOverwritePrevious; ++disposeMethod) {
174         frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod>(disposeMethod));
175         decoder->resetRequiredPreviousFrames();
176         EXPECT_NE(kNotFound, frameBuffers[2].requiredPreviousFrameIndex());
177     }
178 }
179
180 TEST(ImageDecoderTest, requiredPreviousFrameIndexKnownOpaque)
181 {
182     OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
183     decoder->initFrames(3);
184     Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
185
186     frameBuffers[1].setOriginalFrameRect(IntRect(25, 25, 50, 50));
187
188     // A full frame that is known to be opaque doesn't depend on any prior frames.
189     for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= ImageFrame::DisposeOverwritePrevious; ++disposeMethod) {
190         frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod>(disposeMethod));
191         decoder->resetRequiredPreviousFrames(true);
192         EXPECT_EQ(kNotFound, frameBuffers[2].requiredPreviousFrameIndex());
193     }
194
195     // A non-full frame that is known to be opaque does depend on a prior frame.
196     frameBuffers[2].setOriginalFrameRect(IntRect(50, 50, 50, 50));
197     for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= ImageFrame::DisposeOverwritePrevious; ++disposeMethod) {
198         frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod>(disposeMethod));
199         decoder->resetRequiredPreviousFrames(true);
200         EXPECT_NE(kNotFound, frameBuffers[2].requiredPreviousFrameIndex());
201     }
202 }
203
204 TEST(ImageDecoderTest, clearCacheExceptFrameDoNothing)
205 {
206     OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
207     decoder->clearCacheExceptFrame(0);
208
209     // This should not crash.
210     decoder->initFrames(20);
211     decoder->clearCacheExceptFrame(kNotFound);
212 }
213
214 TEST(ImageDecoderTest, clearCacheExceptFrameAll)
215 {
216     const size_t numFrames = 10;
217     OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
218     decoder->initFrames(numFrames);
219     Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
220     for (size_t i = 0; i < numFrames; ++i)
221         frameBuffers[i].setStatus(i % 2 ? ImageFrame::FramePartial : ImageFrame::FrameComplete);
222
223     decoder->clearCacheExceptFrame(kNotFound);
224
225     for (size_t i = 0; i < numFrames; ++i) {
226         SCOPED_TRACE(testing::Message() << i);
227         EXPECT_EQ(ImageFrame::FrameEmpty, frameBuffers[i].status());
228     }
229 }
230
231 TEST(ImageDecoderTest, clearCacheExceptFramePreverveClearExceptFrame)
232 {
233     const size_t numFrames = 10;
234     OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
235     decoder->initFrames(numFrames);
236     Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
237     for (size_t i = 0; i < numFrames; ++i)
238         frameBuffers[i].setStatus(ImageFrame::FrameComplete);
239
240     decoder->resetRequiredPreviousFrames();
241     decoder->clearCacheExceptFrame(5);
242     for (size_t i = 0; i < numFrames; ++i) {
243         SCOPED_TRACE(testing::Message() << i);
244         if (i == 5)
245             EXPECT_EQ(ImageFrame::FrameComplete, frameBuffers[i].status());
246         else
247             EXPECT_EQ(ImageFrame::FrameEmpty, frameBuffers[i].status());
248     }
249 }