| Index: src/codec/SkSwizzler.cpp
|
| diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp
|
| index 563933f13a03c16e880c2b8132c7df3657fc4868..782fb2877b59948019c31e1e257365126043e99a 100644
|
| --- a/src/codec/SkSwizzler.cpp
|
| +++ b/src/codec/SkSwizzler.cpp
|
| @@ -9,101 +9,178 @@
|
| #include "SkSwizzler.h"
|
| #include "SkTemplates.h"
|
|
|
| -// index
|
| -
|
| #define A32_MASK_IN_PLACE (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT)
|
|
|
| -static bool swizzle_index_to_n32(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int, const SkPMColor ctable[]) {
|
| +// kIndex1, kIndex2, kIndex4
|
| +
|
| +static SkSwizzler::ResultAlpha swizzle_small_index_to_n32(
|
| + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
|
| + int bitsPerPixel, int y, const SkPMColor ctable[]) {
|
| +
|
| + SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
|
| + SkPMColor maxAlpha = A32_MASK_IN_PLACE;
|
| + SkPMColor zeroAlpha = 0;
|
| + const uint32_t pixelsPerByte = 8 / bitsPerPixel;
|
| + const uint32_t rowBytes = (width + pixelsPerByte - 1) / 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 < width; p++) {
|
| + uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
|
| + SkPMColor c = ctable[index];
|
| + dst[x] = c;
|
| + maxAlpha &= c;
|
| + zeroAlpha |= c & A32_MASK_IN_PLACE;
|
| + pixelData <<= bitsPerPixel;
|
| + x++;
|
| + }
|
| + }
|
| + return SkSwizzler::GetResult(zeroAlpha, maxAlpha >> SK_A32_SHIFT);
|
| +}
|
| +
|
| +// kIndex
|
| +
|
| +static SkSwizzler::ResultAlpha swizzle_index_to_n32(
|
| + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
|
| + int bitsPerPixel, int y, const SkPMColor ctable[]) {
|
|
|
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| - SkPMColor cc = A32_MASK_IN_PLACE;
|
| + SkPMColor maxAlpha = A32_MASK_IN_PLACE;
|
| + SkPMColor zeroAlpha = 0;
|
| for (int x = 0; x < width; x++) {
|
| SkPMColor c = ctable[*src];
|
| - cc &= c;
|
| + maxAlpha &= c;
|
| + zeroAlpha |= c & A32_MASK_IN_PLACE;
|
| dst[x] = c;
|
| - src += deltaSrc;
|
| + src++;
|
| }
|
| - return cc != A32_MASK_IN_PLACE;
|
| + return SkSwizzler::GetResult(zeroAlpha, maxAlpha >> SK_A32_SHIFT);
|
| }
|
|
|
| -static bool swizzle_index_to_n32_skipZ(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int,
|
| - const SkPMColor ctable[]) {
|
| +static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ(
|
| + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
|
| + int bitsPerPixel, int y, const SkPMColor ctable[]) {
|
|
|
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| - SkPMColor cc = A32_MASK_IN_PLACE;
|
| + SkPMColor maxAlpha = A32_MASK_IN_PLACE;
|
| + SkPMColor zeroAlpha = 0;
|
| for (int x = 0; x < width; x++) {
|
| SkPMColor c = ctable[*src];
|
| - cc &= c;
|
| + maxAlpha &= c;
|
| + zeroAlpha |= c & A32_MASK_IN_PLACE;
|
| if (c != 0) {
|
| dst[x] = c;
|
| }
|
| - src += deltaSrc;
|
| + src++;
|
| }
|
| - return cc != A32_MASK_IN_PLACE;
|
| + return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
|
| }
|
|
|
| #undef A32_MASK_IN_PLACE
|
|
|
| +static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32(
|
| + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
|
| + int bitsPerPixel, int y, const SkPMColor ctable[]) {
|
| +
|
| + SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| + int deltaSrc = bitsPerPixel / 8;
|
| + for (int x = 0; x < width; x++) {
|
| + dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]);
|
| + src += deltaSrc;
|
| + }
|
| + return SkSwizzler::kOpaque_ResultAlpha;
|
| +}
|
| +
|
| +// kBGRA
|
| +
|
| +static SkSwizzler::ResultAlpha swizzle_bgra_to_n32(
|
| + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
|
| + int bitsPerPixel, int y, const SkPMColor ctable[]) {
|
| +
|
| + SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| + uint8_t maxAlpha = 0xFF;
|
| + uint8_t zeroAlpha = 0;
|
| + int deltaSrc = bitsPerPixel / 8;
|
| + for (int x = 0; x < width; x++) {
|
| + uint8_t alpha = src[3];
|
| + maxAlpha &= alpha;
|
| + zeroAlpha |= alpha;
|
| + dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]);
|
| + src += deltaSrc;
|
| + }
|
| + return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
|
| +}
|
| +
|
| // n32
|
| -static bool swizzle_rgbx_to_n32(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int, const SkPMColor[]) {
|
| +static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32(
|
| + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
|
| + int bitsPerPixel, int y, const SkPMColor ctable[]) {
|
| +
|
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| + int deltaSrc = bitsPerPixel / 8;
|
| for (int x = 0; x < width; x++) {
|
| dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
|
| src += deltaSrc;
|
| }
|
| - return false;
|
| + return SkSwizzler::kOpaque_ResultAlpha;
|
| }
|
|
|
| -static bool swizzle_rgba_to_n32_premul(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int, const SkPMColor[]) {
|
| +static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul(
|
| + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
|
| + int bitsPerPixel, int y, const SkPMColor ctable[]) {
|
| +
|
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| - unsigned alphaMask = 0xFF;
|
| + int deltaSrc = bitsPerPixel / 8;
|
| + uint8_t maxAlpha = 0xFF;
|
| + uint8_t zeroAlpha = 0;
|
| for (int x = 0; x < width; x++) {
|
| unsigned alpha = src[3];
|
| dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
|
| src += deltaSrc;
|
| - alphaMask &= alpha;
|
| + maxAlpha &= alpha;
|
| + zeroAlpha |= alpha;
|
| }
|
| - return alphaMask != 0xFF;
|
| + return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
|
| }
|
|
|
| -static bool swizzle_rgba_to_n32_unpremul(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int,
|
| - const SkPMColor[]) {
|
| +static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul(
|
| + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
|
| + int bitsPerPixel, int y, const SkPMColor ctable[]) {
|
| +
|
| uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
|
| - unsigned alphaMask = 0xFF;
|
| + int deltaSrc = bitsPerPixel / 8;
|
| + uint8_t maxAlpha = 0xFF;
|
| + uint8_t zeroAlpha = 0;
|
| for (int x = 0; x < width; x++) {
|
| unsigned alpha = src[3];
|
| dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
|
| src += deltaSrc;
|
| - alphaMask &= alpha;
|
| + maxAlpha &= alpha;
|
| + zeroAlpha |= alpha;
|
| }
|
| - return alphaMask != 0xFF;
|
| + return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
|
| }
|
|
|
| -static bool swizzle_rgba_to_n32_premul_skipZ(void* SK_RESTRICT dstRow,
|
| - const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int,
|
| - const SkPMColor[]) {
|
| +static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ(
|
| + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
|
| + int bitsPerPixel, int y, const SkPMColor ctable[]) {
|
| +
|
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| - unsigned alphaMask = 0xFF;
|
| + int deltaSrc = bitsPerPixel / 8;
|
| + uint8_t maxAlpha = 0xFF;
|
| + uint8_t zeroAlpha = 0;
|
| for (int x = 0; x < width; x++) {
|
| unsigned alpha = src[3];
|
| if (0 != alpha) {
|
| dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
|
| }
|
| src += deltaSrc;
|
| - alphaMask &= alpha;
|
| + maxAlpha &= alpha;
|
| + zeroAlpha |= alpha;
|
| }
|
| - return alphaMask != 0xFF;
|
| + return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
|
| }
|
|
|
| /**
|
| @@ -114,7 +191,7 @@ static bool swizzle_rgba_to_n32_premul_skipZ(void* SK_RESTRICT dstRow,
|
| decide whether to switch to unpremul default.
|
| static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
|
| const uint8_t* SK_RESTRICT src,
|
| - int width, int deltaSrc, int,
|
| + int width, int bitsPerPixel,
|
| const SkPMColor[]) {
|
| SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
|
| unsigned alphaMask = 0xFF;
|
| @@ -133,31 +210,68 @@ static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
|
| }
|
| */
|
|
|
| -SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, const SkPMColor* ctable,
|
| +SkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha,
|
| + uint8_t maxAlpha) {
|
| + return (maxAlpha == 0xFF) ? SkSwizzler::kOpaque_ResultAlpha :
|
| + ((zeroAlpha == 0) ? SkSwizzler::kTransparent_ResultAlpha :
|
| + SkSwizzler::kNeither_ResultAlpha);
|
| +}
|
| +
|
| +SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
|
| + const SkPMColor* ctable,
|
| const SkImageInfo& info, void* dst,
|
| size_t dstRowBytes, bool skipZeroes) {
|
| - if (info.colorType() == kUnknown_SkColorType) {
|
| + if (kUnknown_SkColorType == info.colorType()) {
|
| return NULL;
|
| }
|
| if (info.minRowBytes() > dstRowBytes) {
|
| return NULL;
|
| }
|
| - if (kIndex == sc && NULL == ctable) {
|
| + if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
|
| + && NULL == ctable) {
|
| return NULL;
|
| }
|
| RowProc proc = NULL;
|
| switch (sc) {
|
| + case kIndex1:
|
| + case kIndex2:
|
| + case kIndex4:
|
| + switch (info.colorType()) {
|
| + case kN32_SkColorType:
|
| + proc = &swizzle_small_index_to_n32;
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + break;
|
| case kIndex:
|
| switch (info.colorType()) {
|
| case kN32_SkColorType:
|
| - // We assume the color premultiplied ctable (or not) as desired.
|
| if (skipZeroes) {
|
| - proc = &swizzle_index_to_n32_skipZ;
|
| - } else {
|
| proc = &swizzle_index_to_n32;
|
| + } else {
|
| + proc = &swizzle_index_to_n32_skipZ;
|
| }
|
| break;
|
| -
|
| + default:
|
| + break;
|
| + }
|
| + break;
|
| + case kBGR:
|
| + case kBGRX:
|
| + switch (info.colorType()) {
|
| + case kN32_SkColorType:
|
| + proc = &swizzle_bgrx_to_n32;
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + break;
|
| + case kBGRA:
|
| + switch (info.colorType()) {
|
| + case kN32_SkColorType:
|
| + proc = &swizzle_bgra_to_n32;
|
| + break;
|
| default:
|
| break;
|
| }
|
| @@ -190,32 +304,63 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, const SkPMColor
|
| break;
|
| }
|
| break;
|
| + case kRGB:
|
| + switch (info.colorType()) {
|
| + case kN32_SkColorType:
|
| + proc = &swizzle_rgbx_to_n32;
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + break;
|
| default:
|
| break;
|
| }
|
| if (NULL == proc) {
|
| return NULL;
|
| }
|
| - return SkNEW_ARGS(SkSwizzler, (proc, ctable, BytesPerPixel(sc), info, dst, dstRowBytes));
|
| + return SkNEW_ARGS(SkSwizzler, (proc, ctable, BitsPerPixel(sc), info, dst,
|
| + dstRowBytes));
|
| }
|
|
|
| -SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcBpp,
|
| - const SkImageInfo& info, void* dst, size_t rowBytes)
|
| +SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable,
|
| + int srcBitsPerPixel, const SkImageInfo& info, void* dst,
|
| + size_t rowBytes)
|
| : fRowProc(proc)
|
| , fColorTable(ctable)
|
| - , fSrcPixelSize(srcBpp)
|
| + , fSrcBitsPerPixel(srcBitsPerPixel)
|
| , fDstInfo(info)
|
| , fDstRow(dst)
|
| , fDstRowBytes(rowBytes)
|
| , fCurrY(0)
|
| {
|
| + SkDEBUGCODE(fSwizzleMode = kUninitialized_SwizzleMode);
|
| }
|
|
|
| -bool SkSwizzler::next(const uint8_t* SK_RESTRICT src) {
|
| - SkASSERT(fCurrY < fDstInfo.height());
|
| - const bool hadAlpha = fRowProc(fDstRow, src, fDstInfo.width(), fSrcPixelSize,
|
| - fCurrY, fColorTable);
|
| - fCurrY++;
|
| +SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src) {
|
| + SkASSERT(0 <= fCurrY && fCurrY < fDstInfo.height());
|
| + SkASSERT(kDesignateRow_SwizzleMode != fSwizzleMode);
|
| + SkDEBUGCODE(fSwizzleMode = kConsecutive_SwizzleMode);
|
| +
|
| + // Decode a row
|
| + const ResultAlpha result = fRowProc(fDstRow, src, fDstInfo.width(),
|
| + fSrcBitsPerPixel, fCurrY, fColorTable);
|
| +
|
| + // Move to the next row and return the result
|
| fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes);
|
| - return hadAlpha;
|
| + return result;
|
| +}
|
| +
|
| +SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src,
|
| + int y) {
|
| + SkASSERT(0 <= y && y < fDstInfo.height());
|
| + SkASSERT(kConsecutive_SwizzleMode != fSwizzleMode);
|
| + SkDEBUGCODE(fSwizzleMode = kDesignateRow_SwizzleMode);
|
| +
|
| + // Choose the row
|
| + void* row = SkTAddOffset<void>(fDstRow, y*fDstRowBytes);
|
| +
|
| + // Decode the row
|
| + return fRowProc(row, src, fDstInfo.width(), fSrcBitsPerPixel, fCurrY,
|
| + fColorTable);
|
| }
|
|
|