Add function for creating ASTC blitter

R=robertphillips@google.com

Author: krajcevski@google.com

Review URL: https://codereview.chromium.org/427693002
diff --git a/src/utils/SkTextureCompressor.cpp b/src/utils/SkTextureCompressor.cpp
index 40c0d3e..43d906a 100644
--- a/src/utils/SkTextureCompressor.cpp
+++ b/src/utils/SkTextureCompressor.cpp
@@ -122,6 +122,9 @@
         case kR11_EAC_Format:
             return CreateR11EACBlitter(width, height, compressedBuffer);
 
+        case kASTC_12x12_Format:
+            return CreateASTCBlitter(width, height, compressedBuffer);
+
         default:
             return NULL;
     }
diff --git a/src/utils/SkTextureCompressor_ASTC.cpp b/src/utils/SkTextureCompressor_ASTC.cpp
index 774fd15..402588e 100644
--- a/src/utils/SkTextureCompressor_ASTC.cpp
+++ b/src/utils/SkTextureCompressor_ASTC.cpp
@@ -6,6 +6,7 @@
  */
 
 #include "SkTextureCompressor_ASTC.h"
+#include "SkTextureCompressor_Blitter.h"
 
 #include "SkBlitter.h"
 #include "SkEndian.h"
@@ -132,13 +133,17 @@
 
 // Returns the alpha value of a texel at position (x, y) from src.
 // (x, y) are assumed to be in the range [0, 12).
-static inline uint8_t get_alpha(const uint8_t *src, int rowBytes, int x, int y) {
+inline uint8_t GetAlpha(const uint8_t *src, int rowBytes, int x, int y) {
     SkASSERT(x >= 0 && x < 12);
     SkASSERT(y >= 0 && y < 12);
     SkASSERT(rowBytes >= 12);
     return *(src + y*rowBytes + x);
 }
 
+inline uint8_t GetAlphaTranspose(const uint8_t *src, int rowBytes, int x, int y) {
+    return GetAlpha(src, rowBytes, y, x);
+}
+
 // Output the 16 bytes stored in top and bottom and advance the pointer. The bytes
 // are stored as the integers are represented in memory, so they should be swapped
 // if necessary.
@@ -151,6 +156,9 @@
 
 // Compresses an ASTC block, by looking up the proper contributions from
 // k6x5To12x12Table and computing an index from the associated values.
+typedef uint8_t (*GetAlphaProc)(const uint8_t* src, int rowBytes, int x, int y);
+
+template<GetAlphaProc getAlphaProc>
 static void compress_a8_astc_block(uint8_t** dst, const uint8_t* src, int rowBytes) {
     // Check for single color
     bool constant = true;
@@ -186,7 +194,7 @@
                 const int x = k6x5To12x12Table[idx][w*3 + 1];
                 const int y = k6x5To12x12Table[idx][w*3 + 2];
                 weightTot += weight;
-                alphaTot += weight * get_alpha(src, rowBytes, x, y);
+                alphaTot += weight * getAlphaProc(src, rowBytes, x, y);
             } else {
                 // In our table, not every entry has 20 weights, and all
                 // of them are nonzero. Once we hit a negative weight, we
@@ -248,6 +256,10 @@
     send_packing(dst, SkEndian_SwapLE64(top), SkEndian_SwapLE64(bottom));
 }
 
+inline void compress_a8_astc_block_vertical(uint8_t* dst, const uint8_t* src) {
+    compress_a8_astc_block<GetAlphaTranspose>(&dst, src, 12);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 namespace SkTextureCompressor {
@@ -260,7 +272,7 @@
     uint8_t** dstPtr = &dst;
     for (int y = 0; y < height; y+=12) {
         for (int x = 0; x < width; x+=12) {
-            compress_a8_astc_block(dstPtr, src + y*rowBytes + x, rowBytes);
+            compress_a8_astc_block<GetAlpha>(dstPtr, src + y*rowBytes + x, rowBytes);
         }
     }
 
@@ -268,8 +280,9 @@
 }
 
 SkBlitter* CreateASTCBlitter(int width, int height, void* outputBuffer) {
-    // TODO (krajcevski)
-    return NULL;
+    return new
+        SkTCompressedAlphaBlitter<12, 16, compress_a8_astc_block_vertical>
+        (width, height, outputBuffer);
 }
 
 }  // SkTextureCompressor
diff --git a/src/utils/SkTextureCompressor_Blitter.h b/src/utils/SkTextureCompressor_Blitter.h
index 23265a4..93d158d 100644
--- a/src/utils/SkTextureCompressor_Blitter.h
+++ b/src/utils/SkTextureCompressor_Blitter.h
@@ -231,7 +231,7 @@
     inline void updateBlockColumns(Block block, const int col,
                                    const int colsLeft, const Column curAlphai) {
         SkASSERT(NULL != block);
-        SkASSERT(col + colsLeft <= 4);
+        SkASSERT(col + colsLeft <= BlockDim);
 
         for (int i = col; i < (col + colsLeft); ++i) {
             memcpy(block[i], curAlphai, sizeof(Column));