| Index: src/codec/SkSwizzler.cpp | 
| diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp | 
| index 8315cc7145a406f698f0f9ca40f91df9b5af2eff..4541c96ec2afb9efc555c29f4f0506db375c20e7 100644 | 
| --- a/src/codec/SkSwizzler.cpp | 
| +++ b/src/codec/SkSwizzler.cpp | 
| @@ -22,7 +22,7 @@ SkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha, | 
|  | 
| // samples the row. Does not do anything else but sampling | 
| static SkSwizzler::ResultAlpha sample565(void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, | 
| -        int width, int deltaSrc, int offset, const SkPMColor ctable[]){ | 
| +        int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]){ | 
|  | 
| src += offset; | 
| uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow; | 
| @@ -44,7 +44,7 @@ static SkSwizzler::ResultAlpha sample565(void* SK_RESTRICT dstRow, const uint8_t | 
| // same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x] | 
| static SkSwizzler::ResultAlpha swizzle_bit_to_grayscale( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor* /*ctable*/) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) { | 
|  | 
| uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; | 
|  | 
| @@ -71,7 +71,7 @@ static SkSwizzler::ResultAlpha swizzle_bit_to_grayscale( | 
| // same as swizzle_bit_to_grayscale and swizzle_bit_to_n32 except for value assigned to dst[x] | 
| static SkSwizzler::ResultAlpha swizzle_bit_to_index( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor* /*ctable*/) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) { | 
| uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; | 
|  | 
| // increment src by byte offset and bitIndex by bit offset | 
| @@ -94,7 +94,7 @@ static SkSwizzler::ResultAlpha swizzle_bit_to_index( | 
| // same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x] | 
| static SkSwizzler::ResultAlpha swizzle_bit_to_n32( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor* /*ctable*/) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) { | 
| SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow; | 
|  | 
| // increment src by byte offset and bitIndex by bit offset | 
| @@ -119,7 +119,7 @@ static SkSwizzler::ResultAlpha swizzle_bit_to_n32( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_bit_to_565( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor* /*ctable*/) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) { | 
| uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow; | 
|  | 
| // increment src by byte offset and bitIndex by bit offset | 
| @@ -146,72 +146,73 @@ static SkSwizzler::ResultAlpha swizzle_bit_to_565( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_small_index_to_index( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int bitsPerPixel, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| -    src += offset; | 
| -    uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; | 
| +    uint8_t* dst = (uint8_t*) dstRow; | 
| INIT_RESULT_ALPHA; | 
| -    const uint32_t pixelsPerByte = 8 / bitsPerPixel; | 
| -    const size_t rowBytes = compute_row_bytes_ppb(dstWidth, pixelsPerByte); | 
| -    const uint8_t mask = (1 << bitsPerPixel) - 1; | 
| -    int x = 0; | 
| -    for (uint32_t byte = 0; byte < rowBytes; byte++) { | 
| -        uint8_t pixelData = src[byte]; | 
| -        for (uint32_t p = 0; p < pixelsPerByte && x < dstWidth; p++) { | 
| -            uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask; | 
| -            UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT); | 
| -            dst[x] = index; | 
| -            pixelData <<= bitsPerPixel; | 
| -            x++; | 
| -        } | 
| +    src += offset / 8; | 
| +    int bitIndex = offset % 8; | 
| +    uint8_t currByte = *src; | 
| +    const uint8_t mask = (1 << bpp) - 1; | 
| +    uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask; | 
| +    dst[0] = index; | 
| +    UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT); | 
| + | 
| +    for (int x = 1; x < dstWidth; x++) { | 
| +        int bitOffset = bitIndex + deltaSrc; | 
| +        bitIndex = bitOffset % 8; | 
| +        currByte = *(src += bitOffset / 8); | 
| +        index = (currByte >> (8 - bpp - bitIndex)) & mask; | 
| +        dst[x] = index; | 
| +        UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT); | 
| } | 
| return COMPUTE_RESULT_ALPHA; | 
| } | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_small_index_to_565( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int bitsPerPixel, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| -    src += offset; | 
| -    uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow; | 
| -    const uint32_t pixelsPerByte = 8 / bitsPerPixel; | 
| -    const size_t rowBytes = compute_row_bytes_ppb(dstWidth, pixelsPerByte); | 
| -    const uint8_t mask = (1 << bitsPerPixel) - 1; | 
| -    int x = 0; | 
| -    for (uint32_t byte = 0; byte < rowBytes; byte++) { | 
| -        uint8_t pixelData = src[byte]; | 
| -        for (uint32_t p = 0; p < pixelsPerByte && x < dstWidth; p++) { | 
| -            uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask; | 
| -            uint16_t c = SkPixel32ToPixel16(ctable[index]); | 
| -            dst[x] = c; | 
| -            pixelData <<= bitsPerPixel; | 
| -            x++; | 
| -        } | 
| +    uint16_t* dst = (uint16_t*) dstRow; | 
| +    INIT_RESULT_ALPHA; | 
| +    src += offset / 8; | 
| +    int bitIndex = offset % 8; | 
| +    uint8_t currByte = *src; | 
| +    const uint8_t mask = (1 << bpp) - 1; | 
| +    uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask; | 
| +    dst[0] = SkPixel32ToPixel16(ctable[index]); | 
| + | 
| +    for (int x = 1; x < dstWidth; x++) { | 
| +        int bitOffset = bitIndex + deltaSrc; | 
| +        bitIndex = bitOffset % 8; | 
| +        currByte = *(src += bitOffset / 8); | 
| +        index = (currByte >> (8 - bpp - bitIndex)) & mask; | 
| +        dst[x] = SkPixel32ToPixel16(ctable[index]); | 
| } | 
| -    return SkSwizzler::kOpaque_ResultAlpha; | 
| +    return SkAlphaType::kOpaque_SkAlphaType; | 
| } | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_small_index_to_n32( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int bitsPerPixel, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| -    src += offset; | 
| -    SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow; | 
| +    SkPMColor* dst = (SkPMColor*) dstRow; | 
| INIT_RESULT_ALPHA; | 
| -    const uint32_t pixelsPerByte = 8 / bitsPerPixel; | 
| -    const size_t rowBytes = compute_row_bytes_ppb(dstWidth, pixelsPerByte); | 
| -    const uint8_t mask = (1 << bitsPerPixel) - 1; | 
| -    int x = 0; | 
| -    for (uint32_t byte = 0; byte < rowBytes; byte++) { | 
| -        uint8_t pixelData = src[byte]; | 
| -        for (uint32_t p = 0; p < pixelsPerByte && x < dstWidth; p++) { | 
| -            uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask; | 
| -            SkPMColor c = ctable[index]; | 
| -            UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); | 
| -            dst[x] = c; | 
| -            pixelData <<= bitsPerPixel; | 
| -            x++; | 
| -        } | 
| +    src += offset / 8; | 
| +    int bitIndex = offset % 8; | 
| +    uint8_t currByte = *src; | 
| +    const uint8_t mask = (1 << bpp) - 1; | 
| +    uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask; | 
| +    dst[0] = ctable[index]; | 
| +    UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT); | 
| + | 
| +    for (int x = 1; x < dstWidth; x++) { | 
| +        int bitOffset = bitIndex + deltaSrc; | 
| +        bitIndex = bitOffset % 8; | 
| +        currByte = *(src += bitOffset / 8); | 
| +        index = (currByte >> (8 - bpp - bitIndex)) & mask; | 
| +        dst[x] = ctable[index]; | 
| +        UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT); | 
| } | 
| return COMPUTE_RESULT_ALPHA; | 
| } | 
| @@ -220,7 +221,7 @@ static SkSwizzler::ResultAlpha swizzle_small_index_to_n32( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_index_to_index( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; | 
| @@ -248,7 +249,7 @@ static SkSwizzler::ResultAlpha swizzle_index_to_index( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_index_to_n32( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
| @@ -264,7 +265,7 @@ static SkSwizzler::ResultAlpha swizzle_index_to_n32( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
| @@ -282,14 +283,14 @@ static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_index_to_565( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -      int bytesPerPixel, int offset, const SkPMColor ctable[]) { | 
| +      int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| // FIXME: Support dithering? Requires knowing y, which I think is a bigger | 
| // change. | 
| src += offset; | 
| uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
| for (int x = 0; x < dstWidth; x++) { | 
| dst[x] = SkPixel32ToPixel16(ctable[*src]); | 
| -        src += bytesPerPixel; | 
| +        src += deltaSrc; | 
| } | 
| return SkSwizzler::kOpaque_ResultAlpha; | 
| } | 
| @@ -301,7 +302,7 @@ static SkSwizzler::ResultAlpha swizzle_index_to_565( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_gray_to_n32( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
| @@ -314,7 +315,7 @@ static SkSwizzler::ResultAlpha swizzle_gray_to_n32( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_gray_to_gray( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; | 
| @@ -331,13 +332,13 @@ static SkSwizzler::ResultAlpha swizzle_gray_to_gray( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_gray_to_565( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int bytesPerPixel, int offset, const SkPMColor ctable[]) { | 
| +        int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| // FIXME: Support dithering? | 
| src += offset; | 
| uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
| for (int x = 0; x < dstWidth; x++) { | 
| dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); | 
| -        src += bytesPerPixel; | 
| +        src += deltaSrc; | 
| } | 
| return SkSwizzler::kOpaque_ResultAlpha; | 
| } | 
| @@ -346,7 +347,7 @@ static SkSwizzler::ResultAlpha swizzle_gray_to_565( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
| @@ -359,7 +360,7 @@ static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_bgrx_to_565( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| // FIXME: Support dithering? | 
| src += offset; | 
| uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
| @@ -374,7 +375,7 @@ static SkSwizzler::ResultAlpha swizzle_bgrx_to_565( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
| @@ -390,7 +391,7 @@ static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_premul( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
| @@ -407,7 +408,7 @@ static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_premul( | 
| // kRGBX | 
| static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
| @@ -420,13 +421,13 @@ static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_rgbx_to_565( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -       int bytesPerPixel, int offset, const SkPMColor ctable[]) { | 
| +       int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| // FIXME: Support dithering? | 
| src += offset; | 
| uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
| for (int x = 0; x < dstWidth; x++) { | 
| dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); | 
| -        src += bytesPerPixel; | 
| +        src += deltaSrc; | 
| } | 
| return SkSwizzler::kOpaque_ResultAlpha; | 
| } | 
| @@ -435,7 +436,7 @@ static SkSwizzler::ResultAlpha swizzle_rgbx_to_565( | 
| // kRGBA | 
| static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
| @@ -451,7 +452,7 @@ static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); | 
| @@ -467,7 +468,7 @@ static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul( | 
|  | 
| static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ( | 
| void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 
| -        int deltaSrc, int offset, const SkPMColor ctable[]) { | 
| +        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 
|  | 
| src += offset; | 
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
| @@ -708,7 +709,8 @@ SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, | 
|  | 
| SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) { | 
| SkASSERT(NULL != dst && NULL != src); | 
| -    return fRowProc(dst, src, fDstInfo.width(), fSampleX * fDeltaSrc, fX0 * fDeltaSrc, fColorTable); | 
| +    return fRowProc(dst, src, fDstInfo.width(), fDeltaSrc, fSampleX * fDeltaSrc, | 
| +            fX0 * fDeltaSrc, fColorTable); | 
| } | 
|  | 
| void SkSwizzler::Fill(void* dstStartRow, const SkImageInfo& dstInfo, size_t dstRowBytes, | 
|  |