| Index: src/codec/SkBmpRLECodec.cpp
 | 
| diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp
 | 
| index 14a5b01c1f374d520856058aeef61ef9978324d3..5f1b793fd2ee55ea80ee3a47e4d3b56afa41d691 100644
 | 
| --- a/src/codec/SkBmpRLECodec.cpp
 | 
| +++ b/src/codec/SkBmpRLECodec.cpp
 | 
| @@ -8,6 +8,7 @@
 | 
|  #include "SkBmpRLECodec.h"
 | 
|  #include "SkCodecPriv.h"
 | 
|  #include "SkColorPriv.h"
 | 
| +#include "SkScaledCodec.h"
 | 
|  #include "SkScanlineDecoder.h"
 | 
|  #include "SkStream.h"
 | 
|  
 | 
| @@ -27,16 +28,17 @@ SkBmpRLECodec::SkBmpRLECodec(const SkImageInfo& info, SkStream* stream,
 | 
|      , fStreamBuffer(SkNEW_ARRAY(uint8_t, RLEBytes))
 | 
|      , fRLEBytes(RLEBytes)
 | 
|      , fCurrRLEByte(0)
 | 
| +    , fSampleX(1)
 | 
|  {}
 | 
|  
 | 
|  /*
 | 
|   * Initiates the bitmap decode
 | 
|   */
 | 
|  SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo,
 | 
| -                                        void* dst, size_t dstRowBytes,
 | 
| -                                        const Options& opts,
 | 
| -                                        SkPMColor* inputColorPtr,
 | 
| -                                        int* inputColorCount) {
 | 
| +                                           void* dst, size_t dstRowBytes,
 | 
| +                                           const Options& opts,
 | 
| +                                           SkPMColor* inputColorPtr,
 | 
| +                                           int* inputColorCount) {
 | 
|      if (!this->rewindIfNeeded()) {
 | 
|          return kCouldNotRewind;
 | 
|      }
 | 
| @@ -53,24 +55,13 @@ SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo,
 | 
|          return kInvalidConversion;
 | 
|      }
 | 
|  
 | 
| -    // Create the color table if necessary and prepare the stream for decode
 | 
| -    // Note that if it is non-NULL, inputColorCount will be modified
 | 
| -    if (!this->createColorTable(inputColorCount)) {
 | 
| -        SkCodecPrintf("Error: could not create color table.\n");
 | 
| -        return kInvalidInput;
 | 
| -    }
 | 
| -
 | 
| -    // Copy the color table to the client if necessary
 | 
| -    copy_color_table(dstInfo, fColorTable, inputColorPtr, inputColorCount);
 | 
| -
 | 
| -    // Initialize a swizzler if necessary
 | 
