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