OLD | NEW |
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" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 // segments into the contiguous buffer. If the ImageDecoder was pointing to | 141 // segments into the contiguous buffer. If the ImageDecoder was pointing to |
142 // data in a segment, its pointer would no longer be valid. | 142 // data in a segment, its pointer would no longer be valid. |
143 segmentedData->data(); | 143 segmentedData->data(); |
144 | 144 |
145 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 145 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
146 ASSERT_FALSE(decoder->failed()); | 146 ASSERT_FALSE(decoder->failed()); |
147 EXPECT_EQ(frame->getStatus(), ImageFrame::FrameComplete); | 147 EXPECT_EQ(frame->getStatus(), ImageFrame::FrameComplete); |
148 EXPECT_EQ(hashBitmap(frame->bitmap()), hash); | 148 EXPECT_EQ(hashBitmap(frame->bitmap()), hash); |
149 } | 149 } |
150 | 150 |
| 151 void testRandomFrameDecode(DecoderCreator createDecoder, |
| 152 const char* file, |
| 153 size_t skippingStep) { |
| 154 SCOPED_TRACE(file); |
| 155 |
| 156 RefPtr<SharedBuffer> fullData = readFile(file); |
| 157 ASSERT_TRUE(fullData.get()); |
| 158 Vector<unsigned> baselineHashes; |
| 159 createDecodingBaseline(createDecoder, fullData.get(), &baselineHashes); |
| 160 size_t frameCount = baselineHashes.size(); |
| 161 |
| 162 // Random decoding should get the same results as sequential decoding. |
| 163 std::unique_ptr<ImageDecoder> decoder = createDecoder(); |
| 164 decoder->setData(fullData.get(), true); |
| 165 for (size_t i = 0; i < skippingStep; ++i) { |
| 166 for (size_t j = i; j < frameCount; j += skippingStep) { |
| 167 SCOPED_TRACE(::testing::Message() << "Random i:" << i << " j:" << j); |
| 168 ImageFrame* frame = decoder->frameBufferAtIndex(j); |
| 169 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap())); |
| 170 } |
| 171 } |
| 172 |
| 173 // Decoding in reverse order. |
| 174 decoder = createDecoder(); |
| 175 decoder->setData(fullData.get(), true); |
| 176 for (size_t i = frameCount; i; --i) { |
| 177 SCOPED_TRACE(::testing::Message() << "Reverse i:" << i); |
| 178 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); |
| 179 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->bitmap())); |
| 180 } |
| 181 } |
| 182 |
| 183 void testRandomDecodeAfterClearFrameBufferCache(DecoderCreator createDecoder, |
| 184 const char* file, |
| 185 size_t skippingStep) { |
| 186 SCOPED_TRACE(file); |
| 187 |
| 188 RefPtr<SharedBuffer> data = readFile(file); |
| 189 ASSERT_TRUE(data.get()); |
| 190 Vector<unsigned> baselineHashes; |
| 191 createDecodingBaseline(createDecoder, data.get(), &baselineHashes); |
| 192 size_t frameCount = baselineHashes.size(); |
| 193 |
| 194 std::unique_ptr<ImageDecoder> decoder = createDecoder(); |
| 195 decoder->setData(data.get(), true); |
| 196 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; |
| 197 ++clearExceptFrame) { |
| 198 decoder->clearCacheExceptFrame(clearExceptFrame); |
| 199 for (size_t i = 0; i < skippingStep; ++i) { |
| 200 for (size_t j = 0; j < frameCount; j += skippingStep) { |
| 201 SCOPED_TRACE(::testing::Message() << "Random i:" << i << " j:" << j); |
| 202 ImageFrame* frame = decoder->frameBufferAtIndex(j); |
| 203 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap())); |
| 204 } |
| 205 } |
| 206 } |
| 207 } |
| 208 |
| 209 void testDecodeAfterReallocatingData(DecoderCreator createDecoder, |
| 210 const char* file) { |
| 211 std::unique_ptr<ImageDecoder> decoder = createDecoder(); |
| 212 RefPtr<SharedBuffer> data = readFile(file); |
| 213 ASSERT_TRUE(data.get()); |
| 214 |
| 215 // Parse from 'data'. |
| 216 decoder->setData(data.get(), true); |
| 217 size_t frameCount = decoder->frameCount(); |
| 218 |
| 219 // ... and then decode frames from 'reallocatedData'. |
| 220 RefPtr<SharedBuffer> reallocatedData = data.get()->copy(); |
| 221 ASSERT_TRUE(reallocatedData.get()); |
| 222 data.clear(); |
| 223 decoder->setData(reallocatedData.get(), true); |
| 224 |
| 225 for (size_t i = 0; i < frameCount; ++i) { |
| 226 const ImageFrame* const frame = decoder->frameBufferAtIndex(i); |
| 227 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus()); |
| 228 } |
| 229 } |
| 230 |
| 231 void testByteByByteSizeAvailable(DecoderCreator createDecoder, |
| 232 const char* file, |
| 233 size_t frameOffset, |
| 234 bool hasColorSpace, |
| 235 int expectedRepetitionCount) { |
| 236 std::unique_ptr<ImageDecoder> decoder = createDecoder(); |
| 237 RefPtr<SharedBuffer> data = readFile(file); |
| 238 ASSERT_TRUE(data.get()); |
| 239 EXPECT_LT(frameOffset, data->size()); |
| 240 |
| 241 // Send data to the decoder byte-by-byte and use the provided frame offset in |
| 242 // the data to check that isSizeAvailable() changes state only when that |
| 243 // offset is reached. Also check other decoder state. |
| 244 for (size_t length = 1; length <= frameOffset; ++length) { |
| 245 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), length); |
| 246 decoder->setData(tempData.get(), false); |
| 247 |
| 248 if (length < frameOffset) { |
| 249 EXPECT_FALSE(decoder->isSizeAvailable()); |
| 250 EXPECT_TRUE(decoder->size().isEmpty()); |
| 251 EXPECT_FALSE(decoder->hasEmbeddedColorSpace()); |
| 252 EXPECT_EQ(0u, decoder->frameCount()); |
| 253 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
| 254 EXPECT_FALSE(decoder->frameBufferAtIndex(0)); |
| 255 } else { |
| 256 EXPECT_TRUE(decoder->isSizeAvailable()); |
| 257 EXPECT_FALSE(decoder->size().isEmpty()); |
| 258 EXPECT_EQ(decoder->hasEmbeddedColorSpace(), hasColorSpace); |
| 259 EXPECT_EQ(1u, decoder->frameCount()); |
| 260 EXPECT_EQ(expectedRepetitionCount, decoder->repetitionCount()); |
| 261 } |
| 262 |
| 263 ASSERT_FALSE(decoder->failed()); |
| 264 } |
| 265 } |
| 266 |
| 267 void testProgressiveDecoding(DecoderCreator createDecoder, |
| 268 const char* file, |
| 269 size_t increment) { |
| 270 RefPtr<SharedBuffer> fullData = readFile(file); |
| 271 ASSERT_TRUE(fullData.get()); |
| 272 const size_t fullLength = fullData->size(); |
| 273 |
| 274 std::unique_ptr<ImageDecoder> decoder; |
| 275 |
| 276 Vector<unsigned> truncatedHashes; |
| 277 Vector<unsigned> progressiveHashes; |
| 278 |
| 279 // Compute hashes when the file is truncated. |
| 280 for (size_t i = 1; i <= fullLength; i += increment) { |
| 281 decoder = createDecoder(); |
| 282 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); |
| 283 decoder->setData(data.get(), i == fullLength); |
| 284 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 285 if (!frame) { |
| 286 truncatedHashes.append(0); |
| 287 continue; |
| 288 } |
| 289 truncatedHashes.append(hashBitmap(frame->bitmap())); |
| 290 } |
| 291 |
| 292 // Compute hashes when the file is progressively decoded. |
| 293 decoder = createDecoder(); |
| 294 for (size_t i = 1; i <= fullLength; i += increment) { |
| 295 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); |
| 296 decoder->setData(data.get(), i == fullLength); |
| 297 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 298 if (!frame) { |
| 299 progressiveHashes.append(0); |
| 300 continue; |
| 301 } |
| 302 progressiveHashes.append(hashBitmap(frame->bitmap())); |
| 303 } |
| 304 |
| 305 for (size_t i = 0; i < truncatedHashes.size(); ++i) |
| 306 ASSERT_EQ(truncatedHashes[i], progressiveHashes[i]); |
| 307 } |
| 308 |
151 } // namespace blink | 309 } // namespace blink |
OLD | NEW |