| -    if (!this->initializeStreamBuffer()) {
 | 
| -        SkCodecPrintf("Error: cannot initialize swizzler.\n");
 | 
| -        return kInvalidConversion;
 | 
| +    Result result = this->prepareToDecode(dstInfo, opts, inputColorPtr, inputColorCount);
 | 
| +    if (kSuccess != result) {
 | 
| +        return result;
 | 
|      }
 | 
|  
 | 
|      // Perform the decode
 | 
| -    return decode(dstInfo, dst, dstRowBytes, opts);
 | 
| +    return decodeRows(dstInfo, dst, dstRowBytes, opts);
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -194,33 +185,31 @@ size_t SkBmpRLECodec::checkForMoreData() {
 | 
|  void SkBmpRLECodec::setPixel(void* dst, size_t dstRowBytes,
 | 
|                               const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
 | 
|                               uint8_t index) {
 | 
| -    // Set the row
 | 
| -    int height = dstInfo.height();
 | 
| -    int row;
 | 
| -    if (SkBmpCodec::kBottomUp_RowOrder == this->rowOrder()) {
 | 
| -        row = height - y - 1;
 | 
| -    } else {
 | 
| -        row = y;
 | 
| -    }
 | 
| -
 | 
| -    // Set the pixel based on destination color type
 | 
| -    switch (dstInfo.colorType()) {
 | 
| -        case kN32_SkColorType: {
 | 
| -            SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
 | 
| -                    row * (int) dstRowBytes);
 | 
| -            dstRow[x] = fColorTable->operator[](index);
 | 
| -            break;
 | 
| -        }
 | 
| -        case kRGB_565_SkColorType: {
 | 
| -            uint16_t* dstRow = SkTAddOffset<uint16_t>(dst, row * (int) dstRowBytes);
 | 
| -            dstRow[x] = SkPixel32ToPixel16(fColorTable->operator[](index));
 | 
| -            break;
 | 
| +    if (SkScaledCodec::IsCoordNecessary(x, fSampleX, dstInfo.width())) {
 | 
| +        // Set the row
 | 
| +        uint32_t row = this->getDstRow(y, dstInfo.height());
 | 
| +
 | 
| +        // Set the pixel based on destination color type
 | 
| +        switch (dstInfo.colorType()) {
 | 
| +            case kN32_SkColorType: {
 | 
| +                SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
 | 
| +                        row * (int) dstRowBytes);
 | 
| +                dstRow[SkScaledCodec::GetDstCoord(x, fSampleX)] =
 | 
| +                        fColorTable->operator[](index);
 | 
| +                break;
 | 
| +            }
 | 
| +            case kRGB_565_SkColorType: {
 | 
| +                uint16_t* dstRow = SkTAddOffset<uint16_t>(dst, row * (int) dstRowBytes);
 | 
| +                dstRow[SkScaledCodec::GetDstCoord(x, fSampleX)] =
 | 
| +                        SkPixel32ToPixel16(fColorTable->operator[](index));
 | 
| +                break;
 | 
| +            }
 | 
| +            default:
 | 
| +                // This case should not be reached.  We should catch an invalid
 | 
| +                // color type when we check that the conversion is possible.
 | 
| +                SkASSERT(false);
 | 
| +                break;
 | 
|          }
 | 
| -        default:
 | 
| -            // This case should not be reached.  We should catch an invalid
 | 
| -            // color type when we check that the conversion is possible.
 | 
| -            SkASSERT(false);
 | 
| -            break;
 | 
|      }
 | 
|  }
 | 
|  
 | 
| @@ -231,43 +220,65 @@ void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes,
 | 
|                                  const SkImageInfo& dstInfo, uint32_t x,
 | 
|                                  uint32_t y, uint8_t red, uint8_t green,
 | 
|                                  uint8_t blue) {
 | 
| -    // Set the row
 | 
| -    int height = dstInfo.height();
 | 
| -    int row;
 | 
| -    if (SkBmpCodec::kBottomUp_RowOrder == this->rowOrder()) {
 | 
| -        row = height - y - 1;
 | 
| -    } else {
 | 
| -        row = y;
 | 
| +    if (SkScaledCodec::IsCoordNecessary(x, fSampleX, dstInfo.width())) {
 | 
| +        // Set the row
 | 
| +        uint32_t row = this->getDstRow(y, dstInfo.height());
 | 
| +
 | 
| +        // Set the pixel based on destination color type
 | 
| +        switch (dstInfo.colorType()) {
 | 
| +            case kN32_SkColorType: {
 | 
| +                SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
 | 
| +                        row * (int) dstRowBytes);
 | 
| +                dstRow[SkScaledCodec::GetDstCoord(x, fSampleX)] =
 | 
| +                        SkPackARGB32NoCheck(0xFF, red, green, blue);
 | 
| +                break;
 | 
| +            }
 | 
| +            case kRGB_565_SkColorType: {
 | 
| +                uint16_t* dstRow = SkTAddOffset<uint16_t>(dst, row * (int) dstRowBytes);
 | 
| +                dstRow[SkScaledCodec::GetDstCoord(x, fSampleX)] =
 | 
| +                        SkPack888ToRGB16(red, green, blue);
 | 
| +                break;
 | 
| +            }
 | 
| +            default:
 | 
| +                // This case should not be reached.  We should catch an invalid
 | 
| +                // color type when we check that the conversion is possible.
 | 
| +                SkASSERT(false);
 | 
| +                break;
 | 
| +        }
 | 
|      }
 | 
| +}
 | 
|  
 | 
| -    // Set the pixel based on destination color type
 | 
| -    switch (dstInfo.colorType()) {
 | 
| -        case kN32_SkColorType: {
 | 
| -            SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
 | 
| -                    row * (int) dstRowBytes);
 | 
| -            dstRow[x] = SkPackARGB32NoCheck(0xFF, red, green, blue);
 | 
| -            break;
 | 
| -        }
 | 
| -        case kRGB_565_SkColorType: {
 | 
| -            uint16_t* dstRow = SkTAddOffset<uint16_t>(dst, row * (int) dstRowBytes);
 | 
| -            dstRow[x] = SkPack888ToRGB16(red, green, blue);
 | 
| -            break;
 | 
| -        }
 | 
| -        default:
 | 
| -            // This case should not be reached.  We should catch an invalid
 | 
| -            // color type when we check that the conversion is possible.
 | 
| -            SkASSERT(false);
 | 
| -            break;
 | 
| +SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo,
 | 
| +        const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
 | 
| +    // Create the color table if necessary and prepare the stream for decode
 | 
| +    // Note that if it is non-NULL, inputColorCount will be modified
 | 
| +    if (!this->createColorTable(inputColorCount)) {
 | 
| +        SkCodecPrintf("Error: could not create color table.\n");
 | 
| +        return SkCodec::kInvalidInput;
 | 
|      }
 | 
| +
 | 
| +    // Copy the color table to the client if necessary
 | 
| +    copy_color_table(dstInfo, this->fColorTable, inputColorPtr, inputColorCount);
 | 
| +
 | 
| +    // Initialize a buffer for encoded RLE data
 | 
| +    if (!this->initializeStreamBuffer()) {
 | 
| +        SkCodecPrintf("Error: cannot initialize stream buffer.\n");
 | 
| +        return SkCodec::kInvalidConversion;
 | 
| +    }
 | 
| +
 | 
| +    fCurrRLEByte = 0;
 | 
| +    SkScaledCodec::ComputeSampleSize(dstInfo, this->getInfo(), &fSampleX, NULL);
 | 
| +
 | 
| +    return SkCodec::kSuccess;
 | 
|  }
 | 
