Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp

Issue 1403393004: JPEGImageDecoder RGB565 and downsample support and related Skia imagegenerator changes Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 SkISize scaledSize = SkISize::Make(info.width(), info.height()); 136 SkISize scaledSize = SkISize::Make(info.width(), info.height());
137 ASSERT(m_fullSize == scaledSize); 137 ASSERT(m_fullSize == scaledSize);
138 138
139 if (m_decodeFailedAndEmpty) 139 if (m_decodeFailedAndEmpty)
140 return false; 140 return false;
141 141
142 TRACE_EVENT2("blink", "ImageFrameGenerator::decodeAndScale", "generator", th is, "decodeCount", m_decodeCount); 142 TRACE_EVENT2("blink", "ImageFrameGenerator::decodeAndScale", "generator", th is, "decodeCount", m_decodeCount);
143 143
144 m_externalAllocator = adoptPtr(new ExternalMemoryAllocator(info, pixels, row Bytes)); 144 m_externalAllocator = adoptPtr(new ExternalMemoryAllocator(info, pixels, row Bytes));
145 145
146 SkBitmap bitmap = tryToResumeDecode(scaledSize, index); 146 SkBitmap bitmap = tryToResumeDecode(scaledSize, index, info.colorType());
147 if (bitmap.isNull()) 147 if (bitmap.isNull())
148 return false; 148 return false;
149 149
150 // Don't keep the allocator because it contains a pointer to memory 150 // Don't keep the allocator because it contains a pointer to memory
151 // that we do not own. 151 // that we do not own.
152 m_externalAllocator.clear(); 152 m_externalAllocator.clear();
153 153
154 ASSERT(bitmap.width() == scaledSize.width()); 154 ASSERT(bitmap.width() == scaledSize.width());
155 ASSERT(bitmap.height() == scaledSize.height()); 155 ASSERT(bitmap.height() == scaledSize.height());
156 156
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 198
199 bool sizeUpdated = updateYUVComponentSizes(decoder.get(), componentSizes, Im ageDecoder::ActualSize); 199 bool sizeUpdated = updateYUVComponentSizes(decoder.get(), componentSizes, Im ageDecoder::ActualSize);
200 RELEASE_ASSERT(sizeUpdated); 200 RELEASE_ASSERT(sizeUpdated);
201 201
202 bool yuvDecoded = decoder->decodeToYUV(); 202 bool yuvDecoded = decoder->decodeToYUV();
203 if (yuvDecoded) 203 if (yuvDecoded)
204 setHasAlpha(0, false); // YUV is always opaque 204 setHasAlpha(0, false); // YUV is always opaque
205 return yuvDecoded; 205 return yuvDecoded;
206 } 206 }
207 207
208 SkBitmap ImageFrameGenerator::tryToResumeDecode(const SkISize& scaledSize, size_ t index) 208 SkBitmap ImageFrameGenerator::tryToResumeDecode(const SkISize& scaledSize, size_ t index, SkColorType outType)
209 { 209 {
210 TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecodeAndScale", "ind ex", static_cast<int>(index)); 210 TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecodeAndScale", "ind ex", static_cast<int>(index));
211 211
212 ImageDecoder* decoder = 0; 212 ImageDecoder* decoder = 0;
213 const bool resumeDecoding = ImageDecodingStore::instance().lockDecoder(this, m_fullSize, &decoder); 213 const bool resumeDecoding = ImageDecodingStore::instance().lockDecoder(this, m_fullSize, &decoder);
214 ASSERT(!resumeDecoding || decoder); 214 ASSERT(!resumeDecoding || decoder);
215 215
216 SkBitmap fullSizeImage; 216 SkBitmap fullSizeImage;
217 bool complete = decode(index, &decoder, &fullSizeImage); 217 bool complete = decode(index, &decoder, &fullSizeImage, outType);
218 218
219 if (!decoder) 219 if (!decoder)
220 return SkBitmap(); 220 return SkBitmap();
221 if (index >= m_frameComplete.size()) 221 if (index >= m_frameComplete.size())
222 m_frameComplete.resize(index + 1); 222 m_frameComplete.resize(index + 1);
223 m_frameComplete[index] = complete; 223 m_frameComplete[index] = complete;
224 224
225 // If we are not resuming decoding that means the decoder is freshly 225 // If we are not resuming decoding that means the decoder is freshly
226 // created and we have ownership. If we are resuming decoding then 226 // created and we have ownership. If we are resuming decoding then
227 // the decoder is owned by ImageDecodingStore. 227 // the decoder is owned by ImageDecodingStore.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 MutexLocker lock(m_alphaMutex); 273 MutexLocker lock(m_alphaMutex);
274 if (index >= m_hasAlpha.size()) { 274 if (index >= m_hasAlpha.size()) {
275 const size_t oldSize = m_hasAlpha.size(); 275 const size_t oldSize = m_hasAlpha.size();
276 m_hasAlpha.resize(index + 1); 276 m_hasAlpha.resize(index + 1);
277 for (size_t i = oldSize; i < m_hasAlpha.size(); ++i) 277 for (size_t i = oldSize; i < m_hasAlpha.size(); ++i)
278 m_hasAlpha[i] = true; 278 m_hasAlpha[i] = true;
279 } 279 }
280 m_hasAlpha[index] = hasAlpha; 280 m_hasAlpha[index] = hasAlpha;
281 } 281 }
282 282
283 bool ImageFrameGenerator::decode(size_t index, ImageDecoder** decoder, SkBitmap* bitmap) 283 bool ImageFrameGenerator::decode(size_t index, ImageDecoder** decoder, SkBitmap* bitmap, SkColorType outType)
284 { 284 {
285 TRACE_EVENT2("blink", "ImageFrameGenerator::decode", "width", m_fullSize.wid th(), "height", m_fullSize.height()); 285 TRACE_EVENT2("blink", "ImageFrameGenerator::decode", "width", m_fullSize.wid th(), "height", m_fullSize.height());
286 286
287 ASSERT(decoder); 287 ASSERT(decoder);
288 SharedBuffer* data = 0; 288 SharedBuffer* data = 0;
289 bool allDataReceived = false; 289 bool allDataReceived = false;
290 bool newDecoder = false;
291 m_data.data(&data, &allDataReceived); 290 m_data.data(&data, &allDataReceived);
292 291
293 // Try to create an ImageDecoder if we are not given one. 292 // Try to create an ImageDecoder if we are not given one.
294 if (!*decoder) { 293 if (!*decoder) {
295 newDecoder = true;
296 if (m_imageDecoderFactory) 294 if (m_imageDecoderFactory)
297 *decoder = m_imageDecoderFactory->create().leakPtr(); 295 *decoder = m_imageDecoderFactory->create().leakPtr();
298 296
299 if (!*decoder) 297 if (!*decoder)
300 *decoder = ImageDecoder::create(*data, ImageDecoder::AlphaPremultipl ied, ImageDecoder::GammaAndColorProfileApplied).leakPtr(); 298 *decoder = ImageDecoder::create(*data, ImageDecoder::AlphaPremultipl ied, ImageDecoder::GammaAndColorProfileApplied).leakPtr();
301 299
302 if (!*decoder) 300 if (!*decoder)
303 return false; 301 return false;
304 } 302 }
305 303
306 if (!m_isMultiFrame && newDecoder && allDataReceived) { 304 if (!m_isMultiFrame && allDataReceived) {
scroggo_chromium 2015/10/19 20:41:36 It seems like removing newDecoder is a separate be
aleksandar.stojiljkovic 2015/10/20 09:51:12 Yes. That code was originally contributed here: ht
scroggo_chromium 2015/10/20 15:06:41 Does it need to be tied to the change to support 5
aleksandar.stojiljkovic 2015/10/20 18:28:41 It makes this use case possible: images originally
aleksandar.stojiljkovic 2015/10/20 18:57:56 It is also required for decode to display resoluti
307 // If we're using an external memory allocator that means we're decoding 305 // If we're using an external memory allocator that means we're decoding
308 // directly into the output memory and we can save one memcpy. 306 // directly into the output memory and we can save one memcpy.
309 ASSERT(m_externalAllocator.get()); 307 ASSERT(m_externalAllocator.get());
310 (*decoder)->setMemoryAllocator(m_externalAllocator.get()); 308 (*decoder)->setMemoryAllocator(m_externalAllocator.get());
311 } 309 }
312 (*decoder)->setData(data, allDataReceived); 310 (*decoder)->setData(data, allDataReceived);
311 if (outType == kRGB_565_SkColorType) {
312 if (!(*decoder)->setDecodeRGB565Enabled(true)) {
313 ASSERT(false);
314 return false;
315 }
316 }
317 ImageFrame* frame = (*decoder)->frameBufferAtIndex(index);
318 // restore back to default
319 (*decoder)->setDecodeRGB565Enabled(false);
scroggo_chromium 2015/10/19 20:41:36 What happens if the caller tries to switch back an
aleksandar.stojiljkovic 2015/10/20 09:51:12 clear the image frame happens in call to ImageFram
scroggo_chromium 2015/10/20 15:06:41 Agreed. But ImageDecoder only calls setSize if it
aleksandar.stojiljkovic 2015/10/20 18:28:41 It is something I've seen happening every time on
313 320
314 ImageFrame* frame = (*decoder)->frameBufferAtIndex(index);
315 // For multi-frame image decoders, we need to know how many frames are 321 // For multi-frame image decoders, we need to know how many frames are
316 // in that image in order to release the decoder when all frames are 322 // in that image in order to release the decoder when all frames are
317 // decoded. frameCount() is reliable only if all data is received and set in 323 // decoded. frameCount() is reliable only if all data is received and set in
318 // decoder, particularly with GIF. 324 // decoder, particularly with GIF.
319 if (allDataReceived) 325 if (allDataReceived)
320 m_frameCount = (*decoder)->frameCount(); 326 m_frameCount = (*decoder)->frameCount();
321 327
322 (*decoder)->setData(0, false); // Unref SharedBuffer from ImageDecoder. 328 (*decoder)->setData(0, false); // Unref SharedBuffer from ImageDecoder.
323 (*decoder)->clearCacheExceptFrame(index); 329 (*decoder)->clearCacheExceptFrame(index);
324 (*decoder)->setMemoryAllocator(0); 330 (*decoder)->setMemoryAllocator(0);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 return false; 378 return false;
373 379
374 // Setting a dummy ImagePlanes object signals to the decoder that we want to do YUV decoding. 380 // Setting a dummy ImagePlanes object signals to the decoder that we want to do YUV decoding.
375 decoder->setData(data, allDataReceived); 381 decoder->setData(data, allDataReceived);
376 OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes); 382 OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes);
377 decoder->setImagePlanes(dummyImagePlanes.release()); 383 decoder->setImagePlanes(dummyImagePlanes.release());
378 384
379 return updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder:: SizeForMemoryAllocation); 385 return updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder:: SizeForMemoryAllocation);
380 } 386 }
381 387
388 bool ImageFrameGenerator::canDecodeToRGB565()
389 {
390 // as the same buffer could be used to store consecutive frames, avoid the c omplexity
391 // since some of consecutive frames could have alpha
392 if (m_isMultiFrame)
393 return false;
394
395 // FIXME check how much this cost (decoder creation) and, also for getYUVCom ponentSizes,
396 // cache it in ImageDecodingStore for the real decode
397 SharedBuffer* data = 0;
398 bool allDataReceived = false;
399 m_data.data(&data, &allDataReceived);
400
401 // partially received data needs to have alpha
402 if (!allDataReceived)
403 return false;
404
405 OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data, ImageDecoder::Alp haPremultiplied, ImageDecoder::GammaAndColorProfileApplied);
406 if (!decoder)
407 return false;
408 return decoder->canDecodeToRGB565();
409 }
410
382 } // namespace blink 411 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698