aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2018-03-06 08:43:22 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-06 19:43:46 +0000
commit18e9ba1eddb09bff6083f9a83dc569d3b3b54fe6 (patch)
tree7a7808805687ae43f56a678acc57e1b0fae33f5f /src
parent94458ee0f2be19392042084f181b41308ae63624 (diff)
support 888x, 1010102, and 101010x in SkPixmap::erase()
... and a few more methods to make it possible to write the new test. Bug: oss-fuzz:6606 Change-Id: Ie8dd221059579248405f165a93c324c8ba518fd4 Reviewed-on: https://skia-review.googlesource.com/112400 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBitmap.cpp3
-rw-r--r--src/core/SkPixmap.cpp69
2 files changed, 67 insertions, 5 deletions
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 7223fdb828..a9d5fe8963 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -384,8 +384,11 @@ void* SkBitmap::getAddr(int x, int y) const {
case kRGBA_F16_SkColorType:
base += x << 3;
break;
+ case kRGB_888x_SkColorType:
case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
+ case kRGB_101010x_SkColorType:
+ case kRGBA_1010102_SkColorType:
base += x << 2;
break;
case kARGB_4444_SkColorType:
diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp
index 19d1d65caa..852ffb0b33 100644
--- a/src/core/SkPixmap.cpp
+++ b/src/core/SkPixmap.cpp
@@ -150,6 +150,7 @@ bool SkPixmap::erase(SkColor color, const SkIRect& inArea) const {
}
break;
}
+
case kARGB_4444_SkColorType:
case kRGB_565_SkColorType: {
uint16_t* p = this->writable_addr16(area.fLeft, area.fTop);
@@ -175,8 +176,11 @@ bool SkPixmap::erase(SkColor color, const SkIRect& inArea) const {
}
break;
}
- case kBGRA_8888_SkColorType:
- case kRGBA_8888_SkColorType: {
+
+ case kRGB_888x_SkColorType:
+ a = 255; // then fallthrough to 8888
+ case kRGBA_8888_SkColorType:
+ case kBGRA_8888_SkColorType: {
uint32_t* p = this->writable_addr32(area.fLeft, area.fTop);
if (255 != a && kPremul_SkAlphaType == this->alphaType()) {
@@ -184,16 +188,42 @@ bool SkPixmap::erase(SkColor color, const SkIRect& inArea) const {
g = SkMulDiv255Round(g, a);
b = SkMulDiv255Round(b, a);
}
- uint32_t v = kRGBA_8888_SkColorType == this->colorType()
- ? SkPackARGB_as_RGBA(a, r, g, b)
- : SkPackARGB_as_BGRA(a, r, g, b);
+ uint32_t v = kBGRA_8888_SkColorType == this->colorType()
+ ? SkPackARGB_as_BGRA(a, r, g, b) // bgra 8888
+ : SkPackARGB_as_RGBA(a, r, g, b); // rgba 8888 or rgb 888
+
+ while (--height >= 0) {
+ sk_memset32(p, v, width);
+ p = (uint32_t*)((char*)p + rowBytes);
+ }
+ break;
+ }
+ case kRGB_101010x_SkColorType:
+ a = 255; // then fallthrough to 1010102
+ case kRGBA_1010102_SkColorType: {
+ uint32_t* p = this->writable_addr32(area.fLeft, area.fTop);
+
+ float R = r * (1/255.0f),
+ G = g * (1/255.0f),
+ B = b * (1/255.0f),
+ A = a * (1/255.0f);
+ if (a != 255 && this->alphaType() == kPremul_SkAlphaType) {
+ R *= A;
+ G *= A;
+ B *= A;
+ }
+ uint32_t v = (uint32_t)(R * 1023.0f) << 0
+ | (uint32_t)(G * 1023.0f) << 10
+ | (uint32_t)(B * 1023.0f) << 20
+ | (uint32_t)(A * 3.0f) << 30;
while (--height >= 0) {
sk_memset32(p, v, width);
p = (uint32_t*)((char*)p + rowBytes);
}
break;
}
+
case kRGBA_F16_SkColorType:
// The colorspace is unspecified, so assume linear just like getColor().
this->erase(SkColor4f{(1 / 255.0f) * r,
@@ -321,6 +351,10 @@ SkColor SkPixmap::getColor(int x, int y) const {
SkPMColor c = SkPixel4444ToPixel32(value);
return toColor(c);
}
+ case kRGB_888x_SkColorType: {
+ uint32_t value = *this->addr32(x, y);
+ return SkSwizzle_RB(value | 0xff000000);
+ }
case kBGRA_8888_SkColorType: {
uint32_t value = *this->addr32(x, y);
SkPMColor c = SkSwizzle_BGRA_to_PMColor(value);
@@ -331,6 +365,31 @@ SkColor SkPixmap::getColor(int x, int y) const {
SkPMColor c = SkSwizzle_RGBA_to_PMColor(value);
return toColor(c);
}
+ case kRGB_101010x_SkColorType: {
+ uint32_t value = *this->addr32(x, y);
+ // Convert 10-bit rgb to 8-bit bgr, and mask in 0xff alpha at the top.
+ return (uint32_t)( ((value >> 0) & 0x3ff) * (255/1023.0f) ) << 16
+ | (uint32_t)( ((value >> 10) & 0x3ff) * (255/1023.0f) ) << 8
+ | (uint32_t)( ((value >> 20) & 0x3ff) * (255/1023.0f) ) << 0
+ | 0xff000000;
+ }
+ case kRGBA_1010102_SkColorType: {
+ uint32_t value = *this->addr32(x, y);
+
+ float r = ((value >> 0) & 0x3ff) * (1/1023.0f),
+ g = ((value >> 10) & 0x3ff) * (1/1023.0f),
+ b = ((value >> 20) & 0x3ff) * (1/1023.0f),
+ a = ((value >> 30) & 0x3 ) * (1/ 3.0f);
+ if (a != 0 && needsUnpremul) {
+ r *= (1.0f/a);
+ g *= (1.0f/a);
+ b *= (1.0f/a);
+ }
+ return (uint32_t)( r * 255.0f ) << 16
+ | (uint32_t)( g * 255.0f ) << 8
+ | (uint32_t)( b * 255.0f ) << 0
+ | (uint32_t)( a * 255.0f ) << 24;
+ }
case kRGBA_F16_SkColorType: {
const uint64_t* addr =
(const uint64_t*)fPixels + y * (fRowBytes >> 3) + x;