am b4f070ed: Do not merge.

* commit 'b4f070ed646ef1cbb92c3eaaa073640e30954873':
  Do not merge.
diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h
index 3bb287d..3c904ca 100644
--- a/include/images/SkImageDecoder.h
+++ b/include/images/SkImageDecoder.h
@@ -75,6 +75,20 @@
     */
     void setDitherImage(bool dither) { fDitherImage = dither; }
 
+    /** Returns true if the decoder should try to decode the
+        resulting image to a higher quality even at the expense of
+        the decoding speed.
+    */
+    bool getPreferQualityOverSpeed() const { return fPreferQualityOverSpeed; }
+
+    /** Set to true if the the decoder should try to decode the
+        resulting image to a higher quality even at the expense of
+        the decoding speed.
+    */
+    void setPreferQualityOverSpeed(bool qualityOverSpeed) {
+        fPreferQualityOverSpeed = qualityOverSpeed;
+    }
+
     /** \class Peeker
 
         Base class for optional callbacks to retrieve meta/chunk data out of
@@ -389,6 +403,7 @@
     bool                    fDitherImage;
     bool                    fUsePrefTable;
     mutable bool            fShouldCancelDecode;
+    bool                    fPreferQualityOverSpeed;
 
     // illegal
     SkImageDecoder(const SkImageDecoder&);
diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp
index e3aefea..7e425c1 100644
--- a/src/images/SkImageDecoder_libjpeg.cpp
+++ b/src/images/SkImageDecoder_libjpeg.cpp
@@ -236,7 +236,12 @@
     */
     int sampleSize = this->getSampleSize();
 
-    cinfo.dct_method = JDCT_IFAST;
+    if (this->getPreferQualityOverSpeed()) {
+        cinfo.dct_method = JDCT_ISLOW;
+    } else {
+        cinfo.dct_method = JDCT_IFAST;
+    }
+
     cinfo.scale_num = 1;
     cinfo.scale_denom = sampleSize;
 
@@ -264,13 +269,9 @@
     if (config == SkBitmap::kARGB_8888_Config) {
         cinfo.out_color_space = JCS_RGBA_8888;
     } else if (config == SkBitmap::kRGB_565_Config) {
-        if (sampleSize == 1) {
-            // SkScaledBitmapSampler can't handle RGB_565 yet,
-            // so don't even try.
-            cinfo.out_color_space = JCS_RGB_565;
-            if (this->getDitherImage()) {
-                cinfo.dither_mode = JDITHER_ORDERED;
-            }
+        cinfo.out_color_space = JCS_RGB_565;
+        if (this->getDitherImage()) {
+            cinfo.dither_mode = JDITHER_ORDERED;
         }
     }
 #endif
@@ -360,8 +361,8 @@
 #ifdef ANDROID_RGB
     } else if (JCS_RGBA_8888 == cinfo.out_color_space) {
         sc = SkScaledBitmapSampler::kRGBX;
-    //} else if (JCS_RGB_565 == cinfo.out_color_space) {
-    //    sc = SkScaledBitmapSampler::kRGB_565;
+    } else if (JCS_RGB_565 == cinfo.out_color_space) {
+        sc = SkScaledBitmapSampler::kRGB_565;
 #endif
     } else if (1 == cinfo.out_color_components &&
                JCS_GRAYSCALE == cinfo.out_color_space) {
@@ -468,7 +469,6 @@
     index->index = (huffman_index*)malloc(sizeof(huffman_index));
     jpeg_create_huffman_index(cinfo, index->index);
 
-    cinfo->dct_method = JDCT_IFAST;
     cinfo->scale_num = 1;
     cinfo->scale_denom = 1;
     if (!jpeg_build_huffman_index(cinfo, index->index)) {
@@ -497,7 +497,6 @@
     //jpeg_start_decompress(cinfo);
     jpeg_start_tile_decompress(cinfo);
 
-    cinfo->dct_method = JDCT_IFAST;
     cinfo->scale_num = 1;
     index->cinfo = cinfo;
     *height = cinfo->output_height;
@@ -526,24 +525,30 @@
     int requestedSampleSize = this->getSampleSize();
     cinfo->scale_denom = requestedSampleSize;
 
+    if (this->getPreferQualityOverSpeed()) {
+        cinfo->dct_method = JDCT_ISLOW;
+    } else {
+        cinfo->dct_method = JDCT_IFAST;
+    }
+
     SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, false);
     if (config != SkBitmap::kARGB_8888_Config &&
         config != SkBitmap::kARGB_4444_Config &&
         config != SkBitmap::kRGB_565_Config) {
         config = SkBitmap::kARGB_8888_Config;
     }
+
+    /* default format is RGB */
+    cinfo->out_color_space = JCS_RGB;
+
 #ifdef ANDROID_RGB
     cinfo->dither_mode = JDITHER_NONE;
     if (config == SkBitmap::kARGB_8888_Config) {
         cinfo->out_color_space = JCS_RGBA_8888;
     } else if (config == SkBitmap::kRGB_565_Config) {
-        if (requestedSampleSize == 1) {
-            // SkScaledBitmapSampler can't handle RGB_565 yet,
-            // so don't even try.
-            cinfo->out_color_space = JCS_RGB_565;
-            if (this->getDitherImage()) {
-                cinfo->dither_mode = JDITHER_ORDERED;
-            }
+        cinfo->out_color_space = JCS_RGB_565;
+        if (this->getDitherImage()) {
+            cinfo->dither_mode = JDITHER_ORDERED;
         }
     }
 #endif
@@ -606,6 +611,8 @@
 #ifdef ANDROID_RGB
     } else if (JCS_RGBA_8888 == cinfo->out_color_space) {
         sc = SkScaledBitmapSampler::kRGBX;
+    } else if (JCS_RGB_565 == cinfo->out_color_space) {
+        sc = SkScaledBitmapSampler::kRGB_565;
 #endif
     } else if (1 == cinfo->out_color_components &&
                JCS_GRAYSCALE == cinfo->out_color_space) {
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
index 2b6a28e..cd240b4 100644
--- a/src/images/SkImageDecoder_libpng.cpp
+++ b/src/images/SkImageDecoder_libpng.cpp
@@ -62,10 +62,10 @@
             delete index;
         }
     }
