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: samplecode/SampleUnpremul.cpp

Issue 16410009: Add an option to create unpremultiplied bitmaps. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix for andriod only code. Created 7 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 | « samplecode/SampleColorFilter.cpp ('k') | src/images/SkImageDecoder.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: samplecode/SampleUnpremul.cpp
diff --git a/samplecode/SampleUnpremul.cpp b/samplecode/SampleUnpremul.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dfdd2accdbcd2466cf1e3de20cf24f943cd59981
--- /dev/null
+++ b/samplecode/SampleUnpremul.cpp
@@ -0,0 +1,204 @@
+/*
+ * 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 "SampleCode.h"
+#include "SkBlurDrawLooper.h"
+#include "SkCanvas.h"
+#include "SkColorPriv.h"
+#include "SkForceLinking.h"
+#include "SkImageDecoder.h"
+#include "SkOSFile.h"
+#include "SkStream.h"
+#include "SkString.h"
+#include "SkSystemEventTypes.h"
+#include "SkTypes.h"
+#include "SkUtils.h"
+#include "SkView.h"
+
+__SK_FORCE_IMAGE_DECODER_LINKING;
+
+// Defined in SampleColorFilter.cpp
+extern SkShader* createChecker();
+
+/**
+ * Interprets c as an unpremultiplied color, and returns the
+ * premultiplied equivalent.
+ */
+static SkPMColor premultiply_unpmcolor(SkPMColor c) {
+ U8CPU a = SkGetPackedA32(c);
+ U8CPU r = SkGetPackedR32(c);
+ U8CPU g = SkGetPackedG32(c);
+ U8CPU b = SkGetPackedB32(c);
+ return SkPreMultiplyARGB(a, r, g, b);
+}
+
+class UnpremulView : public SampleView {
+public:
+ UnpremulView(SkString res)
+ : fResPath(res)
+ , fPremul(true)
+ , fDecodeSucceeded(false) {
+ this->nextImage();
+ }
+
+protected:
+ // overrides from SkEventSink
+ virtual bool onQuery(SkEvent* evt) SK_OVERRIDE {
+ if (SampleCode::TitleQ(*evt)) {
+ SampleCode::TitleR(evt, "unpremul");
+ return true;
+ }
+ SkUnichar uni;
+ if (SampleCode::CharQ(*evt, &uni)) {
+ char utf8[kMaxBytesInUTF8Sequence];
+ size_t size = SkUTF8_FromUnichar(uni, utf8);
+ // Only consider events for single char keys
+ if (1 == size) {
+ switch (utf8[0]) {
+ case fNextImageChar:
+ this->nextImage();
+ return true;
+ case fTogglePremulChar:
+ this->togglePremul();
+ return true;
+ default:
+ break;
+ }
+ }
+ }
+ return this->INHERITED::onQuery(evt);
+ }
+
+ virtual void onDrawBackground(SkCanvas* canvas) SK_OVERRIDE {
+ SkPaint paint;
+ SkAutoTUnref<SkShader> shader(createChecker());
+ paint.setShader(shader.get());
+ canvas->drawPaint(paint);
+ }
+
+ virtual void onDrawContent(SkCanvas* canvas) SK_OVERRIDE {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextSize(SkIntToScalar(24));
+ SkAutoTUnref<SkBlurDrawLooper> looper(SkNEW_ARGS(SkBlurDrawLooper,
+ (SkIntToScalar(2), 0, 0, SK_ColorBLUE)));
+ paint.setLooper(looper);
+ SkScalar height = paint.getFontMetrics(NULL);
+ if (!fDecodeSucceeded) {
+ SkString failure;
+ if (fResPath.size() == 0) {
+ failure.printf("resource path is required!");
+ } else {
+ failure.printf("Failed to decode %s", fCurrFile.c_str());
+ }
+ canvas->drawText(failure.c_str(), failure.size(), 0, height, paint);
+ return;
+ }
+
+ // Name, size of the file, and whether or not it is premultiplied.
+ SkString header(SkOSPath::SkBasename(fCurrFile.c_str()));
+ header.appendf(" [%dx%d] %s", fBitmap.width(), fBitmap.height(),
+ (fPremul ? "premultiplied" : "unpremultiplied"));
+ canvas->drawText(header.c_str(), header.size(), 0, height, paint);
+ canvas->translate(0, height);
+
+ // Help messages
+ header.printf("Press '%c' to move to the next image.'", fNextImageChar);
+ canvas->drawText(header.c_str(), header.size(), 0, height, paint);
+ canvas->translate(0, height);
+
+ header.printf("Press '%c' to toggle premultiplied decode.", fTogglePremulChar);
+ canvas->drawText(header.c_str(), header.size(), 0, height, paint);
+
+ // Now draw the image itself.
+ canvas->translate(height * 2, height * 2);
+ if (!fPremul) {
+ // A premultiplied bitmap cannot currently be drawn.
+ SkAutoLockPixels alp(fBitmap);
+ // Copy it to a bitmap which can be drawn, converting
+ // to premultiplied:
+ SkBitmap bm;
+ bm.setConfig(SkBitmap::kARGB_8888_Config, fBitmap.width(),
+ fBitmap.height());
+ SkASSERT(fBitmap.config() == SkBitmap::kARGB_8888_Config);
+ if (!bm.allocPixels()) {
+ SkString errMsg("allocPixels failed");
+ canvas->drawText(errMsg.c_str(), errMsg.size(), 0, height, paint);
+ return;
+ }
+ for (int i = 0; i < fBitmap.width(); ++i) {
+ for (int j = 0; j < fBitmap.height(); ++j) {
+ *bm.getAddr32(i, j) = premultiply_unpmcolor(*fBitmap.getAddr32(i, j));
+ }
+ }
+ canvas->drawBitmap(bm, 0, 0);
+ } else {
+ canvas->drawBitmap(fBitmap, 0, 0);
+ }
+ }
+
+private:
+ const SkString fResPath;
+ SkString fCurrFile;
+ bool fPremul;
+ bool fDecodeSucceeded;
+ SkBitmap fBitmap;
+ SkOSFile::Iter fFileIter;
+
+ static const char fNextImageChar = 'j';
+ static const char fTogglePremulChar = 'h';
+
+ void nextImage() {
+ if (fResPath.size() == 0) {
+ return;
+ }
+ SkString basename;
+ if (!fFileIter.next(&basename)) {
+ fFileIter.reset(fResPath.c_str());
+ if (!fFileIter.next(&basename)) {
+ // Perhaps this should draw some error message?
+ return;
+ }
+ }
+ fCurrFile = SkOSPath::SkPathJoin(fResPath.c_str(), basename.c_str());
+ this->decodeCurrFile();
+ }
+
+ void decodeCurrFile() {
+ if (fCurrFile.size() == 0) {
+ fDecodeSucceeded = false;
+ return;
+ }
+ SkFILEStream stream(fCurrFile.c_str());
+ SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream));
+ if (NULL == decoder.get()) {
+ fDecodeSucceeded = false;
+ return;
+ }
+ if (!fPremul) {
+ decoder->setRequireUnpremultipliedColors(true);
+ }
+ fDecodeSucceeded = decoder->decode(&stream, &fBitmap,
+ SkBitmap::kARGB_8888_Config,
+ SkImageDecoder::kDecodePixels_Mode);
+ this->inval(NULL);
+ }
+
+ void togglePremul() {
+ fPremul = !fPremul;
+ this->decodeCurrFile();
+ }
+
+ typedef SampleView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() {
+ return new UnpremulView(skiagm::GM::GetResourcePath());
+}
+static SkViewRegister reg(MyFactory);
« no previous file with comments | « samplecode/SampleColorFilter.cpp ('k') | src/images/SkImageDecoder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698