From 8dc8bc55479eb7895b3f0cf4fb42d9d917b21ee1 Mon Sep 17 00:00:00 2001 From: "scroggo@google.com" Date: Wed, 7 Aug 2013 19:16:05 +0000 Subject: [PATCH] Add downsample from 8888 to 4444. Extend SkBitmap::copyTo to copy from a source with SkARGB_8888_Config to a destination bitmap with SkARGB_4444_Config. BUG=http://code.google.com/p/chromium/issues/detail?id=245774 R=reed@google.com Review URL: https://codereview.chromium.org/22350003 git-svn-id: http://skia.googlecode.com/svn/trunk@10621 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gm/copyTo4444.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++ gyp/gmslides.gypi | 1 + src/core/SkBitmap.cpp | 16 ++++++++++++- 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 gm/copyTo4444.cpp diff --git a/gm/copyTo4444.cpp b/gm/copyTo4444.cpp new file mode 100644 index 0000000000..b3dceed639 --- /dev/null +++ b/gm/copyTo4444.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" +#include "SkCanvas.h" +#include "SkImageDecoder.h" +#include "SkOSFile.h" + +namespace skiagm { + +/** + * Test copying an image from 8888 to 4444. + */ +class CopyTo4444GM : public GM { +public: + CopyTo4444GM() {} + +protected: + virtual SkString onShortName() { + return SkString("copyTo4444"); + } + + virtual SkISize onISize() { + return make_isize(1024, 512); + } + + virtual void onDraw(SkCanvas* canvas) { + SkBitmap bm, bm4444; + SkString filename = SkOSPath::SkPathJoin( + INHERITED::gResourcePath.c_str(), "mandrill_512.png"); + if (!SkImageDecoder::DecodeFile(filename.c_str(), &bm, + SkBitmap::kARGB_8888_Config, + SkImageDecoder::kDecodePixels_Mode)) { + SkDebugf("Could not decode the file. Did you forget to set the " + "resourcePath?\n"); + return; + } + canvas->drawBitmap(bm, 0, 0); + SkAssertResult(bm.copyTo(&bm4444, SkBitmap::kARGB_4444_Config)); + canvas->drawBitmap(bm4444, bm.width(), 0); + } + +private: + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { return new CopyTo4444GM; } +static GMRegistry reg(MyFactory); + +} diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index 6729835369..8d0b2e98bb 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -28,6 +28,7 @@ '../gm/composeshader.cpp', #'../gm/conicpaths.cpp', '../gm/convexpaths.cpp', + '../gm/copyTo4444.cpp', '../gm/cubicpaths.cpp', '../gm/cmykjpeg.cpp', '../gm/degeneratesegments.cpp', diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp index 9a116dfc2e..d3bbecd706 100644 --- a/src/core/SkBitmap.cpp +++ b/src/core/SkBitmap.cpp @@ -1017,11 +1017,12 @@ bool SkBitmap::canCopyTo(Config dstConfig) const { break; case kA1_Config: case kIndex8_Config: - case kARGB_4444_Config: if (!sameConfigs) { return false; } break; + case kARGB_4444_Config: + return sameConfigs || kARGB_8888_Config == this->config(); default: return false; } @@ -1109,6 +1110,19 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { dstP += tmpDst.rowBytes(); } } + } else if (SkBitmap::kARGB_4444_Config == dstConfig + && SkBitmap::kARGB_8888_Config == src->config()) { + SkASSERT(src->height() == tmpDst.height()); + SkASSERT(src->width() == tmpDst.width()); + for (int y = 0; y < src->height(); ++y) { + SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y); + SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y); + DITHER_4444_SCAN(y); + for (int x = 0; x < src->width(); ++x) { + dstRow[x] = SkDitherARGB32To4444(srcRow[x], + DITHER_VALUE(x)); + } + } } else { // if the src has alpha, we have to clear the dst first if (!src->isOpaque()) {