Index: src/codec/SkMaskSwizzler.cpp |
diff --git a/src/codec/SkMaskSwizzler.cpp b/src/codec/SkMaskSwizzler.cpp |
index 8d9f6c66b3ac007e955118b872d244b52614ea3b..944042d1abd1e084c8c0049e3c0060700abed843 100644 |
--- a/src/codec/SkMaskSwizzler.cpp |
+++ b/src/codec/SkMaskSwizzler.cpp |
@@ -9,12 +9,7 @@ |
#include "SkColorPriv.h" |
#include "SkMaskSwizzler.h" |
-/* |
- * |
- * Row procedure for masked color components with 16 bits per pixel |
- * |
- */ |
-static SkSwizzler::ResultAlpha swizzle_mask16_to_n32( |
+static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_opaque( |
void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
// Use the masks to decode to the destination |
@@ -30,12 +25,7 @@ static SkSwizzler::ResultAlpha swizzle_mask16_to_n32( |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
-/* |
- * |
- * Row procedure for masked color components with 16 bits per pixel with alpha |
- * |
- */ |
-static SkSwizzler::ResultAlpha swizzle_mask16_alpha_to_n32( |
+static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_unpremul( |
void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
// Use the masks to decode to the destination |
@@ -54,12 +44,42 @@ static SkSwizzler::ResultAlpha swizzle_mask16_alpha_to_n32( |
return COMPUTE_RESULT_ALPHA; |
} |
-/* |
- * |
- * Row procedure for masked color components with 24 bits per pixel |
- * |
- */ |
-static SkSwizzler::ResultAlpha swizzle_mask24_to_n32( |
+static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_premul( |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ |
+ // Use the masks to decode to the destination |
+ uint16_t* srcPtr = (uint16_t*) srcRow; |
+ SkPMColor* dstPtr = (SkPMColor*) dstRow; |
+ INIT_RESULT_ALPHA; |
+ for (int i = 0; i < width; i++) { |
+ uint16_t p = srcPtr[i]; |
+ uint8_t red = masks->getRed(p); |
+ uint8_t green = masks->getGreen(p); |
+ uint8_t blue = masks->getBlue(p); |
+ uint8_t alpha = masks->getAlpha(p); |
+ UPDATE_RESULT_ALPHA(alpha); |
+ dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue); |
+ } |
+ return COMPUTE_RESULT_ALPHA; |
+} |
+ |
+static SkSwizzler::ResultAlpha swizzle_mask16_to_565( |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ |
+ // Use the masks to decode to the destination |
+ uint16_t* srcPtr = (uint16_t*) srcRow; |
+ uint16_t* dstPtr = (uint16_t*) dstRow; |
+ for (int i = 0; i < width; i++) { |
+ uint16_t p = srcPtr[i]; |
+ uint8_t red = masks->getRed(p); |
+ uint8_t green = masks->getGreen(p); |
+ uint8_t blue = masks->getBlue(p); |
+ dstPtr[i] = SkPack888ToRGB16(red, green, blue); |
+ } |
+ return SkSwizzler::kOpaque_ResultAlpha; |
+} |
+ |
+static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_opaque( |
void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
// Use the masks to decode to the destination |
@@ -74,12 +94,7 @@ static SkSwizzler::ResultAlpha swizzle_mask24_to_n32( |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
-/* |
- * |
- * Row procedure for masked color components with 24 bits per pixel with alpha |
- * |
- */ |
-static SkSwizzler::ResultAlpha swizzle_mask24_alpha_to_n32( |
+static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_unpremul( |
void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
// Use the masks to decode to the destination |
@@ -97,12 +112,40 @@ static SkSwizzler::ResultAlpha swizzle_mask24_alpha_to_n32( |
return COMPUTE_RESULT_ALPHA; |
} |
-/* |
- * |
- * Row procedure for masked color components with 32 bits per pixel |
- * |
- */ |
-static SkSwizzler::ResultAlpha swizzle_mask32_to_n32( |
+static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_premul( |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ |
+ // Use the masks to decode to the destination |
+ SkPMColor* dstPtr = (SkPMColor*) dstRow; |
+ INIT_RESULT_ALPHA; |
+ for (int i = 0; i < 3*width; i += 3) { |
+ uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16; |
+ uint8_t red = masks->getRed(p); |
+ uint8_t green = masks->getGreen(p); |
+ uint8_t blue = masks->getBlue(p); |
+ uint8_t alpha = masks->getAlpha(p); |
+ UPDATE_RESULT_ALPHA(alpha); |
+ dstPtr[i/3] = SkPreMultiplyARGB(alpha, red, green, blue); |
+ } |
+ return COMPUTE_RESULT_ALPHA; |
+} |
+ |
+static SkSwizzler::ResultAlpha swizzle_mask24_to_565( |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ |
+ // Use the masks to decode to the destination |
+ uint16_t* dstPtr = (uint16_t*) dstRow; |
+ for (int i = 0; i < 3*width; i += 3) { |
+ uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16; |
+ uint8_t red = masks->getRed(p); |
+ uint8_t green = masks->getGreen(p); |
+ uint8_t blue = masks->getBlue(p); |
+ dstPtr[i/3] = SkPack888ToRGB16(red, green, blue); |
+ } |
+ return SkSwizzler::kOpaque_ResultAlpha; |
+} |
+ |
+static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_opaque( |
void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
// Use the masks to decode to the destination |
@@ -118,12 +161,7 @@ static SkSwizzler::ResultAlpha swizzle_mask32_to_n32( |
return SkSwizzler::kOpaque_ResultAlpha; |
} |
-/* |
- * |
- * Row procedure for masked color components with 32 bits per pixel |
- * |
- */ |
-static SkSwizzler::ResultAlpha swizzle_mask32_alpha_to_n32( |
+static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_unpremul( |
void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
// Use the masks to decode to the destination |
@@ -142,44 +180,148 @@ static SkSwizzler::ResultAlpha swizzle_mask32_alpha_to_n32( |
return COMPUTE_RESULT_ALPHA; |
} |
+static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_premul( |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ |
+ // Use the masks to decode to the destination |
+ uint32_t* srcPtr = (uint32_t*) srcRow; |
+ SkPMColor* dstPtr = (SkPMColor*) dstRow; |
+ INIT_RESULT_ALPHA; |
+ for (int i = 0; i < width; i++) { |
+ uint32_t p = srcPtr[i]; |
+ uint8_t red = masks->getRed(p); |
+ uint8_t green = masks->getGreen(p); |
+ uint8_t blue = masks->getBlue(p); |
+ uint8_t alpha = masks->getAlpha(p); |
+ UPDATE_RESULT_ALPHA(alpha); |
+ dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue); |
+ } |
+ return COMPUTE_RESULT_ALPHA; |
+} |
+ |
+static SkSwizzler::ResultAlpha swizzle_mask32_to_565( |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ |
+ // Use the masks to decode to the destination |
+ uint32_t* srcPtr = (uint32_t*) srcRow; |
+ uint16_t* dstPtr = (uint16_t*) dstRow; |
+ for (int i = 0; i < width; i++) { |
+ uint32_t p = srcPtr[i]; |
+ uint8_t red = masks->getRed(p); |
+ uint8_t green = masks->getGreen(p); |
+ uint8_t blue = masks->getBlue(p); |
+ dstPtr[i] = SkPack888ToRGB16(red, green, blue); |
+ } |
+ return SkSwizzler::kOpaque_ResultAlpha; |
+} |
+ |
/* |
* |
* Create a new mask swizzler |
* |
*/ |
SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
- const SkImageInfo& imageInfo, SkMasks* masks, uint32_t bitsPerPixel) { |
+ const SkImageInfo& info, void* dst, size_t dstRowBytes, SkMasks* masks, |
+ uint32_t bitsPerPixel) { |
// Choose the appropriate row procedure |
RowProc proc = NULL; |
- uint32_t alphaMask = masks->getAlphaMask(); |
switch (bitsPerPixel) { |
case 16: |
- if (0 == alphaMask) { |
- proc = &swizzle_mask16_to_n32; |
- } else { |
- proc = &swizzle_mask16_alpha_to_n32; |
+ switch (info.colorType()) { |
+ case kN32_SkColorType: |
+ switch (info.alphaType()) { |
+ case kUnpremul_SkAlphaType: |
+ proc = &swizzle_mask16_to_n32_unpremul; |
+ break; |
+ case kPremul_SkAlphaType: |
+ proc = &swizzle_mask16_to_n32_premul; |
+ break; |
+ case kOpaque_SkAlphaType: |
+ proc = &swizzle_mask16_to_n32_opaque; |
+ break; |
+ default: |
+ break; |
+ } |
+ break; |
+ case kRGB_565_SkColorType: |
+ switch (info.alphaType()) { |
+ case kOpaque_SkAlphaType: |
+ proc = &swizzle_mask16_to_565; |
+ break; |
+ default: |
+ break; |
+ } |
+ break; |
+ default: |
+ break; |
} |
break; |
case 24: |
- if (0 == alphaMask) { |
- proc = &swizzle_mask24_to_n32; |
- } else { |
- proc = &swizzle_mask24_alpha_to_n32; |
+ switch (info.colorType()) { |
+ case kN32_SkColorType: |
+ switch (info.alphaType()) { |
+ case kUnpremul_SkAlphaType: |
+ proc = &swizzle_mask24_to_n32_unpremul; |
+ break; |
+ case kPremul_SkAlphaType: |
+ proc = &swizzle_mask24_to_n32_premul; |
+ break; |
+ case kOpaque_SkAlphaType: |
+ proc = &swizzle_mask24_to_n32_opaque; |
+ break; |
+ default: |
+ break; |
+ } |
+ break; |
+ case kRGB_565_SkColorType: |
+ switch (info.alphaType()) { |
+ case kOpaque_SkAlphaType: |
+ proc = &swizzle_mask24_to_565; |
+ break; |
+ default: |
+ break; |
+ } |
+ break; |
+ default: |
+ break; |
} |
break; |
case 32: |
- if (0 == alphaMask) { |
- proc = &swizzle_mask32_to_n32; |
- } else { |
- proc = &swizzle_mask32_alpha_to_n32; |
+ switch (info.colorType()) { |
+ case kN32_SkColorType: |
+ switch (info.alphaType()) { |
+ case kUnpremul_SkAlphaType: |
+ proc = &swizzle_mask32_to_n32_unpremul; |
+ break; |
+ case kPremul_SkAlphaType: |
+ proc = &swizzle_mask32_to_n32_premul; |
+ break; |
+ case kOpaque_SkAlphaType: |
+ proc = &swizzle_mask32_to_n32_opaque; |
+ break; |
+ default: |
+ break; |
+ } |
+ break; |
+ case kRGB_565_SkColorType: |
+ switch (info.alphaType()) { |
+ case kOpaque_SkAlphaType: |
+ proc = &swizzle_mask32_to_565; |
+ break; |
+ default: |
+ break; |
+ } |
+ break; |
+ default: |
+ break; |
} |
break; |
default: |
SkASSERT(false); |
return NULL; |
} |
- return SkNEW_ARGS(SkMaskSwizzler, (imageInfo, masks, proc)); |
+ return SkNEW_ARGS(SkMaskSwizzler, (info, dst, dstRowBytes, masks, proc)); |
} |
/* |
@@ -187,19 +329,25 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
* Constructor for mask swizzler |
* |
*/ |
-SkMaskSwizzler::SkMaskSwizzler(const SkImageInfo& imageInfo, |
- SkMasks* masks, RowProc proc) |
- : fImageInfo(imageInfo) |
+SkMaskSwizzler::SkMaskSwizzler(const SkImageInfo& dstInfo, void* dst, |
+ size_t dstRowBytes, SkMasks* masks, RowProc proc) |
+ : fDstInfo(dstInfo) |
+ , fDst(dst) |
+ , fDstRowBytes(dstRowBytes) |
, fMasks(masks) |
, fRowProc(proc) |
{} |
/* |
* |
- * Swizzle the next row |
+ * Swizzle the specified row |
* |
*/ |
-SkSwizzler::ResultAlpha SkMaskSwizzler::next(void* dst, |
- const uint8_t* src) { |
- return fRowProc(dst, src, fImageInfo.width(), fMasks); |
+SkSwizzler::ResultAlpha SkMaskSwizzler::next(const uint8_t* SK_RESTRICT src, |
+ int y) { |
+ // Choose the row |
+ void* row = SkTAddOffset<void>(fDst, y*fDstRowBytes); |
+ |
+ // Decode the row |
+ return fRowProc(row, src, fDstInfo.width(), fMasks); |
} |