OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 } | 47 } |
48 | 48 |
49 virtual String filenameExtension() const OVERRIDE { return ""; } | 49 virtual String filenameExtension() const OVERRIDE { return ""; } |
50 virtual ImageFrame* frameBufferAtIndex(size_t) OVERRIDE { return 0; } | 50 virtual ImageFrame* frameBufferAtIndex(size_t) OVERRIDE { return 0; } |
51 | 51 |
52 Vector<ImageFrame, 1>& frameBufferCache() | 52 Vector<ImageFrame, 1>& frameBufferCache() |
53 { | 53 { |
54 return m_frameBufferCache; | 54 return m_frameBufferCache; |
55 } | 55 } |
56 | 56 |
57 void resetRequiredPreviousFrames() | 57 void resetRequiredPreviousFrames(bool knownOpaque = false) |
58 { | 58 { |
59 for (size_t i = 0; i < m_frameBufferCache.size(); ++i) | 59 for (size_t i = 0; i < m_frameBufferCache.size(); ++i) |
60 m_frameBufferCache[i].setRequiredPreviousFrameIndex(findRequiredPrev
iousFrame(i)); | 60 m_frameBufferCache[i].setRequiredPreviousFrameIndex(findRequiredPrev
iousFrame(i, knownOpaque)); |
61 } | 61 } |
62 | 62 |
63 void initFrames(size_t numFrames, unsigned width = 100, unsigned height = 10
0) | 63 void initFrames(size_t numFrames, unsigned width = 100, unsigned height = 10
0) |
64 { | 64 { |
65 setSize(width, height); | 65 setSize(width, height); |
66 m_frameBufferCache.resize(numFrames); | 66 m_frameBufferCache.resize(numFrames); |
67 for (size_t i = 0; i < numFrames; ++i) | 67 for (size_t i = 0; i < numFrames; ++i) |
68 m_frameBufferCache[i].setOriginalFrameRect(IntRect(0, 0, width, heig
ht)); | 68 m_frameBufferCache[i].setOriginalFrameRect(IntRect(0, 0, width, heig
ht)); |
69 } | 69 } |
70 }; | 70 }; |
71 | 71 |
72 TEST(ImageDecoderTest, requiredPreviousFrameIndex) | 72 TEST(ImageDecoderTest, requiredPreviousFrameIndex) |
73 { | 73 { |
74 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); | 74 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); |
75 decoder->initFrames(6); | 75 decoder->initFrames(6); |
76 Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache()
; | 76 Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache(); |
77 | 77 |
78 decoderFrameBufferCache[1].setDisposalMethod(ImageFrame::DisposeKeep); | 78 frameBuffers[1].setDisposalMethod(ImageFrame::DisposeKeep); |
79 decoderFrameBufferCache[2].setDisposalMethod(ImageFrame::DisposeOverwritePre
vious); | 79 frameBuffers[2].setDisposalMethod(ImageFrame::DisposeOverwritePrevious); |
80 decoderFrameBufferCache[3].setDisposalMethod(ImageFrame::DisposeOverwritePre
vious); | 80 frameBuffers[3].setDisposalMethod(ImageFrame::DisposeOverwritePrevious); |
81 decoderFrameBufferCache[4].setDisposalMethod(ImageFrame::DisposeKeep); | 81 frameBuffers[4].setDisposalMethod(ImageFrame::DisposeKeep); |
82 | 82 |
83 decoder->resetRequiredPreviousFrames(); | 83 decoder->resetRequiredPreviousFrames(); |
84 | 84 |
85 // The first frame doesn't require any previous frame. | 85 // The first frame doesn't require any previous frame. |
86 EXPECT_EQ(notFound, decoderFrameBufferCache[0].requiredPreviousFrameIndex())
; | 86 EXPECT_EQ(notFound, frameBuffers[0].requiredPreviousFrameIndex()); |
87 // The previous DisposeNotSpecified frame is required. | 87 // The previous DisposeNotSpecified frame is required. |
88 EXPECT_EQ(0u, decoderFrameBufferCache[1].requiredPreviousFrameIndex()); | 88 EXPECT_EQ(0u, frameBuffers[1].requiredPreviousFrameIndex()); |
89 // DisposeKeep is treated as DisposeNotSpecified. | 89 // DisposeKeep is treated as DisposeNotSpecified. |
90 EXPECT_EQ(1u, decoderFrameBufferCache[2].requiredPreviousFrameIndex()); | 90 EXPECT_EQ(1u, frameBuffers[2].requiredPreviousFrameIndex()); |
91 // Previous DisposeOverwritePrevious frames are skipped. | 91 // Previous DisposeOverwritePrevious frames are skipped. |
92 EXPECT_EQ(1u, decoderFrameBufferCache[3].requiredPreviousFrameIndex()); | 92 EXPECT_EQ(1u, frameBuffers[3].requiredPreviousFrameIndex()); |
93 EXPECT_EQ(1u, decoderFrameBufferCache[4].requiredPreviousFrameIndex()); | 93 EXPECT_EQ(1u, frameBuffers[4].requiredPreviousFrameIndex()); |
94 EXPECT_EQ(4u, decoderFrameBufferCache[5].requiredPreviousFrameIndex()); | 94 EXPECT_EQ(4u, frameBuffers[5].requiredPreviousFrameIndex()); |
95 } | 95 } |
96 | 96 |
97 TEST(ImageDecoderTest, requiredPreviousFrameIndexDisposeOverwriteBgcolor) | 97 TEST(ImageDecoderTest, requiredPreviousFrameIndexDisposeOverwriteBgcolor) |
98 { | 98 { |
99 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); | 99 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); |
100 decoder->initFrames(3); | 100 decoder->initFrames(3); |
101 Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache()
; | 101 Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache(); |
102 | 102 |
103 // Fully covering DisposeOverwriteBgcolor previous frame resets the starting
state. | 103 // Fully covering DisposeOverwriteBgcolor previous frame resets the starting
state. |
104 decoderFrameBufferCache[1].setDisposalMethod(ImageFrame::DisposeOverwriteBgc
olor); | 104 frameBuffers[1].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor); |
105 decoder->resetRequiredPreviousFrames(); | 105 decoder->resetRequiredPreviousFrames(); |
106 EXPECT_EQ(notFound, decoderFrameBufferCache[2].requiredPreviousFrameIndex())
; | 106 EXPECT_EQ(notFound, frameBuffers[2].requiredPreviousFrameIndex()); |
107 | 107 |
108 // Partially covering DisposeOverwriteBgcolor previous frame is required by
this frame. | 108 // Partially covering DisposeOverwriteBgcolor previous frame is required by
this frame. |
109 decoderFrameBufferCache[1].setOriginalFrameRect(IntRect(50, 50, 50, 50)); | 109 frameBuffers[1].setOriginalFrameRect(IntRect(50, 50, 50, 50)); |
110 decoder->resetRequiredPreviousFrames(); | 110 decoder->resetRequiredPreviousFrames(); |
111 EXPECT_EQ(1u, decoderFrameBufferCache[2].requiredPreviousFrameIndex()); | 111 EXPECT_EQ(1u, frameBuffers[2].requiredPreviousFrameIndex()); |
112 } | 112 } |
113 | 113 |
114 TEST(ImageDecoderTest, requiredPreviousFrameIndexForFrame1) | 114 TEST(ImageDecoderTest, requiredPreviousFrameIndexForFrame1) |
115 { | 115 { |
116 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); | 116 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); |
117 decoder->initFrames(2); | 117 decoder->initFrames(2); |
118 Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache()
; | 118 Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache(); |
119 | 119 |
120 decoder->resetRequiredPreviousFrames(); | 120 decoder->resetRequiredPreviousFrames(); |
121 EXPECT_EQ(0u, decoderFrameBufferCache[1].requiredPreviousFrameIndex()); | 121 EXPECT_EQ(0u, frameBuffers[1].requiredPreviousFrameIndex()); |
122 | 122 |
123 // The first frame with DisposeOverwritePrevious or DisposeOverwriteBgcolor | 123 // The first frame with DisposeOverwritePrevious or DisposeOverwriteBgcolor |
124 // resets the starting state. | 124 // resets the starting state. |
125 decoderFrameBufferCache[0].setDisposalMethod(ImageFrame::DisposeOverwritePre
vious); | 125 frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwritePrevious); |
126 decoder->resetRequiredPreviousFrames(); | 126 decoder->resetRequiredPreviousFrames(); |
127 EXPECT_EQ(notFound, decoderFrameBufferCache[1].requiredPreviousFrameIndex())
; | 127 EXPECT_EQ(notFound, frameBuffers[1].requiredPreviousFrameIndex()); |
128 decoderFrameBufferCache[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgc
olor); | 128 frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor); |
129 decoder->resetRequiredPreviousFrames(); | 129 decoder->resetRequiredPreviousFrames(); |
130 EXPECT_EQ(notFound, decoderFrameBufferCache[1].requiredPreviousFrameIndex())
; | 130 EXPECT_EQ(notFound, frameBuffers[1].requiredPreviousFrameIndex()); |
131 | 131 |
132 // ... even if it partially covers. | 132 // ... even if it partially covers. |
133 decoderFrameBufferCache[0].setOriginalFrameRect(IntRect(50, 50, 50, 50)); | 133 frameBuffers[0].setOriginalFrameRect(IntRect(50, 50, 50, 50)); |
134 | 134 |
135 decoderFrameBufferCache[0].setDisposalMethod(ImageFrame::DisposeOverwritePre
vious); | 135 frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwritePrevious); |
136 decoder->resetRequiredPreviousFrames(); | 136 decoder->resetRequiredPreviousFrames(); |
137 EXPECT_EQ(notFound, decoderFrameBufferCache[1].requiredPreviousFrameIndex())
; | 137 EXPECT_EQ(notFound, frameBuffers[1].requiredPreviousFrameIndex()); |
138 decoderFrameBufferCache[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgc
olor); | 138 frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor); |
139 decoder->resetRequiredPreviousFrames(); | 139 decoder->resetRequiredPreviousFrames(); |
140 EXPECT_EQ(notFound, decoderFrameBufferCache[1].requiredPreviousFrameIndex())
; | 140 EXPECT_EQ(notFound, frameBuffers[1].requiredPreviousFrameIndex()); |
| 141 } |
| 142 |
| 143 TEST(ImageDecoderTest, requiredPreviousFrameIndexBlendAtopBgcolor) |
| 144 { |
| 145 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); |
| 146 decoder->initFrames(3); |
| 147 Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache(); |
| 148 |
| 149 frameBuffers[1].setOriginalFrameRect(IntRect(25, 25, 50, 50)); |
| 150 frameBuffers[2].setAlphaBlendSource(ImageFrame::BlendAtopBgcolor); |
| 151 |
| 152 // A full frame with 'blending method == BlendAtopBgcolor' doesn't depend on
any prior frames. |
| 153 for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= I
mageFrame::DisposeOverwritePrevious; ++disposeMethod) { |
| 154 frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod
>(disposeMethod)); |
| 155 decoder->resetRequiredPreviousFrames(); |
| 156 EXPECT_EQ(notFound, frameBuffers[2].requiredPreviousFrameIndex()); |
| 157 } |
| 158 |
| 159 // A non-full frame with 'blending method == BlendAtopBgcolor' does depend o
n a prior frame. |
| 160 frameBuffers[2].setOriginalFrameRect(IntRect(50, 50, 50, 50)); |
| 161 for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= I
mageFrame::DisposeOverwritePrevious; ++disposeMethod) { |
| 162 frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod
>(disposeMethod)); |
| 163 decoder->resetRequiredPreviousFrames(); |
| 164 EXPECT_NE(notFound, frameBuffers[2].requiredPreviousFrameIndex()); |
| 165 } |
| 166 } |
| 167 |
| 168 TEST(ImageDecoderTest, requiredPreviousFrameIndexKnownOpaque) |
| 169 { |
| 170 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); |
| 171 decoder->initFrames(3); |
| 172 Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache(); |
| 173 |
| 174 frameBuffers[1].setOriginalFrameRect(IntRect(25, 25, 50, 50)); |
| 175 |
| 176 // A full frame that is known to be opaque doesn't depend on any prior frame
s. |
| 177 for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= I
mageFrame::DisposeOverwritePrevious; ++disposeMethod) { |
| 178 frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod
>(disposeMethod)); |
| 179 decoder->resetRequiredPreviousFrames(true); |
| 180 EXPECT_EQ(notFound, frameBuffers[2].requiredPreviousFrameIndex()); |
| 181 } |
| 182 |
| 183 // A non-full frame that is known to be opaque does depend on a prior frame. |
| 184 frameBuffers[2].setOriginalFrameRect(IntRect(50, 50, 50, 50)); |
| 185 for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= I
mageFrame::DisposeOverwritePrevious; ++disposeMethod) { |
| 186 frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod
>(disposeMethod)); |
| 187 decoder->resetRequiredPreviousFrames(true); |
| 188 EXPECT_NE(notFound, frameBuffers[2].requiredPreviousFrameIndex()); |
| 189 } |
141 } | 190 } |
142 | 191 |
143 TEST(ImageDecoderTest, clearCacheExceptFrameDoNothing) | 192 TEST(ImageDecoderTest, clearCacheExceptFrameDoNothing) |
144 { | 193 { |
145 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); | 194 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); |
146 decoder->clearCacheExceptFrame(0); | 195 decoder->clearCacheExceptFrame(0); |
147 | 196 |
148 // This should not crash. | 197 // This should not crash. |
149 decoder->initFrames(20); | 198 decoder->initFrames(20); |
150 decoder->clearCacheExceptFrame(notFound); | 199 decoder->clearCacheExceptFrame(notFound); |
151 } | 200 } |
152 | 201 |
153 TEST(ImageDecoderTest, clearCacheExceptFrameAll) | 202 TEST(ImageDecoderTest, clearCacheExceptFrameAll) |
154 { | 203 { |
155 const size_t numFrames = 10; | 204 const size_t numFrames = 10; |
156 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); | 205 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); |
157 decoder->initFrames(numFrames); | 206 decoder->initFrames(numFrames); |
158 Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache()
; | 207 Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache(); |
159 for (size_t i = 0; i < numFrames; ++i) | 208 for (size_t i = 0; i < numFrames; ++i) |
160 decoderFrameBufferCache[i].setStatus(i % 2 ? ImageFrame::FramePartial :
ImageFrame::FrameComplete); | 209 frameBuffers[i].setStatus(i % 2 ? ImageFrame::FramePartial : ImageFrame:
:FrameComplete); |
161 | 210 |
162 decoder->clearCacheExceptFrame(notFound); | 211 decoder->clearCacheExceptFrame(notFound); |
163 | 212 |
164 for (size_t i = 0; i < numFrames; ++i) { | 213 for (size_t i = 0; i < numFrames; ++i) { |
165 SCOPED_TRACE(testing::Message() << i); | 214 SCOPED_TRACE(testing::Message() << i); |
166 EXPECT_EQ(ImageFrame::FrameEmpty, decoderFrameBufferCache[i].status()); | 215 EXPECT_EQ(ImageFrame::FrameEmpty, frameBuffers[i].status()); |
167 } | 216 } |
168 } | 217 } |
169 | 218 |
170 TEST(ImageDecoderTest, clearCacheExceptFramePreverveClearExceptFrame) | 219 TEST(ImageDecoderTest, clearCacheExceptFramePreverveClearExceptFrame) |
171 { | 220 { |
172 const size_t numFrames = 10; | 221 const size_t numFrames = 10; |
173 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); | 222 OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder())); |
174 decoder->initFrames(numFrames); | 223 decoder->initFrames(numFrames); |
175 Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache()
; | 224 Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache(); |
176 for (size_t i = 0; i < numFrames; ++i) | 225 for (size_t i = 0; i < numFrames; ++i) |
177 decoderFrameBufferCache[i].setStatus(ImageFrame::FrameComplete); | 226 frameBuffers[i].setStatus(ImageFrame::FrameComplete); |
178 | 227 |
179 decoder->resetRequiredPreviousFrames(); | 228 decoder->resetRequiredPreviousFrames(); |
180 decoder->clearCacheExceptFrame(5); | 229 decoder->clearCacheExceptFrame(5); |
181 for (size_t i = 0; i < numFrames; ++i) { | 230 for (size_t i = 0; i < numFrames; ++i) { |
182 SCOPED_TRACE(testing::Message() << i); | 231 SCOPED_TRACE(testing::Message() << i); |
183 if (i == 5) | 232 if (i == 5) |
184 EXPECT_EQ(ImageFrame::FrameComplete, decoderFrameBufferCache[i].stat
us()); | 233 EXPECT_EQ(ImageFrame::FrameComplete, frameBuffers[i].status()); |
185 else | 234 else |
186 EXPECT_EQ(ImageFrame::FrameEmpty, decoderFrameBufferCache[i].status(
)); | 235 EXPECT_EQ(ImageFrame::FrameEmpty, frameBuffers[i].status()); |
187 } | 236 } |
188 } | 237 } |
OLD | NEW |