OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 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 | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 size = decoder->decodedYUVSize(2, sizeType); | 83 size = decoder->decodedYUVSize(2, sizeType); |
84 componentSizes[2].set(size.width(), size.height()); | 84 componentSizes[2].set(size.width(), size.height()); |
85 return true; | 85 return true; |
86 } | 86 } |
87 | 87 |
88 ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<Sha
redBuffer> data, bool allDataReceived, bool isMultiFrame) | 88 ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<Sha
redBuffer> data, bool allDataReceived, bool isMultiFrame) |
89 : m_fullSize(fullSize) | 89 : m_fullSize(fullSize) |
90 , m_isMultiFrame(isMultiFrame) | 90 , m_isMultiFrame(isMultiFrame) |
91 , m_decodeFailedAndEmpty(false) | 91 , m_decodeFailedAndEmpty(false) |
92 , m_decodeCount(0) | 92 , m_decodeCount(0) |
| 93 , m_frameCount(0) |
93 { | 94 { |
94 setData(data.get(), allDataReceived); | 95 setData(data.get(), allDataReceived); |
95 } | 96 } |
96 | 97 |
97 ImageFrameGenerator::~ImageFrameGenerator() | 98 ImageFrameGenerator::~ImageFrameGenerator() |
98 { | 99 { |
99 ImageDecodingStore::instance()->removeCacheIndexedByGenerator(this); | 100 ImageDecodingStore::instance()->removeCacheIndexedByGenerator(this); |
100 } | 101 } |
101 | 102 |
102 void ImageFrameGenerator::setData(PassRefPtr<SharedBuffer> data, bool allDataRec
eived) | 103 void ImageFrameGenerator::setData(PassRefPtr<SharedBuffer> data, bool allDataRec
eived) |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 | 198 |
198 ImageDecoder* decoder = 0; | 199 ImageDecoder* decoder = 0; |
199 const bool resumeDecoding = ImageDecodingStore::instance()->lockDecoder(this
, m_fullSize, &decoder); | 200 const bool resumeDecoding = ImageDecodingStore::instance()->lockDecoder(this
, m_fullSize, &decoder); |
200 ASSERT(!resumeDecoding || decoder); | 201 ASSERT(!resumeDecoding || decoder); |
201 | 202 |
202 SkBitmap fullSizeImage; | 203 SkBitmap fullSizeImage; |
203 bool complete = decode(index, &decoder, &fullSizeImage); | 204 bool complete = decode(index, &decoder, &fullSizeImage); |
204 | 205 |
205 if (!decoder) | 206 if (!decoder) |
206 return SkBitmap(); | 207 return SkBitmap(); |
| 208 if (index >= m_frameComplete.size()) |
| 209 m_frameComplete.resize(index + 1); |
| 210 m_frameComplete[index] = complete; |
207 | 211 |
208 // If we are not resuming decoding that means the decoder is freshly | 212 // If we are not resuming decoding that means the decoder is freshly |
209 // created and we have ownership. If we are resuming decoding then | 213 // created and we have ownership. If we are resuming decoding then |
210 // the decoder is owned by ImageDecodingStore. | 214 // the decoder is owned by ImageDecodingStore. |
211 OwnPtr<ImageDecoder> decoderContainer; | 215 OwnPtr<ImageDecoder> decoderContainer; |
212 if (!resumeDecoding) | 216 if (!resumeDecoding) |
213 decoderContainer = adoptPtr(decoder); | 217 decoderContainer = adoptPtr(decoder); |
214 | 218 |
215 if (fullSizeImage.isNull()) { | 219 if (fullSizeImage.isNull()) { |
216 // If decode has failed and resulted an empty image we can save work | 220 // If decode has failed and resulted an empty image we can save work |
217 // in the future by returning early. | 221 // in the future by returning early. |
218 m_decodeFailedAndEmpty = !m_isMultiFrame && decoder->failed(); | 222 m_decodeFailedAndEmpty = !m_isMultiFrame && decoder->failed(); |
219 | 223 |
220 if (resumeDecoding) | 224 if (resumeDecoding) |
221 ImageDecodingStore::instance()->unlockDecoder(this, decoder); | 225 ImageDecodingStore::instance()->unlockDecoder(this, decoder); |
222 return SkBitmap(); | 226 return SkBitmap(); |
223 } | 227 } |
224 | 228 |
225 // If the image generated is complete then there is no need to keep | 229 // If the image generated is complete then there is no need to keep |
226 // the decoder. The exception is multi-frame decoder which can generate | 230 // the decoder. For multi-frame images, if all frames in the image are |
227 // multiple complete frames. | 231 // decoded, we remove the decoder. |
228 const bool removeDecoder = complete && !m_isMultiFrame; | 232 bool removeDecoder; |
| 233 |
| 234 if (m_isMultiFrame) { |
| 235 size_t decodedFrameCount = 0; |
| 236 for (Vector<bool>::iterator it = m_frameComplete.begin(); it != m_frameC
omplete.end(); ++it) { |
| 237 if (*it) |
| 238 decodedFrameCount++; |
| 239 } |
| 240 removeDecoder = m_frameCount && (decodedFrameCount == m_frameCount); |
| 241 } else { |
| 242 removeDecoder = complete; |
| 243 } |
229 | 244 |
230 if (resumeDecoding) { | 245 if (resumeDecoding) { |
231 if (removeDecoder) | 246 if (removeDecoder) { |
232 ImageDecodingStore::instance()->removeDecoder(this, decoder); | 247 ImageDecodingStore::instance()->removeDecoder(this, decoder); |
| 248 m_frameComplete.clear(); |
| 249 } |
233 else | 250 else |
234 ImageDecodingStore::instance()->unlockDecoder(this, decoder); | 251 ImageDecodingStore::instance()->unlockDecoder(this, decoder); |
235 } else if (!removeDecoder) { | 252 } else if (!removeDecoder) { |
236 ImageDecodingStore::instance()->insertDecoder(this, decoderContainer.rel
ease()); | 253 ImageDecodingStore::instance()->insertDecoder(this, decoderContainer.rel
ease()); |
237 } | 254 } |
238 return fullSizeImage; | 255 return fullSizeImage; |
239 } | 256 } |
240 | 257 |
241 void ImageFrameGenerator::setHasAlpha(size_t index, bool hasAlpha) | 258 void ImageFrameGenerator::setHasAlpha(size_t index, bool hasAlpha) |
242 { | 259 { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 | 292 |
276 if (!m_isMultiFrame && newDecoder && allDataReceived) { | 293 if (!m_isMultiFrame && newDecoder && allDataReceived) { |
277 // If we're using an external memory allocator that means we're decoding | 294 // If we're using an external memory allocator that means we're decoding |
278 // directly into the output memory and we can save one memcpy. | 295 // directly into the output memory and we can save one memcpy. |
279 ASSERT(m_externalAllocator.get()); | 296 ASSERT(m_externalAllocator.get()); |
280 (*decoder)->setMemoryAllocator(m_externalAllocator.get()); | 297 (*decoder)->setMemoryAllocator(m_externalAllocator.get()); |
281 } | 298 } |
282 (*decoder)->setData(data, allDataReceived); | 299 (*decoder)->setData(data, allDataReceived); |
283 | 300 |
284 ImageFrame* frame = (*decoder)->frameBufferAtIndex(index); | 301 ImageFrame* frame = (*decoder)->frameBufferAtIndex(index); |
| 302 // For multi-frame image decoders, we need to know how many frames are |
| 303 // in that image in order to release the decoder when all frames are |
| 304 // decoded. frameCount() is reliable only if all data is received and set in |
| 305 // decoder, particularly with GIF. |
| 306 if (allDataReceived) |
| 307 m_frameCount = (*decoder)->frameCount(); |
| 308 |
285 (*decoder)->setData(0, false); // Unref SharedBuffer from ImageDecoder. | 309 (*decoder)->setData(0, false); // Unref SharedBuffer from ImageDecoder. |
286 (*decoder)->clearCacheExceptFrame(index); | 310 (*decoder)->clearCacheExceptFrame(index); |
287 (*decoder)->setMemoryAllocator(0); | 311 (*decoder)->setMemoryAllocator(0); |
288 | 312 |
289 if (!frame || frame->status() == ImageFrame::FrameEmpty) | 313 if (!frame || frame->status() == ImageFrame::FrameEmpty) |
290 return false; | 314 return false; |
291 | 315 |
292 // A cache object is considered complete if we can decode a complete frame. | 316 // A cache object is considered complete if we can decode a complete frame. |
293 // Or we have received all data. The image might not be fully decoded in | 317 // Or we have received all data. The image might not be fully decoded in |
294 // the latter case. | 318 // the latter case. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 | 355 |
332 // Setting a dummy ImagePlanes object signals to the decoder that we want to
do YUV decoding. | 356 // Setting a dummy ImagePlanes object signals to the decoder that we want to
do YUV decoding. |
333 decoder->setData(data, allDataReceived); | 357 decoder->setData(data, allDataReceived); |
334 OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes); | 358 OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes); |
335 decoder->setImagePlanes(dummyImagePlanes.release()); | 359 decoder->setImagePlanes(dummyImagePlanes.release()); |
336 | 360 |
337 return updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder::
SizeForMemoryAllocation); | 361 return updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder::
SizeForMemoryAllocation); |
338 } | 362 } |
339 | 363 |
340 } // namespace blink | 364 } // namespace blink |
OLD | NEW |