|  
 | 
|  /*
 | 
|   * Performs the bitmap decoding for RLE input format
 | 
|   * RLE decoding is performed all at once, rather than a one row at a time
 | 
|   */
 | 
| -SkCodec::Result SkBmpRLECodec::decode(const SkImageInfo& dstInfo,
 | 
| -                                      void* dst, size_t dstRowBytes,
 | 
| -                                      const Options& opts) {
 | 
| +SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo,
 | 
| +                                          void* dst, size_t dstRowBytes,
 | 
| +                                          const Options& opts) {
 | 
|      // Set RLE flags
 | 
|      static const uint8_t RLE_ESCAPE = 0;
 | 
|      static const uint8_t RLE_EOL = 0;
 | 
| @@ -275,7 +286,7 @@ SkCodec::Result SkBmpRLECodec::decode(const SkImageInfo& dstInfo,
 | 
|      static const uint8_t RLE_DELTA = 2;
 | 
|  
 | 
|      // Set constant values
 | 
| -    const int width = dstInfo.width();
 | 
| +    const int width = this->getInfo().width();
 | 
|      const int height = dstInfo.height();
 | 
|  
 | 
|      // Destination parameters
 | 
| @@ -287,9 +298,8 @@ SkCodec::Result SkBmpRLECodec::decode(const SkImageInfo& dstInfo,
 | 
|      // Because of the need for transparent pixels, kN32 is the only color
 | 
|      // type that makes sense for the destination format.
 | 
|      SkASSERT(kN32_SkColorType == dstInfo.colorType());
 | 
| -    if (kNo_ZeroInitialized == opts.fZeroInitialized) {
 | 
| -        SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT, NULL);
 | 
| -    }
 | 
| +    SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT,
 | 
| +            NULL, opts.fZeroInitialized);
 | 
|  
 | 
|      while (true) {
 | 
|          // If we have reached a row that is beyond the requested height, we have
 | 
| 
 |