diff --git a/tests/BitmapTransformerTest.cpp b/tests/BitmapTransformerTest.cpp
new file mode 100644
index 0000000..17d0a00
--- /dev/null
+++ b/tests/BitmapTransformerTest.cpp
@@ -0,0 +1,97 @@
+
+/*
+ * 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 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);
+}
