ARGB image encoder for checksums.
https://codereview.chromium.org/14267031/
git-svn-id: http://skia.googlecode.com/svn/trunk@8831 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gyp/images.gyp b/gyp/images.gyp
index d062d09..c96ff4d 100644
--- a/gyp/images.gyp
+++ b/gyp/images.gyp
@@ -47,6 +47,7 @@
'../src/images/SkImageDecoder_wbmp.cpp',
'../src/images/SkImageEncoder.cpp',
'../src/images/SkImageEncoder_Factory.cpp',
+ '../src/images/SkImageEncoder_argb.cpp',
'../src/images/SkImageRef.cpp',
'../src/images/SkImageRefPool.cpp',
'../src/images/SkImageRefPool.h',
diff --git a/gyp/tests.gyp b/gyp/tests.gyp
index b95b4a6..ef6994e 100644
--- a/gyp/tests.gyp
+++ b/gyp/tests.gyp
@@ -23,13 +23,13 @@
'sources': [
'../tests/AAClipTest.cpp',
'../tests/AnnotationTest.cpp',
+ '../tests/ARGBImageEncoderTest.cpp',
'../tests/AtomicTest.cpp',
'../tests/BitmapCopyTest.cpp',
'../tests/BitmapFactoryTest.cpp',
'../tests/BitmapGetColorTest.cpp',
'../tests/BitmapHasherTest.cpp',
'../tests/BitmapHeapTest.cpp',
- '../tests/BitmapTransformerTest.cpp',
'../tests/BitSetTest.cpp',
'../tests/BlitRowTest.cpp',
'../tests/BlurTest.cpp',
diff --git a/gyp/utils.gyp b/gyp/utils.gyp
index a14f585..169bfbf 100644
--- a/gyp/utils.gyp
+++ b/gyp/utils.gyp
@@ -12,6 +12,7 @@
'../include/config',
'../include/core',
'../include/effects',
+ '../include/images',
'../include/pipe',
'../include/utils',
'../include/utils/mac',
@@ -59,8 +60,6 @@
'../src/utils/SkBase64.h',
'../src/utils/SkBitmapHasher.cpp',
'../src/utils/SkBitmapHasher.h',
- '../src/utils/SkBitmapTransformer.cpp',
- '../src/utils/SkBitmapTransformer.h',
'../src/utils/SkBitSet.cpp',
'../src/utils/SkBitSet.h',
'../src/utils/SkBoundaryPatch.cpp',
diff --git a/include/images/SkImageEncoder.h b/include/images/SkImageEncoder.h
index 5db32c3..0f7d18a 100644
--- a/include/images/SkImageEncoder.h
+++ b/include/images/SkImageEncoder.h
@@ -83,6 +83,11 @@
// All the encoders known by Skia. Note that, depending on the compiler settings,
// not all of these will be available
+/** An ARGBImageEncoder will always write out
+ * bitmap.width() * bitmap.height() * 4
+ * bytes.
+ */
+DECLARE_ENCODER_CREATOR(ARGBImageEncoder);
DECLARE_ENCODER_CREATOR(JPEGImageEncoder);
DECLARE_ENCODER_CREATOR(PNGImageEncoder);
DECLARE_ENCODER_CREATOR(WEBPImageEncoder);
diff --git a/src/images/SkImageEncoder_argb.cpp b/src/images/SkImageEncoder_argb.cpp
new file mode 100644
index 0000000..5abc23c
--- /dev/null
+++ b/src/images/SkImageEncoder_argb.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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 "SkImageEncoder.h"
+#include "SkBitmap.h"
+#include "SkColorPriv.h"
+#include "SkStream.h"
+#include "SkTemplates.h"
+
+class SkARGBImageEncoder : public SkImageEncoder {
+protected:
+ virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) SK_OVERRIDE;
+
+private:
+ typedef SkImageEncoder INHERITED;
+};
+
+typedef void (*ScanlineImporter)(const uint8_t* in, uint8_t* argb, int width,
+ const SkPMColor* SK_RESTRICT ctable);
+
+static void ARGB_8888_To_ARGB(const uint8_t* in, uint8_t* argb, int width, const SkPMColor*) {
+ const uint32_t* SK_RESTRICT src = (const uint32_t*)in;
+ for (int i = 0; i < width; ++i) {
+ const uint32_t c = *src++;
+ argb[0] = SkGetPackedA32(c);
+ argb[1] = SkGetPackedR32(c);
+ argb[2] = SkGetPackedG32(c);
+ argb[3] = SkGetPackedB32(c);
+ argb += 4;
+ }
+}
+
+static void RGB_565_To_ARGB(const uint8_t* in, uint8_t* argb, int width, const SkPMColor*) {
+ const uint16_t* SK_RESTRICT src = (const uint16_t*)in;
+ for (int i = 0; i < width; ++i) {
+ const uint16_t c = *src++;
+ argb[0] = 0xFF;
+ argb[1] = SkPacked16ToR32(c);
+ argb[2] = SkPacked16ToG32(c);
+ argb[3] = SkPacked16ToB32(c);
+ argb += 4;
+ }
+}
+
+static void ARGB_4444_To_ARGB(const uint8_t* in, uint8_t* argb, int width, const SkPMColor*) {
+ const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)in;
+ for (int i = 0; i < width; ++i) {
+ const SkPMColor16 c = *src++;
+ argb[0] = SkPacked4444ToA32(c);
+ argb[1] = SkPacked4444ToR32(c);
+ argb[2] = SkPacked4444ToG32(c);
+ argb[3] = SkPacked4444ToB32(c);
+ argb += 4;
+ }
+}
+
+static void Index8_To_ARGB(const uint8_t* in, uint8_t* argb, int width,
+ const SkPMColor* SK_RESTRICT ctable) {
+ const uint8_t* SK_RESTRICT src = (const uint8_t*)in;
+ for (int i = 0; i < width; ++i) {
+ const uint32_t c = ctable[*src++];
+ argb[0] = SkGetPackedA32(c);
+ argb[1] = SkGetPackedR32(c);
+ argb[2] = SkGetPackedG32(c);
+ argb[3] = SkGetPackedB32(c);
+ argb += 4;
+ }
+}
+
+static ScanlineImporter ChooseImporter(const SkBitmap::Config& config) {
+ switch (config) {
+ case SkBitmap::kARGB_8888_Config:
+ return ARGB_8888_To_ARGB;
+ case SkBitmap::kRGB_565_Config:
+ return RGB_565_To_ARGB;
+ case SkBitmap::kARGB_4444_Config:
+ return ARGB_4444_To_ARGB;
+ case SkBitmap::kIndex8_Config:
+ return Index8_To_ARGB;
+ default:
+ return NULL;
+ }
+}
+
+bool SkARGBImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bitmap, int) {
+ const SkBitmap::Config config = bitmap.getConfig();
+ const ScanlineImporter scanline_import = ChooseImporter(config);
+ if (NULL == scanline_import) {
+ return false;
+ }
+
+ SkAutoLockPixels alp(bitmap);
+ const uint8_t* src = (uint8_t*)bitmap.getPixels();
+ if (NULL == bitmap.getPixels()) {
+ return false;
+ }
+
+ SkAutoLockColors ctLocker;
+ const SkPMColor* colors = ctLocker.lockColors(bitmap);
+
+ const int argbStride = bitmap.width() * 4;
+ SkAutoTDeleteArray<uint8_t> ada(new uint8_t[argbStride]);
+ uint8_t* argb = ada.get();
+ for (int y = 0; y < bitmap.height(); ++y) {
+ scanline_import(src + y * bitmap.rowBytes(), argb, bitmap.width(), colors);
+ stream->write(argb, argbStride);
+ }
+
+ return true;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+DEFINE_ENCODER_CREATOR(ARGBImageEncoder);
+///////////////////////////////////////////////////////////////////////////////
diff --git a/src/utils/SkBitmapHasher.cpp b/src/utils/SkBitmapHasher.cpp
index 6df3ab9..e8352e5 100644
--- a/src/utils/SkBitmapHasher.cpp
+++ b/src/utils/SkBitmapHasher.cpp
@@ -1,4 +1,3 @@
-
/*
* Copyright 2012 Google Inc.
*
@@ -8,63 +7,55 @@
#include "SkBitmap.h"
#include "SkBitmapHasher.h"
-#include "SkBitmapTransformer.h"
#include "SkCityHash.h"
#include "SkEndian.h"
+#include "SkImageEncoder.h"
+#include "SkStream.h"
/**
- * Write an integer value into a bytebuffer in little-endian order.
+ * Write an integer value to a stream in little-endian order.
*/
-static void write_int_to_buffer(int val, char* buf) {
+static void write_int_to_buffer(uint32_t val, SkWStream* out) {
val = SkEndian_SwapLE32(val);
- for (int byte=0; byte<4; byte++) {
- *buf++ = (char)(val & 0xff);
+ for (size_t byte = 0; byte < 4; ++byte) {
+ out->write8((uint8_t)(val & 0xff));
val = val >> 8;
}
}
-/*static*/ bool SkBitmapHasher::ComputeDigestInternal(
- const SkBitmap& bitmap, const SkBitmapTransformer& transformer, SkHashDigest *result) {
- size_t pixelBufferSize = transformer.bytesNeededTotal();
- size_t totalBufferSize = pixelBufferSize + 8; // leave room for x/y dimensions
+/*static*/ bool SkBitmapHasher::ComputeDigestInternal(const SkBitmap& bitmap,
+ SkHashDigest *result) {
+ size_t pixelBufferSize = bitmap.width() * bitmap.height() * 4;
+ size_t totalBufferSize = pixelBufferSize + 2 * sizeof(uint32_t);
SkAutoMalloc bufferManager(totalBufferSize);
char *bufferStart = static_cast<char *>(bufferManager.get());
- char *bufPtr = bufferStart;
+ SkMemoryWStream out(bufferStart, totalBufferSize);
+
// start with the x/y dimensions
- write_int_to_buffer(bitmap.width(), bufPtr);
- bufPtr += 4;
- write_int_to_buffer(bitmap.height(), bufPtr);
- bufPtr += 4;
+ write_int_to_buffer(SkToU32(bitmap.width()), &out);
+ write_int_to_buffer(SkToU32(bitmap.height()), &out);
// add all the pixel data
- if (!transformer.copyBitmapToPixelBuffer(bufPtr, pixelBufferSize)) {
+ SkAutoTDelete<SkImageEncoder> enc(CreateARGBImageEncoder());
+ if (!enc->encodeStream(&out, bitmap, SkImageEncoder::kDefaultQuality)) {
return false;
}
+
*result = SkCityHash::Compute64(bufferStart, totalBufferSize);
return true;
}
/*static*/ bool SkBitmapHasher::ComputeDigest(const SkBitmap& bitmap, SkHashDigest *result) {
- const SkBitmapTransformer::PixelFormat kPixelFormat =
- SkBitmapTransformer::kARGB_8888_Premul_PixelFormat;
-
- // First, try to transform the existing bitmap.
- const SkBitmapTransformer transformer =
- SkBitmapTransformer(bitmap, kPixelFormat);
- if (transformer.isValid(false)) {
- return ComputeDigestInternal(bitmap, transformer, result);
+ if (ComputeDigestInternal(bitmap, result)) {
+ return true;
}
// Hmm, that didn't work. Maybe if we create a new
// kARGB_8888_Config version of the bitmap it will work better?
SkBitmap copyBitmap;
- bitmap.copyTo(©Bitmap, SkBitmap::kARGB_8888_Config);
- const SkBitmapTransformer copyTransformer =
- SkBitmapTransformer(copyBitmap, kPixelFormat);
- if (copyTransformer.isValid(true)) {
- return ComputeDigestInternal(copyBitmap, copyTransformer, result);
- } else {
+ if (!bitmap.copyTo(©Bitmap, SkBitmap::kARGB_8888_Config)) {
return false;
}
+ return ComputeDigestInternal(copyBitmap, result);
}
diff --git a/src/utils/SkBitmapHasher.h b/src/utils/SkBitmapHasher.h
index dc8685b..165da3d 100644
--- a/src/utils/SkBitmapHasher.h
+++ b/src/utils/SkBitmapHasher.h
@@ -10,7 +10,6 @@
#define SkBitmapHasher_DEFINED
#include "SkBitmap.h"
-#include "SkBitmapTransformer.h"
// TODO(epoger): Soon, SkHashDigest will become a real class of its own,
// and callers won't be able to assume it converts to/from a uint64_t.
@@ -34,9 +33,7 @@
static bool ComputeDigest(const SkBitmap& bitmap, SkHashDigest *result);
private:
- static bool ComputeDigestInternal(const SkBitmap& bitmap,
- const SkBitmapTransformer& transformer,
- SkHashDigest *result);
+ static bool ComputeDigestInternal(const SkBitmap& bitmap, SkHashDigest *result);
};
#endif
diff --git a/src/utils/SkBitmapTransformer.cpp b/src/utils/SkBitmapTransformer.cpp
deleted file mode 100644
index c8356d4..0000000
--- a/src/utils/SkBitmapTransformer.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkBitmap.h"
-#include "SkBitmapTransformer.h"
-#include "SkColorPriv.h"
-#include "SkTypes.h"
-
-bool SkBitmapTransformer::isValid(bool logReason) const {
- bool retval = true;
-
- switch(fPixelFormat) {
- case kARGB_8888_Premul_PixelFormat:
- break;
- default:
- if (logReason) {
- SkDEBUGF(("PixelFormat %d not supported\n", fPixelFormat));
- }
- retval = false;
- }
-
- SkBitmap::Config bitmapConfig = fBitmap.config();
- switch(bitmapConfig) {
- case SkBitmap::kARGB_8888_Config:
- break;
- default:
- if (logReason) {
- SkDEBUGF(("SkBitmap::Config %d not supported\n", bitmapConfig));
- }
- retval = false;
- }
-
- return retval;
-}
-
-/**
- * Transform from kARGB_8888_Config to kARGB_8888_Premul_PixelFormat.
- *
- * Similar to the various scanline transformers in
- * src/images/transform_scanline.h .
- */
-static void transform_scanline(const char* SK_RESTRICT src, int width,
- char* SK_RESTRICT dst) {
- const SkPMColor* SK_RESTRICT srcP = reinterpret_cast<const SkPMColor*>(src);
- for (int i = 0; i < width; i++) {
- SkPMColor c = *srcP++;
- unsigned a = SkGetPackedA32(c);
- unsigned r = SkGetPackedR32(c);
- unsigned g = SkGetPackedG32(c);
- unsigned b = SkGetPackedB32(c);
- *dst++ = a;
- *dst++ = r;
- *dst++ = g;
- *dst++ = b;
- }
-}
-
-bool SkBitmapTransformer::copyBitmapToPixelBuffer(void *dstBuffer,
- size_t dstBufferSize) const {
- if (!this->isValid(true)) {
- return false;
- }
- size_t bytesNeeded = this->bytesNeededTotal();
- if (dstBufferSize < bytesNeeded) {
- SkDEBUGF(("dstBufferSize %d must be >= %d\n", dstBufferSize, bytesNeeded));
- return false;
- }
-
- fBitmap.lockPixels();
- int width = fBitmap.width();
- size_t srcRowBytes = fBitmap.rowBytes();
- size_t dstRowBytes = this->bytesNeededPerRow();
- const char *srcBytes = const_cast<const char *>(static_cast<char*>(fBitmap.getPixels()));
- char *dstBytes = static_cast<char *>(dstBuffer);
- for (int y = 0; y < fBitmap.height(); y++) {
- transform_scanline(srcBytes, width, dstBytes);
- srcBytes += srcRowBytes;
- dstBytes += dstRowBytes;
- }
- fBitmap.unlockPixels();
- return true;
-}
diff --git a/src/utils/SkBitmapTransformer.h b/src/utils/SkBitmapTransformer.h
deleted file mode 100644
index 70971ac..0000000
--- a/src/utils/SkBitmapTransformer.h
+++ /dev/null
@@ -1,104 +0,0 @@
-
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkBitmapTransformer_DEFINED
-#define SkBitmapTransformer_DEFINED
-
-#include "SkBitmap.h"
-
-/**
- * Class that can copy pixel data out of an SkBitmap, transforming it
- * into the appropriate PixelFormat.
- *
- * As noted in https://codereview.appspot.com/6849119/#msg6 and
- * https://codereview.appspot.com/6900047 , at some point we might want
- * to make this more general purpose:
- * - support more PixelFormats
- * - use existing SkCanvas::Config8888 enum instead of new PixelFormat enum
- * - add method to copy pixel data for a single row, instead of the whole bitmap
- * - add methods to copy pixel data INTO an SkBitmap
- *
- * That would allow us to replace SkCopyConfig8888ToBitmap() in
- * src/core/SkConfig8888.h , as well as the transformations used by
- * src/images/SkImageDecoder_libpng.cpp , with this common code.
- *
- * But for now, we want something more narrowly targeted, just
- * supplying what is needed by SkBitmapChecksummer.
- */
-class SkBitmapTransformer {
-public:
- enum PixelFormat {
- // 32 bits per pixel, ARGB byte order, with the alpha-channel
- // value premultiplied into the R/G/B channel values.
- kARGB_8888_Premul_PixelFormat,
-
- // marks the end of the list
- kLast_PixelFormat = kARGB_8888_Premul_PixelFormat,
- };
-
- /**
- * Creates an SkBitmapTransformer instance that can transform between
- * the given bitmap and a pixel buffer with given pixelFormat.
- *
- * Call IsValid() before using, to confirm that this particular
- * bitmap/pixelFormat combination is supported!
- */
- SkBitmapTransformer(const SkBitmap& bitmap, PixelFormat pixelFormat) :
- fBitmap(bitmap), fPixelFormat(pixelFormat) {}
-
- /**
- * Returns true iff we can convert between fBitmap and fPixelFormat.
- * If this returns false, the return values of any other methods will
- * be meaningless!
- *
- * @param logReason whether to log the reason why this combination
- * is unsupported (only applies in debug mode)
- */
- bool isValid(bool logReason=false) const;
-
- /**
- * Returns the number of bytes needed to store a single row of the
- * bitmap's pixels if converted to pixelFormat.
- */
- size_t bytesNeededPerRow() const {
- // This is hard-coded for the single supported PixelFormat.
- return fBitmap.width() * 4;
- }
-
- /**
- * Returns the number of bytes needed to store the entire bitmap
- * if converted to pixelFormat, ASSUMING that it is written
- * out as a single contiguous blob of pixels (no leftover bytes
- * at the end of each row).
- */
- size_t bytesNeededTotal() const {
- return this->bytesNeededPerRow() * fBitmap.height();
- }
-
- /**
- * Writes the entire bitmap into dstBuffer, using the already-specified
- * pixelFormat. Returns true if successful.
- *
- * dstBufferSize is the maximum allowable bytes to write into dstBuffer;
- * if that is not large enough to hold the entire bitmap, then this
- * will fail immediately and return false.
- * We force the caller to pass this in to avoid buffer overruns in
- * unanticipated cases.
- *
- * All pixels for all rows will be written into dstBuffer as a
- * single contiguous blob (no skipped pixels at the end of each
- * row).
- */
- bool copyBitmapToPixelBuffer (void *dstBuffer, size_t dstBufferSize) const;
-
-private:
- const SkBitmap& fBitmap;
- const PixelFormat fPixelFormat;
-};
-
-#endif
diff --git a/src/utils/SkMD5.h b/src/utils/SkMD5.h
index 6fbdb46..6b4fc53 100644
--- a/src/utils/SkMD5.h
+++ b/src/utils/SkMD5.h
@@ -17,7 +17,7 @@
//SK_CPU_LENDIAN allows 32 bit <=> 8 bit conversions without copies (if alligned).
//SK_CPU_FAST_UNALIGNED_ACCESS allows 32 bit <=> 8 bit conversions without copies if SK_CPU_LENDIAN.
-class SkMD5 : SkWStream {
+class SkMD5 : public SkWStream {
public:
SkMD5();
diff --git a/src/utils/SkSHA1.h b/src/utils/SkSHA1.h
index 10bbc43..cf2cb8c 100644
--- a/src/utils/SkSHA1.h
+++ b/src/utils/SkSHA1.h
@@ -17,7 +17,7 @@
//SK_CPU_BENDIAN allows 32 bit <=> 8 bit conversions without copies (if alligned).
//SK_CPU_FAST_UNALIGNED_ACCESS allows 32 bit <=> 8 bit conversions without copies if SK_CPU_BENDIAN.
-class SkSHA1 : SkWStream {
+class SkSHA1 : public SkWStream {
public:
SkSHA1();
diff --git a/tests/ARGBImageEncoderTest.cpp b/tests/ARGBImageEncoderTest.cpp
new file mode 100644
index 0000000..05ad58c
--- /dev/null
+++ b/tests/ARGBImageEncoderTest.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/** Tests for ARGBImageEncoder. */
+
+#include "Test.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkImageEncoder.h"
+#include "SkStream.h"
+
+namespace skiatest {
+
+class BitmapTransformerTestClass : public Test {
+public:
+ static Test* Factory(void*) { return SkNEW(BitmapTransformerTestClass); }
+protected:
+ virtual void onGetName(SkString* name) SK_OVERRIDE { name->set("ARGBImageEncoder"); }
+ virtual void onRun(Reporter* reporter) SK_OVERRIDE;
+};
+
+static SkBitmap::Config configs[] = {
+ SkBitmap::kRGB_565_Config,
+ SkBitmap::kARGB_4444_Config,
+ SkBitmap::kARGB_8888_Config,
+};
+
+void BitmapTransformerTestClass::onRun(Reporter* reporter) {
+ // Bytes we expect to get:
+ const int kWidth = 3;
+ const int kHeight = 5;
+ const unsigned char comparisonBuffer[] = {
+ // kHeight rows, each with kWidth pixels, premultiplied ARGB for each pixel
+ 0xff,0xff,0x00,0x00, 0xff,0xff,0x00,0x00, 0xff,0xff,0x00,0x00, // red
+ 0xff,0x00,0xff,0x00, 0xff,0x00,0xff,0x00, 0xff,0x00,0xff,0x00, // green
+ 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, // blue
+ 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, // blue
+ 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, // blue
+ };
+
+ SkAutoTDelete<SkImageEncoder> enc(CreateARGBImageEncoder());
+ for (size_t configIndex = 0; configIndex < SK_ARRAY_COUNT(configs); ++configIndex) {
+ // A bitmap that should generate the above bytes:
+ SkBitmap bitmap;
+ {
+ bitmap.setConfig(configs[configIndex], kWidth, kHeight);
+ REPORTER_ASSERT(reporter, bitmap.allocPixels());
+ bitmap.setIsOpaque(true);
+ bitmap.eraseColor(SK_ColorBLUE);
+ // Change rows [0,1] from blue to [red,green].
+ SkCanvas canvas(bitmap);
+ SkPaint paint;
+ paint.setColor(SK_ColorRED);
+ canvas.drawIRect(SkIRect::MakeLTRB(0, 0, kWidth, 1), paint);
+ paint.setColor(SK_ColorGREEN);
+ canvas.drawIRect(SkIRect::MakeLTRB(0, 1, kWidth, 2), paint);
+ }
+
+ // Transform the bitmap.
+ int bufferSize = bitmap.width() * bitmap.height() * 4;
+ SkAutoMalloc pixelBufferManager(bufferSize);
+ char *pixelBuffer = static_cast<char *>(pixelBufferManager.get());
+ SkMemoryWStream out(pixelBuffer, bufferSize);
+ REPORTER_ASSERT(reporter, enc->encodeStream(&out, bitmap, SkImageEncoder::kDefaultQuality));
+
+ // Confirm we got the expected results.
+ REPORTER_ASSERT(reporter, bufferSize == sizeof(comparisonBuffer));
+ REPORTER_ASSERT(reporter, memcmp(pixelBuffer, comparisonBuffer, bufferSize) == 0);
+ }
+}
+
+static TestRegistry gReg(BitmapTransformerTestClass::Factory);
+
+}
diff --git a/tests/BitmapTransformerTest.cpp b/tests/BitmapTransformerTest.cpp
deleted file mode 100644
index d9ce696..0000000
--- a/tests/BitmapTransformerTest.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/**
- * Tests for SkBitmapTransformer.h and SkBitmapTransformer.cpp
- */
-
-#include "Test.h"
-#include "SkBitmap.h"
-#include "SkBitmapTransformer.h"
-
-namespace skiatest {
- class BitmapTransformerTestClass : public Test {
- public:
- static Test* Factory(void*) {return SkNEW(BitmapTransformerTestClass); }
- protected:
- virtual void onGetName(SkString* name) { name->set("BitmapTransformer"); }
- virtual void onRun(Reporter* reporter) {
- this->fReporter = reporter;
- RunTest();
- }
- private:
- void RunTest() {
- SkBitmap bitmap;
- SkBitmap::Config supportedConfig = SkBitmap::kARGB_8888_Config;
- SkBitmap::Config unsupportedConfig = SkBitmap::kARGB_4444_Config;
- SkBitmapTransformer::PixelFormat supportedPixelFormat =
- SkBitmapTransformer::kARGB_8888_Premul_PixelFormat;
- const int kWidth = 55;
- const int kHeight = 333;
-
- // Transformations that we know are unsupported:
- {
- bitmap.setConfig(unsupportedConfig, kWidth, kHeight);
- SkBitmapTransformer transformer = SkBitmapTransformer(bitmap, supportedPixelFormat);
- REPORTER_ASSERT(fReporter, !transformer.isValid());
- }
-
- // Valid transformations:
- {
- // Bytes we expect to get:
- const int kWidth = 3;
- const int kHeight = 5;
- const unsigned char comparisonBuffer[] = {
- // kHeight rows, each with kWidth pixels, premultiplied ARGB for each pixel
- 0xff,0xff,0x00,0x00, 0xff,0xff,0x00,0x00, 0xff,0xff,0x00,0x00, // red
- 0xff,0x00,0xff,0x00, 0xff,0x00,0xff,0x00, 0xff,0x00,0xff,0x00, // green
- 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, // blue
- 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, // blue
- 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, // blue
- };
-
- // A bitmap that should generate the above bytes:
- bitmap.setConfig(supportedConfig, kWidth, kHeight);
- REPORTER_ASSERT(fReporter, bitmap.allocPixels());
- bitmap.setIsOpaque(true);
- bitmap.eraseColor(SK_ColorBLUE);
- bitmap.lockPixels();
- // Change rows [0,1] from blue to [red,green].
- SkColor oldColor = SK_ColorBLUE;
- SkColor newColors[] = {SK_ColorRED, SK_ColorGREEN};
- for (int y = 0; y <= 1; y++) {
- for (int x = 0; x < kWidth; x++) {
- REPORTER_ASSERT(fReporter, bitmap.getColor(x, y) == oldColor);
- SkPMColor* pixel = static_cast<SkPMColor *>(bitmap.getAddr(x, y));
- *pixel = SkPreMultiplyColor(newColors[y]);
- REPORTER_ASSERT(fReporter, bitmap.getColor(x, y) == newColors[y]);
- }
- }
- bitmap.unlockPixels();
-
- // Transform the bitmap and confirm we got the expected results.
- SkBitmapTransformer transformer = SkBitmapTransformer(bitmap, supportedPixelFormat);
- REPORTER_ASSERT(fReporter, transformer.isValid());
- REPORTER_ASSERT(fReporter, transformer.bytesNeededPerRow() == kWidth * 4);
- REPORTER_ASSERT(fReporter, transformer.bytesNeededTotal() == kWidth * kHeight * 4);
- int bufferSize = transformer.bytesNeededTotal();
- SkAutoMalloc pixelBufferManager(bufferSize);
- char *pixelBuffer = static_cast<char *>(pixelBufferManager.get());
- REPORTER_ASSERT(fReporter,
- transformer.copyBitmapToPixelBuffer(pixelBuffer, bufferSize));
- REPORTER_ASSERT(fReporter, bufferSize == sizeof(comparisonBuffer));
- REPORTER_ASSERT(fReporter, memcmp(pixelBuffer, comparisonBuffer, bufferSize) == 0);
- }
-
- }
-
- Reporter* fReporter;
- };
-
- static TestRegistry gReg(BitmapTransformerTestClass::Factory);
-}