add new copyTo version to SkBitmap, which takes SkColorType

BUG=skia:
R=scroggo@google.com, halcanary@google.com, bsalomon@google.com

Author: reed@google.com

Review URL: https://codereview.chromium.org/171723007

git-svn-id: http://skia.googlecode.com/svn/trunk@13553 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/dm/DMWriteTask.cpp b/dm/DMWriteTask.cpp
index dc31d29..5adb1d0 100644
--- a/dm/DMWriteTask.cpp
+++ b/dm/DMWriteTask.cpp
@@ -113,12 +113,10 @@
         return false;
     }
 
-    SkImageInfo info;
-    SkAssertResult(bitmap.asImageInfo(&info));
+    const SkImageInfo info = bitmap.info();
 
     SkBitmap expected;
-    expected.setConfig(info);
-    expected.allocPixels();
+    expected.allocPixels(info);
 
     // expected will be unpremultiplied.
     decoder->setRequireUnpremultipliedColors(true);
@@ -128,19 +126,18 @@
     }
 
     // We always seem to decode to 8888.  This puts 565 back in 565.
-    if (expected.config() != bitmap.config()) {
+    if (expected.colorType() != bitmap.colorType()) {
         SkBitmap converted;
-        SkAssertResult(expected.copyTo(&converted, bitmap.config()));
+        SkAssertResult(expected.copyTo(&converted, bitmap.colorType()));
         expected.swap(converted);
     }
     SkASSERT(expected.config() == bitmap.config());
 
     // Manually unpremultiply 8888 bitmaps to match expected.
     // Their pixels are shared, concurrently even, so we must copy them.
-    if (info.fColorType == kPMColor_SkColorType) {
+    if (info.colorType() == kPMColor_SkColorType) {
         SkBitmap unpremul;
-        unpremul.setConfig(info);
-        unpremul.allocPixels();
+        unpremul.allocPixels(info);
 
         SkAutoLockPixels lockSrc(bitmap), lockDst(unpremul);
         const SkPMColor* src = (SkPMColor*)bitmap.getPixels();
diff --git a/gm/bitmapcopy.cpp b/gm/bitmapcopy.cpp
index 5bd2bf8..68db908 100644
--- a/gm/bitmapcopy.cpp
+++ b/gm/bitmapcopy.cpp
@@ -9,23 +9,23 @@
 
 namespace skiagm {
 
-static const char* gConfigNames[] = {
-    "unknown config",
+static const char* gColorTypeNames[] = {
+    "unknown",
     "A8",
-    "Index8",
     "565",
     "4444",
-    "8888"
+    "8888",
+    "8888",
+    "Index8",
 };
 
-SkBitmap::Config gConfigs[] = {
-  SkBitmap::kRGB_565_Config,
-  SkBitmap::kARGB_4444_Config,  // TODO(edisonn): Should we remove it from GM?
-                                // it fails to copy in bitmap with this config.
-  SkBitmap::kARGB_8888_Config,
+static const SkColorType gColorTypes[] = {
+    kRGB_565_SkColorType,
+    kARGB_4444_SkColorType,
+    kPMColor_SkColorType,
 };
 
-#define NUM_CONFIGS (sizeof(gConfigs) / sizeof(SkBitmap::Config))
+#define NUM_CONFIGS SK_ARRAY_COUNT(gColorTypes)
 
 static void draw_checks(SkCanvas* canvas, int width, int height) {
     SkPaint paint;
@@ -72,7 +72,7 @@
         draw_checks(&canvasTmp, 40, 40);
 
         for (unsigned i = 0; i < NUM_CONFIGS; ++i) {
-            src.copyTo(&fDst[i], gConfigs[i]);
+            src.copyTo(&fDst[i], gColorTypes[i]);
         }
 
         canvas->clear(0xFFDDDDDD);
@@ -83,7 +83,7 @@
             height = paint.getFontSpacing();
         }
         for (unsigned i = 0; i < NUM_CONFIGS; i++) {
-            const char* name = gConfigNames[src.config()];
+            const char* name = gColorTypeNames[src.colorType()];
             SkScalar textWidth = paint.measureText(name, strlen(name));
             if (textWidth > width) {
                 width = textWidth;
@@ -96,7 +96,7 @@
         for (unsigned i = 0; i < NUM_CONFIGS; i++) {
             canvas->save();
             // Draw destination config name
-            const char* name = gConfigNames[fDst[i].config()];
+            const char* name = gColorTypeNames[fDst[i].colorType()];
             SkScalar textWidth = paint.measureText(name, strlen(name));
             SkScalar x = (width - textWidth) / SkScalar(2);
             SkScalar y = paint.getFontSpacing() / SkScalar(2);
diff --git a/gm/bitmapfilters.cpp b/gm/bitmapfilters.cpp
index 7addf25..fb3b304 100644
--- a/gm/bitmapfilters.cpp
+++ b/gm/bitmapfilters.cpp
@@ -85,9 +85,9 @@
         }
         fOnce = true;
         make_bm(&fBM8);
-        fBM8.copyTo(&fBM4444, SkBitmap::kARGB_4444_Config);
-        fBM8.copyTo(&fBM16, SkBitmap::kRGB_565_Config);
-        fBM8.copyTo(&fBM32, SkBitmap::kARGB_8888_Config);
+        fBM8.copyTo(&fBM4444, kARGB_4444_SkColorType);
+        fBM8.copyTo(&fBM16, kRGB_565_SkColorType);
+        fBM8.copyTo(&fBM32, kPMColor_SkColorType);
     }
 public:
     SkBitmap    fBM8, fBM4444, fBM16, fBM32;
diff --git a/gm/bitmapscroll.cpp b/gm/bitmapscroll.cpp
index b14b047..d2b8ca0 100644
--- a/gm/bitmapscroll.cpp
+++ b/gm/bitmapscroll.cpp
@@ -129,7 +129,7 @@
                 // scrollRect() should always return true, even if it's a no-op
                 SkBitmap scrolledBitmap;
                 SkDEBUGCODE(bool copyToReturnValue = )origBitmap.copyTo(
-                    &scrolledBitmap, origBitmap.config());
+                    &scrolledBitmap, origBitmap.colorType());
                 SkASSERT(copyToReturnValue);
                 SkDEBUGCODE(bool scrollRectReturnValue = )scrolledBitmap.scrollRect(
                     subset, scrollX * xMult, scrollY * yMult);
diff --git a/gm/copyTo4444.cpp b/gm/copyTo4444.cpp
index 4efe00b..7e2c279 100644
--- a/gm/copyTo4444.cpp
+++ b/gm/copyTo4444.cpp
@@ -40,7 +40,7 @@
             return;
         }
         canvas->drawBitmap(bm, 0, 0);
-        SkAssertResult(bm.copyTo(&bm4444, SkBitmap::kARGB_4444_Config));
+        SkAssertResult(bm.copyTo(&bm4444, kARGB_4444_SkColorType));
         canvas->drawBitmap(bm4444, SkIntToScalar(bm.width()), 0);
     }
 
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index c52c5d8..662e981 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -293,7 +293,7 @@
         // from this method, we should be able to get rid of the
         // transformation to 8888 format also.
         SkBitmap copy;
-        bitmap.copyTo(&copy, SkBitmap::kARGB_8888_Config);
+        bitmap.copyTo(&copy, kPMColor_SkColorType);
         if (!SkImageEncoder::EncodeFile(path.c_str(), copy,
                                         SkImageEncoder::kPNG_Type,
                                         100)) {
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index 80ccd0a..364a1cd 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -14,6 +14,8 @@
 #include "SkPoint.h"
 #include "SkRefCnt.h"
 
+//#define SK_SUPPORT_LEGACY_COPYTO_CONFIG
+
 struct SkMask;
 struct SkIRect;
 struct SkRect;
@@ -618,19 +620,33 @@
     */
     bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
 
-    /** Makes a deep copy of this bitmap, respecting the requested config,
+#ifdef SK_SUPPORT_LEGACY_COPYTO_CONFIG
+    bool copyTo(SkBitmap* dst, Config c, Allocator* allocator) const;
+    bool canCopyTo(Config newConfig) const;
+#endif
+    /** Makes a deep copy of this bitmap, respecting the requested colorType,
      *  and allocating the dst pixels on the cpu.
      *  Returns false if either there is an error (i.e. the src does not have
      *  pixels) or the request cannot be satisfied (e.g. the src has per-pixel
      *  alpha, and the requested config does not support alpha).
      *  @param dst The bitmap to be sized and allocated
-     *  @param c The desired config for dst
+     *  @param ct The desired colorType for dst
      *  @param allocator Allocator used to allocate the pixelref for the dst
      *                   bitmap. If this is null, the standard HeapAllocator
      *                   will be used.
-     *  @return true if the copy could be made.
+     *  @return true if the copy was made.
      */
-    bool copyTo(SkBitmap* dst, Config c, Allocator* allocator = NULL) const;
+    bool copyTo(SkBitmap* dst, SkColorType ct, Allocator* = NULL) const;
+
+    bool copyTo(SkBitmap* dst, Allocator* allocator = NULL) const {
+        return this->copyTo(dst, this->colorType(), allocator);
+    }
+
+    /**
+     *  Returns true if this bitmap's pixels can be converted into the requested
+     *  colorType, such that copyTo() could succeed.
+     */
+    bool canCopyTo(SkColorType colorType) const;
 
     /** Makes a deep copy of this bitmap, respecting the requested config, and
      *  with custom allocation logic that will keep the copied pixels
@@ -653,11 +669,6 @@
      */
     bool deepCopyTo(SkBitmap* dst) const;
 
-    /** Returns true if this bitmap can be deep copied into the requested config
-        by calling copyTo().
-     */
-    bool canCopyTo(Config newConfig) const;
-
     SK_ATTR_DEPRECATED("use setFilterLevel on SkPaint")
     void buildMipMap(bool forceRebuild = false);
 
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index 80ffaaa..c8fbf3d 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -1449,7 +1449,7 @@
 
         SkBaseDevice* device = orig->getDevice();
         SkBitmap bmp;
-        if (device->accessBitmap(false).copyTo(&bmp, SkBitmap::kARGB_8888_Config)) {
+        if (device->accessBitmap(false).copyTo(&bmp, kPMColor_SkColorType)) {
             static int gSampleGrabCounter;
             SkString name;
             name.printf("sample_grab_%d.png", gSampleGrabCounter++);
diff --git a/samplecode/SampleDither.cpp b/samplecode/SampleDither.cpp
index 57c7613..c0ce299 100644
--- a/samplecode/SampleDither.cpp
+++ b/samplecode/SampleDither.cpp
@@ -118,7 +118,7 @@
         make_bm(&fBM);
         make_bm(&fBMPreDither);
         pre_dither(fBMPreDither);
-        fBM.copyTo(&fBM16, SkBitmap::kARGB_4444_Config);
+        fBM.copyTo(&fBM16, kARGB_4444_SkColorType);
 
         fAngle = 0;
 
diff --git a/samplecode/SampleDitherBitmap.cpp b/samplecode/SampleDitherBitmap.cpp
index d6d15e9..a3ebafa 100644
--- a/samplecode/SampleDitherBitmap.cpp
+++ b/samplecode/SampleDitherBitmap.cpp
@@ -84,7 +84,7 @@
     DitherBitmapView() {
         fResult = test_pathregion();
         fBM8 = make_bitmap();
-        fBM8.copyTo(&fBM32, SkBitmap::kARGB_8888_Config);
+        fBM8.copyTo(&fBM32, kPMColor_SkColorType);
 
         this->setBGColor(0xFFDDDDDD);
     }
diff --git a/samplecode/SampleFilter.cpp b/samplecode/SampleFilter.cpp
index 1b26bf2..7b2c551 100644
--- a/samplecode/SampleFilter.cpp
+++ b/samplecode/SampleFilter.cpp
@@ -89,9 +89,9 @@
 
     FilterView() {
         make_bm(&fBM8);
-        fBM8.copyTo(&fBM4444, SkBitmap::kARGB_4444_Config);
-        fBM8.copyTo(&fBM16, SkBitmap::kRGB_565_Config);
-        fBM8.copyTo(&fBM32, SkBitmap::kARGB_8888_Config);
+        fBM8.copyTo(&fBM4444, kARGB_4444_SkColorType);
+        fBM8.copyTo(&fBM16, kRGB_565_SkColorType);
+        fBM8.copyTo(&fBM32, kPMColor_SkColorType);
 
         this->setBGColor(0xFFDDDDDD);
     }
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 520ccd3..32cb7b2 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -982,32 +982,43 @@
 #include "SkCanvas.h"
 #include "SkPaint.h"
 
-bool SkBitmap::canCopyTo(Config dstConfig) const {
-    if (this->config() == kNo_Config) {
+#ifdef SK_SUPPORT_LEGACY_COPYTO_CONFIG
+bool SkBitmap::copyTo(SkBitmap* dst, Config c, Allocator* allocator) const {
+    return this->copyTo(dst, SkBitmapConfigToSkColorType(c), allocator);
+}
+
+bool SkBitmap::canCopyTo(Config newConfig) const {
+    return this->canCopyTo(SkBitmapConfigToSkColorType(c));
+}
+#endif
+
+bool SkBitmap::canCopyTo(SkColorType dstColorType) const {
+    if (this->colorType() == kUnknown_SkColorType) {
         return false;
     }
 
-    bool sameConfigs = (this->config() == dstConfig);
-    switch (dstConfig) {
-        case kA8_Config:
-        case kRGB_565_Config:
-        case kARGB_8888_Config:
+    bool sameConfigs = (this->colorType() == dstColorType);
+    switch (dstColorType) {
+        case kAlpha_8_SkColorType:
+        case kRGB_565_SkColorType:
+        case kPMColor_SkColorType:
             break;
-        case kIndex8_Config:
+        case kIndex_8_SkColorType:
             if (!sameConfigs) {
                 return false;
             }
             break;
-        case kARGB_4444_Config:
-            return sameConfigs || kARGB_8888_Config == this->config();
+        case kARGB_4444_SkColorType:
+            return sameConfigs || kPMColor_SkColorType == this->colorType();
         default:
             return false;
     }
     return true;
 }
 
-bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
-    if (!this->canCopyTo(dstConfig)) {
+bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType,
+                      Allocator* alloc) const {
+    if (!this->canCopyTo(dstColorType)) {
         return false;
     }
 
@@ -1024,7 +1035,7 @@
             SkASSERT(tmpSrc.height() == this->height());
 
             // did we get lucky and we can just return tmpSrc?
-            if (tmpSrc.config() == dstConfig && NULL == alloc) {
+            if (tmpSrc.colorType() == dstColorType && NULL == alloc) {
                 dst->swap(tmpSrc);
                 // If the result is an exact copy, clone the gen ID.
                 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->info()) {
@@ -1047,14 +1058,20 @@
     // The only way to be readyToDraw is if fPixelRef is non NULL.
     SkASSERT(fPixelRef != NULL);
 
+    SkImageInfo dstInfo = src->info();
+    dstInfo.fColorType = dstColorType;
+
     SkBitmap tmpDst;
-    tmpDst.setConfig(dstConfig, src->width(), src->height(), 0,
-                     src->alphaType());
+    if (!tmpDst.setConfig(dstInfo)) {
+        return false;
+    }
 
     // allocate colortable if srcConfig == kIndex8_Config
-    SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
-    new SkColorTable(*src->getColorTable()) : NULL;
-    SkAutoUnref au(ctable);
+    SkAutoTUnref<SkColorTable> ctable;
+    if (dstColorType == kIndex_8_SkColorType) {
+        // TODO: can we just ref() the src colortable? Is it reentrant-safe?
+        ctable.reset(SkNEW_ARGS(SkColorTable, (*src->getColorTable())));
+    }
     if (!tmpDst.allocPixels(alloc, ctable)) {
         return false;
     }
@@ -1070,7 +1087,7 @@
 
     /* do memcpy for the same configs cases, else use drawing
     */
-    if (src->config() == dstConfig) {
+    if (src->colorType() == dstColorType) {
         if (tmpDst.getSize() == src->getSize()) {
             memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
             SkPixelRef* pixelRef = tmpDst.pixelRef();
@@ -1102,8 +1119,8 @@
                 dstP += tmpDst.rowBytes();
             }
         }
-    } else if (SkBitmap::kARGB_4444_Config == dstConfig
-               && SkBitmap::kARGB_8888_Config == src->config()) {
+    } else if (kARGB_4444_SkColorType == dstColorType
+               && kPMColor_SkColorType == src->colorType()) {
         SkASSERT(src->height() == tmpDst.height());
         SkASSERT(src->width() == tmpDst.width());
         for (int y = 0; y < src->height(); ++y) {
@@ -1134,7 +1151,7 @@
 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
     const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig);
 
-    if (!this->canCopyTo(dstConfig)) {
+    if (!this->canCopyTo(dstCT)) {
         return false;
     }
 
@@ -1169,7 +1186,7 @@
     if (this->getTexture()) {
         return false;
     } else {
-        return this->copyTo(dst, dstConfig, NULL);
+        return this->copyTo(dst, dstCT, NULL);
     }
 }
 
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 07ae3df..7ed8058 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -189,9 +189,9 @@
     if (!src.extractSubset(&subset, srcRect)) {
         return false;
     }
-    if (SkBitmap::kARGB_8888_Config != subset.config()) {
+    if (kPMColor_SkColorType != subset.colorType()) {
         // It'd be preferable to do this directly to bitmap.
-        subset.copyTo(&subset, SkBitmap::kARGB_8888_Config);
+        subset.copyTo(&subset, kPMColor_SkColorType);
     }
     SkAutoLockPixels alp(bitmap);
     uint32_t* bmpPixels = reinterpret_cast<uint32_t*>(bitmap.getPixels());
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
index f946f87..4d23658 100644
--- a/src/effects/SkBlurImageFilter.cpp
+++ b/src/effects/SkBlurImageFilter.cpp
@@ -178,7 +178,7 @@
     }
 
     if (kernelSizeX == 0 && kernelSizeY == 0) {
-        src.copyTo(dst, dst->config());
+        src.copyTo(dst, dst->colorType());
         offset->fX = srcBounds.fLeft;
         offset->fY = srcBounds.fTop;
         return true;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index c053e8b..94e4c8c 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -155,7 +155,7 @@
                 return result;
             }
         } else {
-            origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config);
+            origBitmap.copyTo(&tmpBitmap, kPMColor_SkColorType);
             // now bitmap points to our temp, which has been promoted to 32bits
             bitmap = &tmpBitmap;
             desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap->config());
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 0d8ddaa..475f50e 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -59,7 +59,7 @@
 }
 
 bool SkImage_Gpu::getROPixels(SkBitmap* dst) const {
-    return fBitmap.copyTo(dst, SkBitmap::kARGB_8888_Config);
+    return fBitmap.copyTo(dst, kPMColor_SkColorType);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 504943e..abf6dc8 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -127,7 +127,7 @@
         if (!fBitmap.extractSubset(&src, subset)) {
             return false;
         }
-        return src.copyTo(dst, src.config());
+        return src.copyTo(dst, src.colorType());
     }
 }
 
diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp
index 1e28136..7e3bb9b 100644
--- a/src/images/SkDecodingImageGenerator.cpp
+++ b/src/images/SkDecodingImageGenerator.cpp
@@ -14,60 +14,50 @@
 #include "SkStream.h"
 #include "SkUtils.h"
 
+static bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) {
+    return a.width() == b.width() && a.height() == b.height() &&
+           a.colorType() == b.colorType();
+}
+
 namespace {
 /**
  *  Special allocator used by getPixels(). Uses preallocated memory
- *  provided.
+ *  provided if possible, else fall-back on the default allocator
  */
 class TargetAllocator : public SkBitmap::Allocator {
 public:
-    TargetAllocator(void* target,
-                    size_t rowBytes,
-                    int width,
-                    int height,
-                    SkBitmap::Config config)
-        : fTarget(target)
+    TargetAllocator(const SkImageInfo& info,
+                    void* target,
+                    size_t rowBytes)
+        : fInfo(info)
+        , fTarget(target)
         , fRowBytes(rowBytes)
-        , fWidth(width)
-        , fHeight(height)
-        , fConfig(config) { }
+    {}
 
     bool isReady() { return (fTarget != NULL); }
 
     virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) {
-        if ((NULL == fTarget)
-            || (fConfig != bm->config())
-            || (fWidth != bm->width())
-            || (fHeight != bm->height())
-            || (ct != NULL)) {
+        if (NULL == fTarget || !equal_modulo_alpha(fInfo, bm->info())) {
             // Call default allocator.
             return bm->allocPixels(NULL, ct);
         }
-        // make sure fRowBytes is correct.
-        bm->setConfig(fConfig, fWidth, fHeight, fRowBytes, bm->alphaType());
+        
         // TODO(halcanary): verify that all callers of this function
         // will respect new RowBytes.  Will be moot once rowbytes belongs
         // to PixelRef.
-        bm->setPixels(fTarget, NULL);
+        bm->installPixels(fInfo, fTarget, fRowBytes, NULL, NULL);
+
         fTarget = NULL;  // never alloc same pixels twice!
         return true;
     }
 
 private:
+    const SkImageInfo fInfo;
     void* fTarget;  // Block of memory to be supplied as pixel memory
                     // in allocPixelRef.  Must be large enough to hold
-                    // a bitmap described by fWidth, fHeight, and
-                    // fRowBytes.
-    size_t fRowBytes;  // rowbytes for the destination bitmap
-    int fWidth;   // Along with fHeight and fConfig, the information
-    int fHeight;  // about the bitmap whose pixels this allocator is
-                  // expected to allocate. If they do not match the
-                  // bitmap passed to allocPixelRef, it is assumed
-                  // that the bitmap will be copied to a bitmap with
-                  // the correct info using this allocator, so the
-                  // default allocator will be used instead of
-                  // fTarget.
-    SkBitmap::Config fConfig;
+                    // a bitmap described by fInfo and fRowBytes
+    const size_t fRowBytes;  // rowbytes for the destination bitmap
+
     typedef SkBitmap::Allocator INHERITED;
 };
 
@@ -94,14 +84,13 @@
         SkStreamRewindable* stream,
         const SkImageInfo& info,
         int sampleSize,
-        bool ditherImage,
-        SkBitmap::Config requestedConfig)
+        bool ditherImage)
     : fData(data)
     , fStream(stream)
     , fInfo(info)
     , fSampleSize(sampleSize)
     , fDitherImage(ditherImage)
-    , fRequestedConfig(requestedConfig) {
+{
     SkASSERT(stream != NULL);
     SkSafeRef(fData);  // may be NULL.
 }
@@ -151,8 +140,7 @@
         // to change the settings.
         return false;
     }
-    int bpp = SkBitmap::ComputeBytesPerPixel(fRequestedConfig);
-    if (static_cast<size_t>(bpp * info.fWidth) > rowBytes) {
+    if (info.minRowBytes() > rowBytes) {
         // The caller has specified a bad rowBytes.
         return false;
     }
@@ -166,10 +154,11 @@
     decoder->setSampleSize(fSampleSize);
 
     SkBitmap bitmap;
-    TargetAllocator allocator(pixels, rowBytes, info.fWidth,
-                              info.fHeight, fRequestedConfig);
+    TargetAllocator allocator(fInfo, pixels, rowBytes);
     decoder->setAllocator(&allocator);
-    bool success = decoder->decode(fStream, &bitmap, fRequestedConfig,
+    // TODO: need to be able to pass colortype directly to decoder
+    SkBitmap::Config legacyConfig = SkColorTypeToBitmapConfig(info.colorType());
+    bool success = decoder->decode(fStream, &bitmap, legacyConfig,
                                    SkImageDecoder::kDecodePixels_Mode);
     decoder->setAllocator(NULL);
     if (!success) {
@@ -177,16 +166,16 @@
     }
     if (allocator.isReady()) {  // Did not use pixels!
         SkBitmap bm;
-        SkASSERT(bitmap.canCopyTo(fRequestedConfig));
-        if (!bitmap.copyTo(&bm, fRequestedConfig, &allocator)
-            || allocator.isReady()) {
+        SkASSERT(bitmap.canCopyTo(info.colorType()));
+        bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator);
+        if (!copySuccess || allocator.isReady()) {
             SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed.");
             // Earlier we checked canCopyto(); we expect consistency.
             return false;
         }
-        SkASSERT(check_alpha(fInfo.fAlphaType, bm.alphaType()));
+        SkASSERT(check_alpha(info.alphaType(), bm.alphaType()));
     } else {
-        SkASSERT(check_alpha(fInfo.fAlphaType, bitmap.alphaType()));
+        SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType()));
     }
     return true;
 }
@@ -245,38 +234,23 @@
         return NULL;
     }
 
-    SkImageInfo info;
-    SkBitmap::Config config;
+    SkImageInfo info = bitmap.info();
 
     if (!opts.fUseRequestedColorType) {
-        // Use default config.
-        if (SkBitmap::kIndex8_Config == bitmap.config()) {
+        // Use default
+        if (kIndex_8_SkColorType == bitmap.colorType()) {
             // We don't support kIndex8 because we don't support
             // colortables in this workflow.
-            config = SkBitmap::kARGB_8888_Config;
-            info.fWidth = bitmap.width();
-            info.fHeight = bitmap.height();
             info.fColorType = kPMColor_SkColorType;
-            info.fAlphaType = bitmap.alphaType();
-        } else {
-            config = bitmap.config();  // Save for later!
-            if (!bitmap.asImageInfo(&info)) {
-                SkDEBUGFAIL("Getting SkImageInfo from bitmap failed.");
-                return NULL;
-            }
         }
     } else {
-        config = SkColorTypeToBitmapConfig(opts.fRequestedColorType);
-        if (!bitmap.canCopyTo(config)) {
-            SkASSERT(bitmap.config() != config);
+        if (!bitmap.canCopyTo(opts.fRequestedColorType)) {
+            SkASSERT(bitmap.colorType() != opts.fRequestedColorType);
             return NULL;  // Can not translate to needed config.
         }
-        info.fWidth = bitmap.width();
-        info.fHeight = bitmap.height();
         info.fColorType = opts.fRequestedColorType;
-        info.fAlphaType = bitmap.alphaType();
     }
     return SkNEW_ARGS(SkDecodingImageGenerator,
                       (data, autoStream.detach(), info,
-                       opts.fSampleSize, opts.fDitherImage, config));
+                       opts.fSampleSize, opts.fDitherImage));
 }
diff --git a/src/images/SkDecodingImageGenerator.h b/src/images/SkDecodingImageGenerator.h
index 12a49d5..fef7c6c 100644
--- a/src/images/SkDecodingImageGenerator.h
+++ b/src/images/SkDecodingImageGenerator.h
@@ -113,13 +113,12 @@
     const SkImageInfo      fInfo;
     const int              fSampleSize;
     const bool             fDitherImage;
-    const SkBitmap::Config fRequestedConfig;
+
     SkDecodingImageGenerator(SkData* data,
                              SkStreamRewindable* stream,
                              const SkImageInfo& info,
                              int sampleSize,
-                             bool ditherImage,
-                             SkBitmap::Config requestedConfig);
+                             bool ditherImage);
     static SkImageGenerator* Create(SkData*, SkStreamRewindable*,
                                     const Options&);
     typedef SkImageGenerator INHERITED;
diff --git a/src/ports/SkImageDecoder_CG.cpp b/src/ports/SkImageDecoder_CG.cpp
index 90c282d..c61ce98 100644
--- a/src/ports/SkImageDecoder_CG.cpp
+++ b/src/ports/SkImageDecoder_CG.cpp
@@ -208,8 +208,8 @@
             // format.
             // <Error>: CGImageDestinationFinalize image destination does not have enough images
             // So instead we copy to 8888.
-            if (bm.config() == SkBitmap::kARGB_4444_Config) {
-                bm.copyTo(&bitmap8888, SkBitmap::kARGB_8888_Config);
+            if (bm.colorType() == kARGB_4444_SkColorType) {
+                bm.copyTo(&bitmap8888, kPMColor_SkColorType);
                 bmPtr = &bitmap8888;
             }
             type = kUTTypePNG;
diff --git a/src/utils/SkBitmapHasher.cpp b/src/utils/SkBitmapHasher.cpp
index 9f0affd..6c861cd 100644
--- a/src/utils/SkBitmapHasher.cpp
+++ b/src/utils/SkBitmapHasher.cpp
@@ -57,7 +57,7 @@
     // Hmm, that didn't work. Maybe if we create a new
     // kARGB_8888_Config version of the bitmap it will work better?
     SkBitmap copyBitmap;
-    if (!bitmap.copyTo(&copyBitmap, SkBitmap::kARGB_8888_Config)) {
+    if (!bitmap.copyTo(&copyBitmap, kPMColor_SkColorType)) {
         return false;
     }
     return ComputeDigestInternal(copyBitmap, result);
diff --git a/src/utils/mac/SkCreateCGImageRef.cpp b/src/utils/mac/SkCreateCGImageRef.cpp
index 01f2dac..7687c3c 100644
--- a/src/utils/mac/SkCreateCGImageRef.cpp
+++ b/src/utils/mac/SkCreateCGImageRef.cpp
@@ -94,7 +94,7 @@
         copy = new SkBitmap;
         // here we make a ceep copy of the pixels, since CG won't take our
         // 565 directly
-        bm.copyTo(copy, SkBitmap::kARGB_8888_Config);
+        bm.copyTo(copy, kPMColor_SkColorType);
     } else {
         copy = new SkBitmap(bm);
     }
diff --git a/tests/BitmapCopyTest.cpp b/tests/BitmapCopyTest.cpp
index 57ac950..db03e5c 100644
--- a/tests/BitmapCopyTest.cpp
+++ b/tests/BitmapCopyTest.cpp
@@ -13,37 +13,37 @@
 }
 
 // these are in the same order as the SkBitmap::Config enum
-static const char* gConfigName[] = {
-    "None", "A8", "Index8", "565", "4444", "8888"
+static const char* gColorTypeName[] = {
+    "None", "A8", "565", "4444", "RGBA", "BGRA", "Index8"
 };
 
 static void report_opaqueness(skiatest::Reporter* reporter, const SkBitmap& src,
                               const SkBitmap& dst) {
     ERRORF(reporter, "src %s opaque:%d, dst %s opaque:%d",
-           gConfigName[src.config()], src.isOpaque(),
-           gConfigName[dst.config()], dst.isOpaque());
+           gColorTypeName[src.colorType()], src.isOpaque(),
+           gColorTypeName[dst.colorType()], dst.isOpaque());
 }
 
-static bool canHaveAlpha(SkBitmap::Config config) {
-    return config != SkBitmap::kRGB_565_Config;
+static bool canHaveAlpha(SkColorType ct) {
+    return kRGB_565_SkColorType != ct;
 }
 
 // copyTo() should preserve isOpaque when it makes sense
 static void test_isOpaque(skiatest::Reporter* reporter,
                           const SkBitmap& srcOpaque, const SkBitmap& srcPremul,
-                          SkBitmap::Config dstConfig) {
+                          SkColorType dstColorType) {
     SkBitmap dst;
 
-    if (canHaveAlpha(srcPremul.config()) && canHaveAlpha(dstConfig)) {
-        REPORTER_ASSERT(reporter, srcPremul.copyTo(&dst, dstConfig));
-        REPORTER_ASSERT(reporter, dst.config() == dstConfig);
+    if (canHaveAlpha(srcPremul.colorType()) && canHaveAlpha(dstColorType)) {
+        REPORTER_ASSERT(reporter, srcPremul.copyTo(&dst, dstColorType));
+        REPORTER_ASSERT(reporter, dst.colorType() == dstColorType);
         if (srcPremul.isOpaque() != dst.isOpaque()) {
             report_opaqueness(reporter, srcPremul, dst);
         }
     }
 
-    REPORTER_ASSERT(reporter, srcOpaque.copyTo(&dst, dstConfig));
-    REPORTER_ASSERT(reporter, dst.config() == dstConfig);
+    REPORTER_ASSERT(reporter, srcOpaque.copyTo(&dst, dstColorType));
+    REPORTER_ASSERT(reporter, dst.colorType() == dstColorType);
     if (srcOpaque.isOpaque() != dst.isOpaque()) {
         report_opaqueness(reporter, srcOpaque, dst);
     }
@@ -68,8 +68,8 @@
 }
 
 struct Pair {
-    SkBitmap::Config    fConfig;
-    const char*         fValid;
+    SkColorType fColorType;
+    const char* fValid;
 };
 
 // Utility functions for copyPixelsTo()/copyPixelsFrom() tests.
@@ -199,30 +199,30 @@
 }
 
 static const Pair gPairs[] = {
-    { SkBitmap::kNo_Config,         "0000000"  },
-    { SkBitmap::kA8_Config,         "0101010"  },
-    { SkBitmap::kIndex8_Config,     "0111010"  },
-    { SkBitmap::kRGB_565_Config,    "0101010"  },
-    { SkBitmap::kARGB_4444_Config,  "0101110"  },
-    { SkBitmap::kARGB_8888_Config,  "0101110"  },
+    { kUnknown_SkColorType,     "000000"  },
+    { kAlpha_8_SkColorType,     "010101"  },
+    { kIndex_8_SkColorType,     "011101"  },
+    { kRGB_565_SkColorType,     "010101"  },
+    { kARGB_4444_SkColorType,   "010111"  },
+    { kPMColor_SkColorType,     "010111"  },
 };
 
 static const int W = 20;
 static const int H = 33;
 
 static void setup_src_bitmaps(SkBitmap* srcOpaque, SkBitmap* srcPremul,
-                              SkBitmap::Config config) {
+                              SkColorType ct) {
     SkColorTable* ctOpaque = NULL;
     SkColorTable* ctPremul = NULL;
-
-    srcOpaque->setConfig(config, W, H, 0, kOpaque_SkAlphaType);
-    srcPremul->setConfig(config, W, H, 0, kPremul_SkAlphaType);
-    if (SkBitmap::kIndex8_Config == config) {
+    if (kIndex_8_SkColorType == ct) {
         ctOpaque = init_ctable(kOpaque_SkAlphaType);
         ctPremul = init_ctable(kPremul_SkAlphaType);
     }
-    srcOpaque->allocPixels(ctOpaque);
-    srcPremul->allocPixels(ctPremul);
+
+    srcOpaque->allocPixels(SkImageInfo::Make(W, H, ct, kOpaque_SkAlphaType),
+                           NULL, ctOpaque);
+    srcPremul->allocPixels(SkImageInfo::Make(W, H, ct, kPremul_SkAlphaType),
+                           NULL, ctPremul);
     SkSafeUnref(ctOpaque);
     SkSafeUnref(ctPremul);
     init_src(*srcOpaque);
@@ -232,7 +232,7 @@
 DEF_TEST(BitmapCopy_extractSubset, reporter) {
     for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
         SkBitmap srcOpaque, srcPremul;
-        setup_src_bitmaps(&srcOpaque, &srcPremul, gPairs[i].fConfig);
+        setup_src_bitmaps(&srcOpaque, &srcPremul, gPairs[i].fColorType);
 
         SkBitmap bitmap(srcOpaque);
         SkBitmap subset;
@@ -241,7 +241,8 @@
         // catches a bug where we cloned the genID incorrectly.
         r.set(0, 1, W, 3);
         bitmap.setIsVolatile(true);
-        if (bitmap.extractSubset(&subset, r)) {
+        // Relies on old behavior of extractSubset failing if colortype is unknown
+        if (kUnknown_SkColorType != bitmap.colorType() && bitmap.extractSubset(&subset, r)) {
             REPORTER_ASSERT(reporter, subset.width() == W);
             REPORTER_ASSERT(reporter, subset.height() == 2);
             REPORTER_ASSERT(reporter, subset.alphaType() == bitmap.alphaType());
@@ -250,11 +251,11 @@
             // Test copying an extracted subset.
             for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) {
                 SkBitmap copy;
-                bool success = subset.copyTo(&copy, gPairs[j].fConfig);
+                bool success = subset.copyTo(&copy, gPairs[j].fColorType);
                 if (!success) {
                     // Skip checking that success matches fValid, which is redundant
                     // with the code below.
-                    REPORTER_ASSERT(reporter, gPairs[i].fConfig != gPairs[j].fConfig);
+                    REPORTER_ASSERT(reporter, gPairs[i].fColorType != gPairs[j].fColorType);
                     continue;
                 }
 
@@ -265,7 +266,7 @@
                 REPORTER_ASSERT(reporter, copy.width() == W);
                 REPORTER_ASSERT(reporter, copy.height() == 2);
 
-                if (gPairs[i].fConfig == gPairs[j].fConfig) {
+                if (gPairs[i].fColorType == gPairs[j].fColorType) {
                     SkAutoLockPixels alp0(subset);
                     SkAutoLockPixels alp1(copy);
                     // they should both have, or both not-have, a colortable
@@ -291,31 +292,31 @@
 
     for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
         SkBitmap srcOpaque, srcPremul;
-        setup_src_bitmaps(&srcOpaque, &srcPremul, gPairs[i].fConfig);
+        setup_src_bitmaps(&srcOpaque, &srcPremul, gPairs[i].fColorType);
 
         for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) {
             SkBitmap dst;
 
-            bool success = srcPremul.copyTo(&dst, gPairs[j].fConfig);
+            bool success = srcPremul.copyTo(&dst, gPairs[j].fColorType);
             bool expected = gPairs[i].fValid[j] != '0';
             if (success != expected) {
                 ERRORF(reporter, "SkBitmap::copyTo from %s to %s. expected %s "
-                       "returned %s", gConfigName[i], gConfigName[j],
+                       "returned %s", gColorTypeName[i], gColorTypeName[j],
                        boolStr(expected), boolStr(success));
             }
 
-            bool canSucceed = srcPremul.canCopyTo(gPairs[j].fConfig);
+            bool canSucceed = srcPremul.canCopyTo(gPairs[j].fColorType);
             if (success != canSucceed) {
                 ERRORF(reporter, "SkBitmap::copyTo from %s to %s. returned %s "
-                       "canCopyTo %s", gConfigName[i], gConfigName[j],
+                       "canCopyTo %s", gColorTypeName[i], gColorTypeName[j],
                        boolStr(success), boolStr(canSucceed));
             }
 
             if (success) {
                 REPORTER_ASSERT(reporter, srcPremul.width() == dst.width());
                 REPORTER_ASSERT(reporter, srcPremul.height() == dst.height());
-                REPORTER_ASSERT(reporter, dst.config() == gPairs[j].fConfig);
-                test_isOpaque(reporter, srcOpaque, srcPremul, dst.config());
+                REPORTER_ASSERT(reporter, dst.colorType() == gPairs[j].fColorType);
+                test_isOpaque(reporter, srcOpaque, srcPremul, dst.colorType());
                 if (srcPremul.config() == dst.config()) {
                     SkAutoLockPixels srcLock(srcPremul);
                     SkAutoLockPixels dstLock(dst);
@@ -351,8 +352,9 @@
             // Test with a very large configuration without pixel buffer
             // attached.
             SkBitmap tstSafeSize;
-            tstSafeSize.setConfig(gPairs[i].fConfig, 100000000U,
-                                  100000000U);
+            tstSafeSize.setConfig(SkImageInfo::Make(100000000U, 100000000U,
+                                                    gPairs[i].fColorType,
+                                                    kPremul_SkAlphaType));
             int64_t safeSize = tstSafeSize.computeSafeSize64();
             if (safeSize < 0) {
                 ERRORF(reporter, "getSafeSize64() negative: %s",
@@ -360,25 +362,25 @@
             }
             bool sizeFail = false;
             // Compare against hand-computed values.
-            switch (gPairs[i].fConfig) {
-                case SkBitmap::kNo_Config:
+            switch (gPairs[i].fColorType) {
+                case kUnknown_SkColorType:
                     break;
 
-                case SkBitmap::kA8_Config:
-                case SkBitmap::kIndex8_Config:
+                case kAlpha_8_SkColorType:
+                case kIndex_8_SkColorType:
                     if (safeSize != 0x2386F26FC10000LL) {
                         sizeFail = true;
                     }
                     break;
 
-                case SkBitmap::kRGB_565_Config:
-                case SkBitmap::kARGB_4444_Config:
+                case kRGB_565_SkColorType:
+                case kARGB_4444_SkColorType:
                     if (safeSize != 0x470DE4DF820000LL) {
                         sizeFail = true;
                     }
                     break;
 
-                case SkBitmap::kARGB_8888_Config:
+                case kPMColor_SkColorType:
                     if (safeSize != 0x8E1BC9BF040000LL) {
                         sizeFail = true;
                     }
@@ -398,22 +400,28 @@
             // Create bitmap to act as source for copies and subsets.
             SkBitmap src, subset;
             SkColorTable* ct = NULL;
-            if (isExtracted[copyCase]) { // A larger image to extract from.
-                src.setConfig(gPairs[i].fConfig, 2 * subW + 1, subH);
-            } else { // Tests expect a 2x2 bitmap, so make smaller.
-                src.setConfig(gPairs[i].fConfig, subW, subH);
-            }
             if (SkBitmap::kIndex8_Config == src.config()) {
                 ct = init_ctable(kPremul_SkAlphaType);
             }
 
-            src.allocPixels(ct);
+            if (isExtracted[copyCase]) { // A larger image to extract from.
+                src.allocPixels(SkImageInfo::Make(2 * subW + 1, subH,
+                                                  gPairs[i].fColorType,
+                                                  kPremul_SkAlphaType));
+            } else { // Tests expect a 2x2 bitmap, so make smaller.
+                src.allocPixels(SkImageInfo::Make(subW, subH,
+                                                  gPairs[i].fColorType,
+                                                  kPremul_SkAlphaType));
+            }
             SkSafeUnref(ct);
 
             // Either copy src or extract into 'subset', which is used
             // for subsequent calls to copyPixelsTo/From.
             bool srcReady = false;
-            if (isExtracted[copyCase]) {
+            // Test relies on older behavior that extractSubset will fail on
+            // no_config
+            if (kUnknown_SkColorType != src.colorType() &&
+                isExtracted[copyCase]) {
                 // The extractedSubset() test case allows us to test copy-
                 // ing when src and dst mave possibly different strides.
                 SkIRect r;
@@ -421,7 +429,7 @@
 
                 srcReady = src.extractSubset(&subset, r);
             } else {
-                srcReady = src.copyTo(&subset, src.config());
+                srcReady = src.copyTo(&subset);
             }
 
             // Not all configurations will generate a valid 'subset'.
@@ -454,13 +462,14 @@
 
                 // Test #1 ////////////////////////////////////////////
 
+                const SkImageInfo info = SkImageInfo::Make(subW, subH,
+                                                           gPairs[i].fColorType,
+                                                           kPremul_SkAlphaType);
                 // Before/after comparisons easier if we attach buf
                 // to an appropriately configured SkBitmap.
                 memset(buf, 0xFF, bufSize);
                 // Config with stride greater than src but that fits in buf.
-                bufBm.setConfig(gPairs[i].fConfig, subW, subH,
-                    SkBitmap::ComputeRowBytes(subset.config(), subW) * 2);
-                bufBm.setPixels(buf);
+                bufBm.installPixels(info, buf, info.minRowBytes() * 2);
                 successExpected = false;
                 // Then attempt to copy with a stride that is too large
                 // to fit in the buffer.
@@ -479,9 +488,7 @@
                 // issue of getSafeSize(). Without getSafeSize()
                 // buffer overrun/read would occur.
                 memset(buf, 0xFF, bufSize);
-                bufBm.setConfig(gPairs[i].fConfig, subW, subH,
-                                subset.rowBytes());
-                bufBm.setPixels(buf);
+                bufBm.installPixels(info, buf, subset.rowBytes());
                 successExpected = subset.getSafeSize() <= bufSize;
                 REPORTER_ASSERT(reporter,
                     subset.copyPixelsTo(buf, bufSize) ==
@@ -493,9 +500,7 @@
                 // Test #3 ////////////////////////////////////////////
                 // Copy with different stride between src and dst.
                 memset(buf, 0xFF, bufSize);
-                bufBm.setConfig(gPairs[i].fConfig, subW, subH,
-                                subset.rowBytes()+1);
-                bufBm.setPixels(buf);
+                bufBm.installPixels(info, buf, subset.rowBytes()+1);
                 successExpected = true; // Should always work.
                 REPORTER_ASSERT(reporter,
                         subset.copyPixelsTo(buf, bufSize,
@@ -507,8 +512,7 @@
                 // Test #4 ////////////////////////////////////////////
                 // Test copy with stride too small.
                 memset(buf, 0xFF, bufSize);
-                bufBm.setConfig(gPairs[i].fConfig, subW, subH);
-                bufBm.setPixels(buf);
+                bufBm.installPixels(info, buf, info.minRowBytes());
                 successExpected = false;
                 // Request copy with stride too small.
                 REPORTER_ASSERT(reporter,
@@ -523,8 +527,7 @@
                 // Tests the case where the source stride is too small
                 // for the source configuration.
                 memset(buf, 0xFF, bufSize);
-                bufBm.setConfig(gPairs[i].fConfig, subW, subH);
-                bufBm.setPixels(buf);
+                bufBm.installPixels(info, buf, info.minRowBytes());
                 writeCoordPixels(bufBm, coords);
                 REPORTER_ASSERT(reporter,
                     subset.copyPixelsFrom(buf, bufSize, 1) == false);
@@ -535,8 +538,7 @@
                 // where the source stride is different from the dest.
                 // stride.
                 // We've made the buffer large enough to always succeed.
-                bufBm.setConfig(gPairs[i].fConfig, subW, subH);
-                bufBm.setPixels(buf);
+                bufBm.installPixels(info, buf, info.minRowBytes());
                 writeCoordPixels(bufBm, coords);
                 REPORTER_ASSERT(reporter,
                     subset.copyPixelsFrom(buf, bufSize, bufBm.rowBytes()) ==
diff --git a/tests/GpuBitmapCopyTest.cpp b/tests/GpuBitmapCopyTest.cpp
index d5485bb..af3fbda 100644
--- a/tests/GpuBitmapCopyTest.cpp
+++ b/tests/GpuBitmapCopyTest.cpp
@@ -24,31 +24,31 @@
 }
 
 // these are in the same order as the SkBitmap::Config enum
-static const char* gConfigName[] = {
+static const char* gColorTypeName[] = {
     "None", "8888"
 };
 
 struct Pair {
-    SkBitmap::Config    fConfig;
-    const char*         fValid;
+    SkColorType fColorType;
+    const char* fValid;
 };
 
 /**
  *  Check to ensure that copying a GPU-backed SkBitmap behaved as expected.
  *  @param reporter Used to report failures.
- *  @param desiredConfig Config being copied to. If the copy succeeded, dst must have this Config.
+ *  @param desiredCT colorType being copied to. If the copy succeeded, dst must have this Config.
  *  @param success True if the copy succeeded.
  *  @param src A GPU-backed SkBitmap that had copyTo or deepCopyTo called on it.
  *  @param dst SkBitmap that was copied to.
  *  @param expectSameGenID Whether the genIDs should be the same if success is true.
  */
-static void TestIndividualCopy(skiatest::Reporter* reporter, const SkBitmap::Config desiredConfig,
+static void TestIndividualCopy(skiatest::Reporter* reporter, const SkColorType desiredCT,
                                const bool success, const SkBitmap& src, const SkBitmap& dst,
                                const bool expectSameGenID) {
     if (success) {
         REPORTER_ASSERT(reporter, src.width() == dst.width());
         REPORTER_ASSERT(reporter, src.height() == dst.height());
-        REPORTER_ASSERT(reporter, dst.config() == desiredConfig);
+        REPORTER_ASSERT(reporter, dst.colorType() == desiredCT);
         if (src.config() == dst.config()) {
             if (expectSameGenID) {
                 REPORTER_ASSERT(reporter, src.getGenerationID() == dst.getGenerationID());
@@ -75,7 +75,7 @@
                 REPORTER_ASSERT(reporter, readBack);
             } else {
                 // If dst is not a texture, do a copy instead, to the same config as srcReadBack.
-                bool copy = dst.copyTo(&dstReadBack, srcReadBack.config());
+                bool copy = dst.copyTo(&dstReadBack, srcReadBack.colorType());
                 REPORTER_ASSERT(reporter, copy);
             }
 
@@ -133,7 +133,7 @@
             //
 //            { SkBitmap::kNo_Config,         "00"  },
 //            { SkBitmap::kARGB_8888_Config,  "01"  },
-            { SkBitmap::kARGB_8888_Config,  "1"  },
+            { kPMColor_SkColorType,  "1"  },
         };
 
         const int W = 20;
@@ -141,7 +141,7 @@
 
         for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
             SkImageInfo info = SkImageInfo::Make(W, H,
-                                                 SkBitmapConfigToColorType(gPairs[i].fConfig),
+                                                 gPairs[i].fColorType,
                                                  kPremul_SkAlphaType);
             SkBitmap src, dst;
 
@@ -165,41 +165,42 @@
             const bool extracted = src.extractSubset(&subset, subsetRect);
 
             for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) {
+                SkBitmap::Config pairsConfig = SkColorTypeToBitmapConfig(gPairs[j].fColorType);
                 dst.reset();
-                bool success = src.deepCopyTo(&dst, gPairs[j].fConfig);
+                bool success = src.deepCopyTo(&dst, pairsConfig);
                 bool expected = gPairs[i].fValid[j] != '0';
                 if (success != expected) {
                     ERRORF(reporter, "SkBitmap::deepCopyTo from %s to %s. "
-                           "expected %s returned %s", gConfigName[i],
-                           gConfigName[j], boolStr(expected),
+                           "expected %s returned %s", gColorTypeName[i],
+                           gColorTypeName[j], boolStr(expected),
                            boolStr(success));
                 }
 
-                bool canSucceed = src.canCopyTo(gPairs[j].fConfig);
+                bool canSucceed = src.canCopyTo(gPairs[j].fColorType);
                 if (success != canSucceed) {
                     ERRORF(reporter, "SkBitmap::deepCopyTo from %s to %s "
                            "returned %s, but canCopyTo returned %s",
-                           gConfigName[i], gConfigName[j], boolStr(success),
+                           gColorTypeName[i], gColorTypeName[j], boolStr(success),
                            boolStr(canSucceed));
                 }
 
-                TestIndividualCopy(reporter, gPairs[j].fConfig, success, src, dst, true);
+                TestIndividualCopy(reporter, gPairs[j].fColorType, success, src, dst, true);
 
                 // Test copying the subset bitmap, using both copyTo and deepCopyTo.
                 if (extracted) {
                     SkBitmap subsetCopy;
-                    success = subset.copyTo(&subsetCopy, gPairs[j].fConfig);
+                    success = subset.copyTo(&subsetCopy, gPairs[j].fColorType);
                     REPORTER_ASSERT(reporter, success == expected);
                     REPORTER_ASSERT(reporter, success == canSucceed);
-                    TestIndividualCopy(reporter, gPairs[j].fConfig, success, subset, subsetCopy,
+                    TestIndividualCopy(reporter, gPairs[j].fColorType, success, subset, subsetCopy,
                                        true);
 
                     // Reset the bitmap so that a failed copyTo will leave it in the expected state.
                     subsetCopy.reset();
-                    success = subset.deepCopyTo(&subsetCopy, gPairs[j].fConfig);
+                    success = subset.deepCopyTo(&subsetCopy, pairsConfig);
                     REPORTER_ASSERT(reporter, success == expected);
                     REPORTER_ASSERT(reporter, success == canSucceed);
-                    TestIndividualCopy(reporter, gPairs[j].fConfig, success, subset, subsetCopy,
+                    TestIndividualCopy(reporter, gPairs[j].fColorType, success, subset, subsetCopy,
                                        true);
 
                     // Now set a bitmap to be a subset that will share the same pixelref.
@@ -209,23 +210,24 @@
                     SkBitmap trueSubset;
                     // FIXME: Once https://codereview.chromium.org/109023008/ lands, call
                     // trueSubset.installPixelRef(src.pixelRef(), subset);
-                    trueSubset.setConfig(gPairs[i].fConfig, W/2, H/2);
+                    trueSubset.setConfig(SkImageInfo::Make(W/2, H/2, gPairs[i].fColorType,
+                                                           kPremul_SkAlphaType));
                     trueSubset.setPixelRef(src.pixelRef(), W/2, H/2);
 
                     subsetCopy.reset();
-                    success = trueSubset.copyTo(&subsetCopy, gPairs[j].fConfig);
+                    success = trueSubset.copyTo(&subsetCopy, gPairs[j].fColorType);
                     REPORTER_ASSERT(reporter, success == expected);
                     REPORTER_ASSERT(reporter, success == canSucceed);
-                    TestIndividualCopy(reporter, gPairs[j].fConfig, success, trueSubset, subsetCopy,
+                    TestIndividualCopy(reporter, gPairs[j].fColorType, success, trueSubset, subsetCopy,
                                        false);
 
                     // deepCopyTo copies the entire pixelref, even if the bitmap only represents
                     // a subset. Therefore, the result should share the same genID.
                     subsetCopy.reset();
-                    success = trueSubset.deepCopyTo(&subsetCopy, gPairs[j].fConfig);
+                    success = trueSubset.deepCopyTo(&subsetCopy, pairsConfig);
                     REPORTER_ASSERT(reporter, success == expected);
                     REPORTER_ASSERT(reporter, success == canSucceed);
-                    TestIndividualCopy(reporter, gPairs[j].fConfig, success, trueSubset, subsetCopy,
+                    TestIndividualCopy(reporter, gPairs[j].fColorType, success, trueSubset, subsetCopy,
                                        true);
                 }
             } // for (size_t j = ...
diff --git a/tools/CopyTilesRenderer.cpp b/tools/CopyTilesRenderer.cpp
index d3f266b..1298d43 100644
--- a/tools/CopyTilesRenderer.cpp
+++ b/tools/CopyTilesRenderer.cpp
@@ -70,7 +70,7 @@
                                 dst.pixelRef()->readPixels(&copy, &subset);
                             } else {
 #endif
-                                dst.copyTo(&copy, dst.config());
+                                dst.copyTo(&copy);
 #if SK_SUPPORT_GPU
                             }
 #endif
diff --git a/tools/skdiff_utils.cpp b/tools/skdiff_utils.cpp
index 6f73a08..2f05239 100644
--- a/tools/skdiff_utils.cpp
+++ b/tools/skdiff_utils.cpp
@@ -85,7 +85,7 @@
 
 bool write_bitmap(const SkString& path, const SkBitmap& bitmap) {
     SkBitmap copy;
-    bitmap.copyTo(&copy, SkBitmap::kARGB_8888_Config);
+    bitmap.copyTo(&copy, kPMColor_SkColorType);
     force_all_opaque(copy);
     return SkImageEncoder::EncodeFile(path.c_str(), copy,
                                       SkImageEncoder::kPNG_Type, 100);
diff --git a/tools/skimage_main.cpp b/tools/skimage_main.cpp
index f5a2b3d..d34d57c 100644
--- a/tools/skimage_main.cpp
+++ b/tools/skimage_main.cpp
@@ -164,7 +164,7 @@
         return true;
     }
 
-    if (bm.config() == SkBitmap::kARGB_8888_Config) {
+    if (bm.colorType() == kPMColor_SkColorType) {
         // First attempt at encoding failed, and the bitmap was already 8888. Making
         // a copy is not going to help.
         return false;
@@ -172,7 +172,7 @@
 
     // Encoding failed. Copy to 8888 and try again.
     SkBitmap bm8888;
-    if (!bm.copyTo(&bm8888, SkBitmap::kARGB_8888_Config)) {
+    if (!bm.copyTo(&bm8888, kPMColor_SkColorType)) {
         return false;
     }
     return SkImageEncoder::EncodeFile(filename.c_str(), bm8888, SkImageEncoder::kPNG_Type, 100);
diff --git a/tools/skpdiff/SkDiffContext.cpp b/tools/skpdiff/SkDiffContext.cpp
index df1c93d..b9c55c1 100644
--- a/tools/skpdiff/SkDiffContext.cpp
+++ b/tools/skpdiff/SkDiffContext.cpp
@@ -122,7 +122,7 @@
 
             // compute the image diff and output it
             SkBitmap copy;
-            diffData.fResult.poiAlphaMask.copyTo(&copy, SkBitmap::kARGB_8888_Config);
+            diffData.fResult.poiAlphaMask.copyTo(&copy, kPMColor_SkColorType);
             SkImageEncoder::EncodeFile(newRecord->fDifferencePath.c_str(), copy,
                                        SkImageEncoder::kPNG_Type, 100);
 
diff --git a/tools/skpdiff/SkPMetric.cpp b/tools/skpdiff/SkPMetric.cpp
index 22337d8..ed80763 100644
--- a/tools/skpdiff/SkPMetric.cpp
+++ b/tools/skpdiff/SkPMetric.cpp
@@ -125,8 +125,8 @@
 /// Converts a 8888 bitmap to LAB color space and puts it into the output
 static bool bitmap_to_cielab(const SkBitmap* bitmap, ImageLAB* outImageLAB) {
     SkBitmap bm8888;
-    if (bitmap->config() != SkBitmap::kARGB_8888_Config) {
-        if (!bitmap->copyTo(&bm8888, SkBitmap::kARGB_8888_Config)) {
+    if (bitmap->colorType() != kPMColor_SkColorType) {
+        if (!bitmap->copyTo(&bm8888, kPMColor_SkColorType)) {
             return false;
         }
         bitmap = &bm8888;