| 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 |