diff options
author | scroggo <scroggo@chromium.org> | 2015-08-14 08:32:46 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-14 08:32:46 -0700 |
commit | cc2feb161f756c4035a407296567654d86bc7be7 (patch) | |
tree | fc18ba44cbd7bfc55ac169fe2610c45c4194fe03 /src/codec/SkSwizzler.cpp | |
parent | 8f4ba76742c329bc4d5e1b8ca376d27922bd00b1 (diff) |
Support more swizzles to 565 in SkCodec
Add more swizzling functions for swizzling to 565. Much of this
code was revived from crrev.com/1055743003 (for BMP). Also added
swizzling functions for WBMP.
Consolidate the static function conversion_possible.
In SkCodec::getPixels, check that the alphatype corresponds to the
colorType. This prevents requesting 565 + non-opaque.
In SkIcoCodec, report that the image is unpremul (instead of
whatever the largest embedded codec thinks), but modify the
requested info to have the alpha type expected/required by the
embedded codec.
Add tests for decoding to 565.
BUG=skia:3257
BUG=skia:3683
Review URL: https://codereview.chromium.org/1277213002
Diffstat (limited to 'src/codec/SkSwizzler.cpp')
-rw-r--r-- | src/codec/SkSwizzler.cpp | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp index 44277614c6..8315cc7145 100644 --- a/src/codec/SkSwizzler.cpp +++ b/src/codec/SkSwizzler.cpp @@ -114,6 +114,34 @@ static SkSwizzler::ResultAlpha swizzle_bit_to_n32( return SkSwizzler::kOpaque_ResultAlpha; } +#define RGB565_BLACK 0 +#define RGB565_WHITE 0xFFFF + +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*/) { + uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow; + + // increment src by byte offset and bitIndex by bit offset + src += offset / 8; + int bitIndex = offset % 8; + uint8_t currByte = *src; + + dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK; + + for (int x = 1; x < dstWidth; x++) { + int bitOffset = bitIndex + deltaSrc; + bitIndex = bitOffset % 8; + currByte = *(src += bitOffset / 8); + dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK; + } + + return SkSwizzler::kOpaque_ResultAlpha; +} + +#undef RGB565_BLACK +#undef RGB565_WHITE + // kIndex1, kIndex2, kIndex4 static SkSwizzler::ResultAlpha swizzle_small_index_to_index( @@ -140,6 +168,29 @@ static SkSwizzler::ResultAlpha swizzle_small_index_to_index( 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[]) { + + 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++; + } + } + return SkSwizzler::kOpaque_ResultAlpha; +} + 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[]) { @@ -306,6 +357,19 @@ static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32( return SkSwizzler::kOpaque_ResultAlpha; } +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[]) { + // FIXME: Support dithering? + src += offset; + uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; + for (int x = 0; x < dstWidth; x++) { + dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]); + src += deltaSrc; + } + return SkSwizzler::kOpaque_ResultAlpha; +} + // kBGRA static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul( @@ -470,6 +534,9 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, case kIndex_8_SkColorType: proc = &swizzle_bit_to_index; break; + case kRGB_565_SkColorType: + proc = &swizzle_bit_to_565; + break; case kGray_8_SkColorType: proc = &swizzle_bit_to_grayscale; break; @@ -484,6 +551,9 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, case kN32_SkColorType: proc = &swizzle_small_index_to_n32; break; + case kRGB_565_SkColorType: + proc = &swizzle_small_index_to_565; + break; case kIndex_8_SkColorType: proc = &swizzle_small_index_to_index; break; @@ -534,6 +604,9 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, case kN32_SkColorType: proc = &swizzle_bgrx_to_n32; break; + case kRGB_565_SkColorType: + proc = &swizzle_bgrx_to_565; + break; default: break; } |