-    virtual bool buildTileIndex(SkStream *stream,
-             int *width, int *height, bool isShareable);
 
 protected:
+    virtual bool onBuildTileIndex(SkStream *stream,
+             int *width, int *height);
     virtual bool onDecodeRegion(SkBitmap* bitmap, SkIRect rect);
     virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
 
@@ -419,33 +419,13 @@
     return true;
 }
 
-bool SkPNGImageDecoder::buildTileIndex(SkStream* sk_stream,
-                int *width, int *height, bool isShareable) {
+bool SkPNGImageDecoder::onBuildTileIndex(SkStream* sk_stream, int *width,
+        int *height) {
     png_structp png_ptr;
     png_infop   info_ptr;
 
     this->index = new SkPNGImageIndex();
 
-    if (!isShareable) {
-        size_t len, inputLen = 0;
-        size_t bufferSize = 4096;
-        void *tmp = sk_malloc_throw(bufferSize);
-
-        while ((len = sk_stream->read((char*) tmp + inputLen,
-                        bufferSize - inputLen)) != 0) {
-            inputLen += len;
-            if (inputLen == bufferSize) {
-                bufferSize *= 2;
-                tmp = sk_realloc_throw(tmp, bufferSize);
-            }
-        }
-        tmp = sk_realloc_throw(tmp, inputLen);
-
-        SkMemoryStream *mem_stream = new SkMemoryStream(tmp, inputLen, true);
-        this->index->inputStream = mem_stream;
-        sk_stream = mem_stream;
-    }
-
     if (onDecodeInit(sk_stream, &png_ptr, &info_ptr) == false) {
         return false;
     }
diff --git a/src/images/SkScaledBitmapSampler.cpp b/src/images/SkScaledBitmapSampler.cpp
index 3ba38f7..32b78ef 100644
--- a/src/images/SkScaledBitmapSampler.cpp
+++ b/src/images/SkScaledBitmapSampler.cpp
@@ -93,6 +93,18 @@
     return false;
 }
 
+static bool Sample_D565_D565(void* SK_RESTRICT dstRow,
+                             const uint8_t* SK_RESTRICT src,
+                             int width, int deltaSrc, int, const SkPMColor[]) {
+    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
+    uint16_t* SK_RESTRICT castedSrc = (uint16_t*) src;
+    for (int x = 0; x < width; x++) {
+        dst[x] = castedSrc[0];
+        castedSrc += deltaSrc >> 1;
+    }
+    return false;
+}
+
 static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow,
                                const uint8_t* SK_RESTRICT src,
                            int width, int deltaSrc, int y, const SkPMColor[]) {
@@ -335,21 +347,25 @@
         Sample_RGBx_D8888,  Sample_RGBx_D8888,
         Sample_RGBA_D8888,  Sample_RGBA_D8888,
         Sample_Index_D8888, Sample_Index_D8888,
+        NULL,               NULL,
         // 565 (no alpha distinction)
         Sample_Gray_D565,   Sample_Gray_D565_D,
         Sample_RGBx_D565,   Sample_RGBx_D565_D,
         Sample_RGBx_D565,   Sample_RGBx_D565_D,
         Sample_Index_D565,  Sample_Index_D565_D,
+        Sample_D565_D565,   Sample_D565_D565,
         // 4444
         Sample_Gray_D4444,  Sample_Gray_D4444_D,
         Sample_RGBx_D4444,  Sample_RGBx_D4444_D,
         Sample_RGBA_D4444,  Sample_RGBA_D4444_D,
         Sample_Index_D4444, Sample_Index_D4444_D,
+        NULL,               NULL,
         // Index8
         NULL,               NULL,
         NULL,               NULL,
         NULL,               NULL,
         Sample_Index_DI,    Sample_Index_DI,
+        NULL,               NULL,
     };
 
     fCTable = ctable;
@@ -379,6 +395,10 @@
             fSrcPixelSize = 1;
             index += 6;
             break;
+        case SkScaledBitmapSampler::kRGB_565:
+            fSrcPixelSize = 2;
+            index += 8;
+            break;
         default:
             return false;
     }
@@ -388,13 +408,13 @@
             index += 0;
             break;
         case SkBitmap::kRGB_565_Config:
-            index += 8;
+            index += 10;
             break;
         case SkBitmap::kARGB_4444_Config:
-            index += 16;
+            index += 20;
             break;
         case SkBitmap::kIndex8_Config:
-            index += 24;
+            index += 30;
             break;
         default:
             return false;
diff --git a/src/images/SkScaledBitmapSampler.h b/src/images/SkScaledBitmapSampler.h
index 84a75ba..43f1669 100644
--- a/src/images/SkScaledBitmapSampler.h
+++ b/src/images/SkScaledBitmapSampler.h
@@ -21,7 +21,8 @@
         kIndex, // 1 byte per pixel
         kRGB,   // 3 bytes per pixel
         kRGBX,  // 4 byes per pixel (ignore 4th)
-        kRGBA   // 4 bytes per pixel
+        kRGBA,  // 4 bytes per pixel
+        kRGB_565 // 2 bytes per pixel
     };
 
     // Given a dst bitmap (with pixels already allocated) and a src-config,