diff options
author | aelias <aelias@chromium.org> | 2014-09-23 20:47:20 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-24 03:47:31 +0000 |
commit | 93778c0cb6edfe0d5b1146e2797fbac9abadaf14 (patch) | |
tree | 78fbc33e57e83e17abee58ab7de370993b0671c6 | |
parent | 2e56d4508e33de5fc60bbbb41c5a5d5534e88174 (diff) | |
download | chromium_src-93778c0cb6edfe0d5b1146e2797fbac9abadaf14.zip chromium_src-93778c0cb6edfe0d5b1146e2797fbac9abadaf14.tar.gz chromium_src-93778c0cb6edfe0d5b1146e2797fbac9abadaf14.tar.bz2 |
Fix DecompressionTask with power-of-two expanded thumbnails.
Older versions of Chrome expanded thumbnails to 1024x1024 to work around
an IMG driver bug. When these were processed through DecompressionTask,
they got corrupted because this method assumed the content size and
buffer size were the same. This patch changes it to decompress into a
potentially larger buffer then copy if needed.
BUG=416437
Review URL: https://codereview.chromium.org/598593003
Cr-Commit-Position: refs/heads/master@{#296341}
-rw-r--r-- | chrome/browser/android/thumbnail/thumbnail_store.cc | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/chrome/browser/android/thumbnail/thumbnail_store.cc b/chrome/browser/android/thumbnail/thumbnail_store.cc index afcd687..1923b77 100644 --- a/chrome/browser/android/thumbnail/thumbnail_store.cc +++ b/chrome/browser/android/thumbnail/thumbnail_store.cc @@ -840,33 +840,54 @@ void ThumbnailStore::DecompressionTask( post_decompression_callback, skia::RefPtr<SkPixelRef> compressed_data, float scale, - const gfx::Size& encoded_size) { - SkBitmap raw_data; + const gfx::Size& content_size) { + SkBitmap raw_data_small; bool success = false; if (compressed_data.get()) { - size_t pixel_size = 4; // Pixel size is 4 bytes for kARGB_8888_Config. - size_t stride = pixel_size * encoded_size.width(); - - raw_data.allocPixels(SkImageInfo::Make(encoded_size.width(), - encoded_size.height(), - kRGBA_8888_SkColorType, - kOpaque_SkAlphaType)); + gfx::Size buffer_size = gfx::Size(compressed_data->info().width(), + compressed_data->info().height()); + + SkBitmap raw_data; + raw_data.allocPixels(SkImageInfo::Make(buffer_size.width(), + buffer_size.height(), + kRGBA_8888_SkColorType, + kOpaque_SkAlphaType)); SkAutoLockPixels raw_data_lock(raw_data); + compressed_data->lockPixels(); success = etc1_decode_image( reinterpret_cast<unsigned char*>(compressed_data->pixels()), reinterpret_cast<unsigned char*>(raw_data.getPixels()), - encoded_size.width(), - encoded_size.height(), - pixel_size, - stride); + buffer_size.width(), + buffer_size.height(), + raw_data.bytesPerPixel(), + raw_data.rowBytes()); + compressed_data->unlockPixels(); raw_data.setImmutable(); + + if (!success) { + // Leave raw_data_small empty for consistency with other failure modes. + } else if (content_size == buffer_size) { + // Shallow copy the pixel reference. + raw_data_small = raw_data; + } else { + // The content size is smaller than the buffer size (likely because of + // a power-of-two rounding), so deep copy the bitmap. + raw_data_small.allocPixels(SkImageInfo::Make(content_size.width(), + content_size.height(), + kRGBA_8888_SkColorType, + kOpaque_SkAlphaType)); + SkAutoLockPixels raw_data_small_lock(raw_data_small); + SkCanvas small_canvas(raw_data_small); + small_canvas.drawBitmap(raw_data, 0, 0); + raw_data_small.setImmutable(); + } } content::BrowserThread::PostTask( content::BrowserThread::UI, FROM_HERE, - base::Bind(post_decompression_callback, success, raw_data)); + base::Bind(post_decompression_callback, success, raw_data_small)); } ThumbnailStore::ThumbnailMetaData::ThumbnailMetaData() { |