| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 componentSizes[1].set(size.width(), size.height()); | 97 componentSizes[1].set(size.width(), size.height()); |
| 98 size = decoder->decodedYUVSize(2, sizeType); | 98 size = decoder->decodedYUVSize(2, sizeType); |
| 99 componentSizes[2].set(size.width(), size.height()); | 99 componentSizes[2].set(size.width(), size.height()); |
| 100 return true; | 100 return true; |
| 101 } | 101 } |
| 102 | 102 |
| 103 ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<Sha
redBuffer> data, bool allDataReceived, bool isMultiFrame) | 103 ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<Sha
redBuffer> data, bool allDataReceived, bool isMultiFrame) |
| 104 : m_fullSize(fullSize) | 104 : m_fullSize(fullSize) |
| 105 , m_data(adoptRef(new ThreadSafeDataTransport())) | 105 , m_data(adoptRef(new ThreadSafeDataTransport())) |
| 106 , m_isMultiFrame(isMultiFrame) | 106 , m_isMultiFrame(isMultiFrame) |
| 107 , m_decodeFailedAndEmpty(false) | 107 , m_decodeFailed(false) |
| 108 , m_decodeCount(0) | |
| 109 , m_frameCount(0) | 108 , m_frameCount(0) |
| 110 , m_encodedData(nullptr) | 109 , m_encodedData(nullptr) |
| 111 { | 110 { |
| 112 setData(data.get(), allDataReceived); | 111 setData(data.get(), allDataReceived); |
| 113 } | 112 } |
| 114 | 113 |
| 115 ImageFrameGenerator::~ImageFrameGenerator() | 114 ImageFrameGenerator::~ImageFrameGenerator() |
| 116 { | 115 { |
| 117 if (m_encodedData) | 116 if (m_encodedData) |
| 118 m_encodedData->unref(); | 117 m_encodedData->unref(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 // While m_encodedData is referenced, prevent disposing m_data and its c
ontent. | 167 // While m_encodedData is referenced, prevent disposing m_data and its c
ontent. |
| 169 // it is dereferenced in sharedSkDataReleaseCallback, called when m_enco
dedData gets dereferenced. | 168 // it is dereferenced in sharedSkDataReleaseCallback, called when m_enco
dedData gets dereferenced. |
| 170 m_data->ref(); | 169 m_data->ref(); |
| 171 } | 170 } |
| 172 // Increase the reference, caller must decrease it. One reference is always
kept by ImageFrameGenerator and released | 171 // Increase the reference, caller must decrease it. One reference is always
kept by ImageFrameGenerator and released |
| 173 // in destructor. | 172 // in destructor. |
| 174 m_encodedData->ref(); | 173 m_encodedData->ref(); |
| 175 return m_encodedData; | 174 return m_encodedData; |
| 176 } | 175 } |
| 177 | 176 |
| 178 bool ImageFrameGenerator::decodeAndScale(const SkImageInfo& info, size_t index,
void* pixels, size_t rowBytes) | 177 bool ImageFrameGenerator::decodeAndScale(size_t index, const SkImageInfo& info,
void* pixels, size_t rowBytes) |
| 179 { | 178 { |
| 180 // This method is called to populate a discardable memory owned by Skia. | 179 // Prevent concurrent decode or scale operations on the same image data. |
| 180 MutexLocker lock(m_decodeMutex); |
| 181 | 181 |
| 182 // Prevents concurrent decode or scale operations on the same image data. | 182 if (m_decodeFailed) |
| 183 MutexLocker lock(m_decodeMutex); | 183 return false; |
| 184 |
| 185 TRACE_EVENT1("blink", "ImageFrameGenerator::decodeAndScale", "frame index",
static_cast<int>(index)); |
| 186 |
| 187 m_externalAllocator = adoptPtr(new ExternalMemoryAllocator(info, pixels, row
Bytes)); |
| 184 | 188 |
| 185 // This implementation does not support scaling so check the requested size. | 189 // This implementation does not support scaling so check the requested size. |
| 186 SkISize scaledSize = SkISize::Make(info.width(), info.height()); | 190 SkISize scaledSize = SkISize::Make(info.width(), info.height()); |
| 187 ASSERT(m_fullSize == scaledSize); | 191 ASSERT(m_fullSize == scaledSize); |
| 188 | 192 |
| 189 if (m_decodeFailedAndEmpty) | 193 SkBitmap bitmap = tryToResumeDecode(index, scaledSize); |
| 190 return false; | |
| 191 | |
| 192 TRACE_EVENT2("blink", "ImageFrameGenerator::decodeAndScale", "generator", th
is, "decodeCount", m_decodeCount); | |
| 193 | |
| 194 m_externalAllocator = adoptPtr(new ExternalMemoryAllocator(info, pixels, row
Bytes)); | |
| 195 | |
| 196 SkBitmap bitmap = tryToResumeDecode(scaledSize, index); | |
| 197 if (bitmap.isNull()) | 194 if (bitmap.isNull()) |
| 198 return false; | 195 return false; |
| 199 | 196 |
| 200 // Don't keep the allocator because it contains a pointer to memory | 197 // Don't keep the allocator because it contains a pointer to memory |
| 201 // that we do not own. | 198 // that we do not own. |
| 202 m_externalAllocator.clear(); | 199 m_externalAllocator.clear(); |
| 203 | 200 |
| 201 // Check to see if the decoder has written directly to the pixel memory |
| 202 // provided. If not, make a copy. |
| 204 ASSERT(bitmap.width() == scaledSize.width()); | 203 ASSERT(bitmap.width() == scaledSize.width()); |
| 205 ASSERT(bitmap.height() == scaledSize.height()); | 204 ASSERT(bitmap.height() == scaledSize.height()); |
| 206 | |
| 207 bool result = true; | |
| 208 SkAutoLockPixels bitmapLock(bitmap); | 205 SkAutoLockPixels bitmapLock(bitmap); |
| 209 // Check to see if decoder has written directly to the memory provided | |
| 210 // by Skia. If not make a copy. | |
| 211 if (bitmap.getPixels() != pixels) | 206 if (bitmap.getPixels() != pixels) |
| 212 result = bitmap.copyPixelsTo(pixels, rowBytes * info.height(), rowBytes)
; | 207 return bitmap.copyPixelsTo(pixels, rowBytes * info.height(), rowBytes); |
| 213 return result; | 208 return true; |
| 214 } | 209 } |
| 215 | 210 |
| 216 bool ImageFrameGenerator::decodeToYUV(SkISize componentSizes[3], void* planes[3]
, size_t rowBytes[3]) | 211 bool ImageFrameGenerator::decodeToYUV(size_t index, SkISize componentSizes[3], v
oid* planes[3], size_t rowBytes[3]) |
| 217 { | 212 { |
| 218 // This method is called to populate a discardable memory owned by Skia. | 213 // Prevent concurrent decode or scale operations on the same image data. |
| 219 | |
| 220 // Prevents concurrent decode or scale operations on the same image data. | |
| 221 MutexLocker lock(m_decodeMutex); | 214 MutexLocker lock(m_decodeMutex); |
| 222 | 215 |
| 223 if (m_decodeFailedAndEmpty) | 216 if (m_decodeFailed) |
| 224 return false; | 217 return false; |
| 225 | 218 |
| 226 TRACE_EVENT2("blink", "ImageFrameGenerator::decodeToYUV", "generator", this,
"decodeCount", static_cast<int>(m_decodeCount)); | 219 TRACE_EVENT1("blink", "ImageFrameGenerator::decodeToYUV", "frame index", sta
tic_cast<int>(index)); |
| 227 | 220 |
| 228 if (!planes || !planes[0] || !planes[1] || !planes[2] | 221 if (!planes || !planes[0] || !planes[1] || !planes[2] |
| 229 || !rowBytes || !rowBytes[0] || !rowBytes[1] || !rowBytes[2]) { | 222 || !rowBytes || !rowBytes[0] || !rowBytes[1] || !rowBytes[2]) { |
| 230 return false; | 223 return false; |
| 231 } | 224 } |
| 232 | 225 |
| 233 SharedBuffer* data = 0; | 226 SharedBuffer* data = 0; |
| 234 bool allDataReceived = false; | 227 bool allDataReceived = false; |
| 235 m_data->data(&data, &allDataReceived); | 228 m_data->data(&data, &allDataReceived); |
| 236 | 229 |
| 237 // FIXME: YUV decoding does not currently support progressive decoding. | 230 // FIXME: YUV decoding does not currently support progressive decoding. |
| 238 ASSERT(allDataReceived); | 231 ASSERT(allDataReceived); |
| 239 | 232 |
| 240 OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data, ImageDecoder::Alp
haPremultiplied, ImageDecoder::GammaAndColorProfileApplied); | 233 OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data, ImageDecoder::Alp
haPremultiplied, ImageDecoder::GammaAndColorProfileApplied); |
| 241 if (!decoder) | 234 if (!decoder) |
| 242 return false; | 235 return false; |
| 243 | 236 |
| 244 decoder->setData(data, allDataReceived); | 237 decoder->setData(data, allDataReceived); |
| 245 | 238 |
| 246 OwnPtr<ImagePlanes> imagePlanes = adoptPtr(new ImagePlanes(planes, rowBytes)
); | 239 OwnPtr<ImagePlanes> imagePlanes = adoptPtr(new ImagePlanes(planes, rowBytes)
); |
| 247 decoder->setImagePlanes(imagePlanes.release()); | 240 decoder->setImagePlanes(imagePlanes.release()); |
| 248 | 241 |
| 249 bool sizeUpdated = updateYUVComponentSizes(decoder.get(), componentSizes, Im
ageDecoder::ActualSize); | 242 bool sizeUpdated = updateYUVComponentSizes(decoder.get(), componentSizes, Im
ageDecoder::ActualSize); |
| 250 RELEASE_ASSERT(sizeUpdated); | 243 RELEASE_ASSERT(sizeUpdated); |
| 251 | 244 |
| 252 bool yuvDecoded = decoder->decodeToYUV(); | 245 if (decoder->decodeToYUV()) { |
| 253 if (yuvDecoded) | |
| 254 setHasAlpha(0, false); // YUV is always opaque | 246 setHasAlpha(0, false); // YUV is always opaque |
| 255 return yuvDecoded; | 247 return true; |
| 248 } |
| 249 |
| 250 ASSERT(decoder->failed()); |
| 251 m_decodeFailed = true; |
| 252 return false; |
| 256 } | 253 } |
| 257 | 254 |
| 258 SkBitmap ImageFrameGenerator::tryToResumeDecode(const SkISize& scaledSize, size_
t index) | 255 SkBitmap ImageFrameGenerator::tryToResumeDecode(size_t index, const SkISize& sca
ledSize) |
| 259 { | 256 { |
| 260 TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecodeAndScale", "ind
ex", static_cast<int>(index)); | 257 TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecode", "frame index
", static_cast<int>(index)); |
| 261 | 258 |
| 262 ImageDecoder* decoder = 0; | 259 ImageDecoder* decoder = 0; |
| 263 const bool resumeDecoding = ImageDecodingStore::instance().lockDecoder(this,
m_fullSize, &decoder); | 260 const bool resumeDecoding = ImageDecodingStore::instance().lockDecoder(this,
m_fullSize, &decoder); |
| 264 ASSERT(!resumeDecoding || decoder); | 261 ASSERT(!resumeDecoding || decoder); |
| 265 | 262 |
| 266 SkBitmap fullSizeImage; | 263 SkBitmap fullSizeImage; |
| 267 bool complete = decode(index, &decoder, &fullSizeImage); | 264 bool complete = decode(index, &decoder, &fullSizeImage); |
| 268 | 265 |
| 269 if (!decoder) | 266 if (!decoder) |
| 270 return SkBitmap(); | 267 return SkBitmap(); |
| 271 if (index >= m_frameComplete.size()) | 268 if (index >= m_frameComplete.size()) |
| 272 m_frameComplete.resize(index + 1); | 269 m_frameComplete.resize(index + 1); |
| 273 m_frameComplete[index] = complete; | 270 m_frameComplete[index] = complete; |
| 274 | 271 |
| 275 // If we are not resuming decoding that means the decoder is freshly | 272 // If we are not resuming decoding that means the decoder is freshly |
| 276 // created and we have ownership. If we are resuming decoding then | 273 // created and we have ownership. If we are resuming decoding then |
| 277 // the decoder is owned by ImageDecodingStore. | 274 // the decoder is owned by ImageDecodingStore. |
| 278 OwnPtr<ImageDecoder> decoderContainer; | 275 OwnPtr<ImageDecoder> decoderContainer; |
| 279 if (!resumeDecoding) | 276 if (!resumeDecoding) |
| 280 decoderContainer = adoptPtr(decoder); | 277 decoderContainer = adoptPtr(decoder); |
| 281 | 278 |
| 282 if (fullSizeImage.isNull()) { | 279 if (fullSizeImage.isNull()) { |
| 283 // If decode has failed and resulted an empty image we can save work | 280 // If decoding has failed, we can save work in the future by |
| 284 // in the future by returning early. | 281 // ignoring further requests to decode the image. |
| 285 m_decodeFailedAndEmpty = !m_isMultiFrame && decoder->failed(); | 282 m_decodeFailed = decoder->failed(); |
| 286 | |
| 287 if (resumeDecoding) | 283 if (resumeDecoding) |
| 288 ImageDecodingStore::instance().unlockDecoder(this, decoder); | 284 ImageDecodingStore::instance().unlockDecoder(this, decoder); |
| 289 return SkBitmap(); | 285 return SkBitmap(); |
| 290 } | 286 } |
| 291 | 287 |
| 292 // If the image generated is complete then there is no need to keep | 288 // If the image generated is complete then there is no need to keep |
| 293 // the decoder. For multi-frame images, if all frames in the image are | 289 // the decoder. For multi-frame images, if all frames in the image are |
| 294 // decoded, we remove the decoder. | 290 // decoded, we remove the decoder. |
| 295 bool removeDecoder; | 291 bool removeDecoder; |
| 296 | 292 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 327 for (size_t i = oldSize; i < m_hasAlpha.size(); ++i) | 323 for (size_t i = oldSize; i < m_hasAlpha.size(); ++i) |
| 328 m_hasAlpha[i] = true; | 324 m_hasAlpha[i] = true; |
| 329 } | 325 } |
| 330 m_hasAlpha[index] = hasAlpha; | 326 m_hasAlpha[index] = hasAlpha; |
| 331 } | 327 } |
| 332 | 328 |
| 333 bool ImageFrameGenerator::decode(size_t index, ImageDecoder** decoder, SkBitmap*
bitmap) | 329 bool ImageFrameGenerator::decode(size_t index, ImageDecoder** decoder, SkBitmap*
bitmap) |
| 334 { | 330 { |
| 335 TRACE_EVENT2("blink", "ImageFrameGenerator::decode", "width", m_fullSize.wid
th(), "height", m_fullSize.height()); | 331 TRACE_EVENT2("blink", "ImageFrameGenerator::decode", "width", m_fullSize.wid
th(), "height", m_fullSize.height()); |
| 336 | 332 |
| 337 ASSERT(decoder); | |
| 338 SharedBuffer* data = 0; | 333 SharedBuffer* data = 0; |
| 339 bool allDataReceived = false; | 334 bool allDataReceived = false; |
| 340 bool newDecoder = false; | |
| 341 m_data->data(&data, &allDataReceived); | 335 m_data->data(&data, &allDataReceived); |
| 342 | 336 |
| 343 // Try to create an ImageDecoder if we are not given one. | 337 // Try to create an ImageDecoder if we are not given one. |
| 338 ASSERT(decoder); |
| 339 bool newDecoder = false; |
| 344 if (!*decoder) { | 340 if (!*decoder) { |
| 345 newDecoder = true; | 341 newDecoder = true; |
| 346 if (m_imageDecoderFactory) | 342 if (m_imageDecoderFactory) |
| 347 *decoder = m_imageDecoderFactory->create().leakPtr(); | 343 *decoder = m_imageDecoderFactory->create().leakPtr(); |
| 348 | 344 |
| 349 if (!*decoder) | 345 if (!*decoder) |
| 350 *decoder = ImageDecoder::create(*data, ImageDecoder::AlphaPremultipl
ied, ImageDecoder::GammaAndColorProfileApplied).leakPtr(); | 346 *decoder = ImageDecoder::create(*data, ImageDecoder::AlphaPremultipl
ied, ImageDecoder::GammaAndColorProfileApplied).leakPtr(); |
| 351 | 347 |
| 352 if (!*decoder) | 348 if (!*decoder) |
| 353 return false; | 349 return false; |
| 354 } | 350 } |
| 355 | 351 |
| 356 if (!m_isMultiFrame && newDecoder && allDataReceived) { | 352 if (!m_isMultiFrame && newDecoder && allDataReceived) { |
| 357 // If we're using an external memory allocator that means we're decoding | 353 // If we're using an external memory allocator that means we're decoding |
| 358 // directly into the output memory and we can save one memcpy. | 354 // directly into the output memory and we can save one memcpy. |
| 359 ASSERT(m_externalAllocator.get()); | 355 ASSERT(m_externalAllocator.get()); |
| 360 (*decoder)->setMemoryAllocator(m_externalAllocator.get()); | 356 (*decoder)->setMemoryAllocator(m_externalAllocator.get()); |
| 361 } | 357 } |
| 358 |
| 362 (*decoder)->setData(data, allDataReceived); | 359 (*decoder)->setData(data, allDataReceived); |
| 360 ImageFrame* frame = (*decoder)->frameBufferAtIndex(index); |
| 363 | 361 |
| 364 ImageFrame* frame = (*decoder)->frameBufferAtIndex(index); | |
| 365 // For multi-frame image decoders, we need to know how many frames are | 362 // For multi-frame image decoders, we need to know how many frames are |
| 366 // in that image in order to release the decoder when all frames are | 363 // in that image in order to release the decoder when all frames are |
| 367 // decoded. frameCount() is reliable only if all data is received and set in | 364 // decoded. frameCount() is reliable only if all data is received and set in |
| 368 // decoder, particularly with GIF. | 365 // decoder, particularly with GIF. |
| 369 if (allDataReceived) | 366 if (allDataReceived) |
| 370 m_frameCount = (*decoder)->frameCount(); | 367 m_frameCount = (*decoder)->frameCount(); |
| 371 | 368 |
| 372 (*decoder)->setData(0, false); // Unref SharedBuffer from ImageDecoder. | 369 (*decoder)->setData(0, false); // Unref SharedBuffer from ImageDecoder. |
| 373 (*decoder)->clearCacheExceptFrame(index); | 370 (*decoder)->clearCacheExceptFrame(index); |
| 374 (*decoder)->setMemoryAllocator(0); | 371 (*decoder)->setMemoryAllocator(0); |
| 375 | 372 |
| 376 if (!frame || frame->status() == ImageFrame::FrameEmpty) | 373 if (!frame || frame->status() == ImageFrame::FrameEmpty) |
| 377 return false; | 374 return false; |
| 378 | 375 |
| 379 // A cache object is considered complete if we can decode a complete frame. | 376 // A cache object is considered complete if we can decode a complete frame. |
| 380 // Or we have received all data. The image might not be fully decoded in | 377 // Or we have received all data. The image might not be fully decoded in |
| 381 // the latter case. | 378 // the latter case. |
| 382 const bool isDecodeComplete = frame->status() == ImageFrame::FrameComplete |
| allDataReceived; | 379 const bool isDecodeComplete = frame->status() == ImageFrame::FrameComplete |
| allDataReceived; |
| 380 |
| 383 SkBitmap fullSizeBitmap = frame->getSkBitmap(); | 381 SkBitmap fullSizeBitmap = frame->getSkBitmap(); |
| 384 if (!fullSizeBitmap.isNull()) | 382 if (!fullSizeBitmap.isNull()) { |
| 385 { | |
| 386 ASSERT(fullSizeBitmap.width() == m_fullSize.width() && fullSizeBitmap.he
ight() == m_fullSize.height()); | 383 ASSERT(fullSizeBitmap.width() == m_fullSize.width() && fullSizeBitmap.he
ight() == m_fullSize.height()); |
| 387 setHasAlpha(index, !fullSizeBitmap.isOpaque()); | 384 setHasAlpha(index, !fullSizeBitmap.isOpaque()); |
| 388 } | 385 } |
| 386 |
| 389 *bitmap = fullSizeBitmap; | 387 *bitmap = fullSizeBitmap; |
| 390 return isDecodeComplete; | 388 return isDecodeComplete; |
| 391 } | 389 } |
| 392 | 390 |
| 393 bool ImageFrameGenerator::hasAlpha(size_t index) | 391 bool ImageFrameGenerator::hasAlpha(size_t index) |
| 394 { | 392 { |
| 395 MutexLocker lock(m_alphaMutex); | 393 MutexLocker lock(m_alphaMutex); |
| 396 if (index < m_hasAlpha.size()) | 394 if (index < m_hasAlpha.size()) |
| 397 return m_hasAlpha[index]; | 395 return m_hasAlpha[index]; |
| 398 return true; | 396 return true; |
| 399 } | 397 } |
| 400 | 398 |
| 401 bool ImageFrameGenerator::getYUVComponentSizes(SkISize componentSizes[3]) | 399 bool ImageFrameGenerator::getYUVComponentSizes(SkISize componentSizes[3]) |
| 402 { | 400 { |
| 403 ASSERT(componentSizes); | |
| 404 | |
| 405 TRACE_EVENT2("blink", "ImageFrameGenerator::getYUVComponentSizes", "width",
m_fullSize.width(), "height", m_fullSize.height()); | 401 TRACE_EVENT2("blink", "ImageFrameGenerator::getYUVComponentSizes", "width",
m_fullSize.width(), "height", m_fullSize.height()); |
| 406 | 402 |
| 407 SharedBuffer* data = 0; | 403 SharedBuffer* data = 0; |
| 408 bool allDataReceived = false; | 404 bool allDataReceived = false; |
| 409 m_data->data(&data, &allDataReceived); | 405 m_data->data(&data, &allDataReceived); |
| 410 | 406 |
| 411 // FIXME: YUV decoding does not currently support progressive decoding. | 407 // FIXME: YUV decoding does not currently support progressive decoding. |
| 412 if (!allDataReceived) | 408 if (!allDataReceived) |
| 413 return false; | 409 return false; |
| 414 | 410 |
| 415 OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data, ImageDecoder::Alp
haPremultiplied, ImageDecoder::GammaAndColorProfileApplied); | 411 OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data, ImageDecoder::Alp
haPremultiplied, ImageDecoder::GammaAndColorProfileApplied); |
| 416 if (!decoder) | 412 if (!decoder) |
| 417 return false; | 413 return false; |
| 418 | 414 |
| 419 // Setting a dummy ImagePlanes object signals to the decoder that we want to
do YUV decoding. | 415 // Setting a dummy ImagePlanes object signals to the decoder that we want to
do YUV decoding. |
| 420 decoder->setData(data, allDataReceived); | 416 decoder->setData(data, allDataReceived); |
| 421 OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes); | 417 OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes); |
| 422 decoder->setImagePlanes(dummyImagePlanes.release()); | 418 decoder->setImagePlanes(dummyImagePlanes.release()); |
| 423 | 419 |
| 420 ASSERT(componentSizes); |
| 424 return updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder::
SizeForMemoryAllocation); | 421 return updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder::
SizeForMemoryAllocation); |
| 425 } | 422 } |
| 426 | 423 |
| 427 } // namespace blink | 424 } // namespace blink |
| OLD | NEW |