summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraelias <aelias@chromium.org>2014-09-23 20:47:20 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-24 03:47:31 +0000
commit93778c0cb6edfe0d5b1146e2797fbac9abadaf14 (patch)
tree78fbc33e57e83e17abee58ab7de370993b0671c6
parent2e56d4508e33de5fc60bbbb41c5a5d5534e88174 (diff)
downloadchromium_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.cc49
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() {