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

Unified Diff: skia/ext/image_operations.cc

Issue 118341: Add a mipmap-like divide-by-two image scaling algorithm. I am going to use th... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « skia/ext/image_operations.h ('k') | skia/ext/image_operations_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: skia/ext/image_operations.cc
===================================================================
--- skia/ext/image_operations.cc (revision 17864)
+++ skia/ext/image_operations.cc (working copy)
@@ -624,5 +624,79 @@
return cropped;
}
+// static
+SkBitmap ImageOperations::DownsampleByTwo(const SkBitmap& bitmap) {
+ // Handle the nop case.
+ if (bitmap.width() <= 1 || bitmap.height() <= 1)
+ return bitmap;
+
cpu_(ooo_6.6-7.5) 2009/06/09 17:32:42 do we care if the source bitmap is not KARG_888 ?
+ SkBitmap result;
+ result.setConfig(SkBitmap::kARGB_8888_Config,
+ (bitmap.width() + 1) / 2, (bitmap.height() + 1) / 2);
cpu_(ooo_6.6-7.5) 2009/06/09 17:32:42 vertical aligment
+ result.allocPixels();
+
+ SkAutoLockPixels lock(bitmap);
+ for (int dest_y = 0; dest_y < result.height(); dest_y++) {
+ for (int dest_x = 0; dest_x < result.width(); dest_x++ ) {
+ // This code is based on downsampleby2_proc32 in SkBitmap.cpp. It is very
+ // clever in that it does two channels at once: alpha and green ("ag")
+ // and red and blue ("rb"). Each channel gets averaged across 4 pixels
+ // to get the result.
+ int src_x = dest_x << 1;
+ int src_y = dest_y << 1;
+ const SkPMColor* cur_src = bitmap.getAddr32(src_x, src_y);
+ SkPMColor tmp, ag, rb;
+
+ // Top left pixel of the 2x2 block.
+ tmp = *cur_src;
+ ag = (tmp >> 8) & 0xFF00FF;
+ rb = tmp & 0xFF00FF;
+ if (src_x < bitmap.width() - 1)
+ cur_src += 1;
+
+ // Top right pixel of the 2x2 block.
+ tmp = *cur_src;
+ ag += (tmp >> 8) & 0xFF00FF;
+ rb += tmp & 0xFF00FF;
+ if (src_y < bitmap.height() - 1)
+ cur_src = bitmap.getAddr32(src_x, src_y + 1);
+ else
+ cur_src = bitmap.getAddr32(src_x, src_y); // Move back to the first.
+
+ // Bottom left pixel of the 2x2 block.
+ tmp = *cur_src;
+ ag += (tmp >> 8) & 0xFF00FF;
+ rb += tmp & 0xFF00FF;
+ if (src_x < bitmap.width() - 1)
+ cur_src += 1;
+
+ // Bottom right pixel of the 2x2 block.
+ tmp = *cur_src;
+ ag += (tmp >> 8) & 0xFF00FF;
+ rb += tmp & 0xFF00FF;
+
cpu_(ooo_6.6-7.5) 2009/06/09 17:32:42 note that there must be some implicit division by
+ *result.getAddr32(dest_x, dest_y) =
+ ((rb >> 2) & 0xFF00FF) | ((ag << 6) & 0xFF00FF00);
+ }
+ }
+
+ return result;
+}
+
+// static
+SkBitmap ImageOperations::DownsampleByTwoUntilSize(const SkBitmap& bitmap,
+ int min_w, int min_h) {
+ if (bitmap.width() <= min_w || bitmap.height() <= min_h ||
+ min_w < 0 || min_h < 0)
+ return bitmap;
+
+ // Since bitmaps are refcounted, this copy will be fast.
+ SkBitmap current = bitmap;
+ while (current.width() >= min_w * 2 && current.height() >= min_h * 2 &&
+ current.width() > 1 && current.height() > 1)
+ current = DownsampleByTwo(current);
+ return current;
+}
+
} // namespace skia
« no previous file with comments | « skia/ext/image_operations.h ('k') | skia/ext/image_operations_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698