Index: src/codec/SkMaskSwizzler.cpp |
diff --git a/src/codec/SkMaskSwizzler.cpp b/src/codec/SkMaskSwizzler.cpp |
index 8d9f6c66b3ac007e955118b872d244b52614ea3b..6e7c5f1a3a81c422a757294dc34776a87e84d6eb 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,62 @@ 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_opaque( |
+ 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_mask16_to_565_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; |
+ uint16_t* dstPtr = (uint16_t*) 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] = SkPixel32ToPixel16( |
+ SkPreMultiplyARGB(alpha, red, green, blue)); |
+ } |
+ return COMPUTE_RESULT_ALPHA; |
+} |
+ |
+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 +114,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 +132,59 @@ 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_opaque( |
+ 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_mask24_to_565_premul( |
+ void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) { |
+ |
+ // Use the masks to decode to the destination |
+ uint16_t* dstPtr = (uint16_t*) 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] = SkPixel32ToPixel16( |
+ SkPreMultiplyARGB(alpha, red, green, blue)); |
+ } |
+ return COMPUTE_RESULT_ALPHA; |
+} |
+ |
+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 +200,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 +219,170 @@ 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_opaque( |
+ 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; |
+} |
+ |
+static SkSwizzler::ResultAlpha swizzle_mask32_to_565_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; |
+ uint16_t* dstPtr = (uint16_t*) 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] = SkPixel32ToPixel16( |
+ SkPreMultiplyARGB(alpha, red, green, blue)); |
+ } |
+ return COMPUTE_RESULT_ALPHA; |
+} |
+ |
/* |
* |
* Create a new mask swizzler |
* |
*/ |
SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( |
- const SkImageInfo& imageInfo, SkMasks* masks, uint32_t bitsPerPixel) { |
+ const SkImageInfo& info, 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; |
+ default: |
+ break; |
+ } |
+ break; |
+ case kRGB_565_SkColorType: |
+ switch (info.alphaType()) { |
+ case kPremul_SkAlphaType: |
+ proc = &swizzle_mask16_to_565_premul; |
scroggo
2015/03/17 13:27:22
565 is only opaque, so we 565 premul does not make
msarett
2015/03/17 16:54:06
That's good news. Reduces the number of cases and
|
+ break; |
+ case kOpaque_SkAlphaType: |
+ proc = &swizzle_mask16_to_565_opaque; |
+ 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; |
+ default: |
+ break; |
+ } |
+ break; |
+ case kRGB_565_SkColorType: |
+ switch (info.alphaType()) { |
+ case kPremul_SkAlphaType: |
+ proc = &swizzle_mask24_to_565_premul; |
+ break; |
+ case kOpaque_SkAlphaType: |
+ proc = &swizzle_mask24_to_565_opaque; |
+ 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; |
+ default: |
+ break; |
+ } |
+ break; |
+ case kRGB_565_SkColorType: |
+ switch (info.alphaType()) { |
+ case kPremul_SkAlphaType: |
+ proc = &swizzle_mask32_to_565_premul; |
+ break; |
+ case kOpaque_SkAlphaType: |
+ proc = &swizzle_mask32_to_565_opaque; |
+ default: |
+ break; |
+ } |
+ break; |
+ default: |
+ break; |
} |
break; |
default: |
SkASSERT(false); |
return NULL; |
} |
- return SkNEW_ARGS(SkMaskSwizzler, (imageInfo, masks, proc)); |
+ return SkNEW_ARGS(SkMaskSwizzler, (info, masks, proc)); |
} |
/* |