bool SkPixmap::extractSubset(SkPixmap* result, const SkIRect& subset) const {
SkIRect srcRect, r;
srcRect.setWH(this->width(), this->height()); if (!r.intersect(srcRect, subset)) { returnfalse; // r is empty (i.e. no intersection)
}
// If the upper left of the rectangle was outside the bounds of this SkBitmap, we should have // exited above.
SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width()));
SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height()));
// This is the same as SkPixmap::addr(x,y), but this version gets inlined, while the public // method does not. Perhaps we could bloat it so it can be inlined, but that would grow code-size // everywhere, instead of just here (on behalf of getAlphaf()). staticconstvoid* fast_getaddr(const SkPixmap& pm, int x, int y) {
x <<= SkColorTypeShiftPerPixel(pm.colorType()); returnstatic_cast<constchar*>(pm.addr()) + y * pm.rowBytes() + x;
}
float value = 0; constvoid* srcPtr = fast_getaddr(*this, x, y);
switch (this->colorType()) { case kUnknown_SkColorType: return 0; case kGray_8_SkColorType: case kR8G8_unorm_SkColorType: case kR16G16_unorm_SkColorType: case kR16G16_float_SkColorType: case kRGB_565_SkColorType: case kRGB_888x_SkColorType: case kRGB_101010x_SkColorType: case kBGR_101010x_SkColorType: case kBGR_101010x_XR_SkColorType: case kRGB_F16F16F16x_SkColorType: case kR8_unorm_SkColorType: return 1; case kAlpha_8_SkColorType:
value = static_cast<const uint8_t*>(srcPtr)[0] * (1.0f/255); break; case kA16_unorm_SkColorType:
value = static_cast<const uint16_t*>(srcPtr)[0] * (1.0f/65535); break; case kA16_float_SkColorType: {
SkHalf half = static_cast<const SkHalf*>(srcPtr)[0];
value = SkHalfToFloat(half); break;
} case kARGB_4444_SkColorType: {
uint16_t u16 = static_cast<const uint16_t*>(srcPtr)[0];
value = SkGetPackedA4444(u16) * (1.0f/15); break;
} case kRGBA_8888_SkColorType: case kBGRA_8888_SkColorType: case kSRGBA_8888_SkColorType:
value = static_cast<const uint8_t*>(srcPtr)[3] * (1.0f/255); break; case kRGBA_1010102_SkColorType: case kBGRA_1010102_SkColorType: {
uint32_t u32 = static_cast<const uint32_t*>(srcPtr)[0];
value = (u32 >> 30) * (1.0f/3); break;
} case kBGRA_10101010_XR_SkColorType: {
uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
value = ((u64 >> 54) - 384) / 510.f; break;
} case kRGBA_10x6_SkColorType: {
uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
value = (u64 >> 54) * (1.0f/1023); break;
} case kR16G16B16A16_unorm_SkColorType: {
uint64_t u64 = static_cast<const uint64_t*>(srcPtr)[0];
value = (u64 >> 48) * (1.0f/65535); break;
} case kRGBA_F16Norm_SkColorType: case kRGBA_F16_SkColorType: {
value = from_half(skvx::half4::Load(srcPtr))[3]; break;
} case kRGBA_F32_SkColorType:
value = static_cast<constfloat*>(srcPtr)[3]; break;
} return value;
}
bool SkPixmap::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB, int x, int y) const { if (!SkImageInfoValidConversion(dstInfo, fInfo)) { returnfalse;
}
switch (this->colorType()) { case kAlpha_8_SkColorType: { unsigned a = 0xFF; for (int y = 0; y < height; ++y) { const uint8_t* row = this->addr8(0, y); for (int x = 0; x < width; ++x) {
a &= row[x];
} if (0xFF != a) { returnfalse;
}
} returntrue;
} case kA16_unorm_SkColorType: { unsigned a = 0xFFFF; for (int y = 0; y < height; ++y) { const uint16_t* row = this->addr16(0, y); for (int x = 0; x < width; ++x) {
a &= row[x];
} if (0xFFFF != a) { returnfalse;
}
} returntrue;
} case kA16_float_SkColorType: { for (int y = 0; y < height; ++y) { const SkHalf* row = this->addr16(0, y); for (int x = 0; x < width; ++x) { if (row[x] < SK_Half1) { returnfalse;
}
}
} returntrue;
} case kRGB_565_SkColorType: case kGray_8_SkColorType: case kR8G8_unorm_SkColorType: case kR16G16_unorm_SkColorType: case kR16G16_float_SkColorType: case kRGB_888x_SkColorType: case kRGB_101010x_SkColorType: case kBGR_101010x_SkColorType: case kRGB_F16F16F16x_SkColorType: case kBGR_101010x_XR_SkColorType: case kR8_unorm_SkColorType: returntrue; case kARGB_4444_SkColorType: { unsigned c = 0xFFFF; for (int y = 0; y < height; ++y) { const SkPMColor16* row = this->addr16(0, y); for (int x = 0; x < width; ++x) {
c &= row[x];
} if (0xF != SkGetPackedA4444(c)) { returnfalse;
}
} returntrue;
} case kBGRA_8888_SkColorType: case kRGBA_8888_SkColorType: case kSRGBA_8888_SkColorType: {
SkPMColor c = (SkPMColor)~0; for (int y = 0; y < height; ++y) { const SkPMColor* row = this->addr32(0, y); for (int x = 0; x < width; ++x) {
c &= row[x];
} if (0xFF != SkGetPackedA32(c)) { returnfalse;
}
} returntrue;
} case kRGBA_F16Norm_SkColorType: case kRGBA_F16_SkColorType: { const SkHalf* row = (const SkHalf*)this->addr(); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { if (row[4 * x + 3] < SK_Half1) { returnfalse;
}
}
row += this->rowBytes() >> 1;
} returntrue;
} case kRGBA_F32_SkColorType: { constfloat* row = (constfloat*)this->addr(); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { if (row[4 * x + 3] < 1.0f) { returnfalse;
}
}
row += this->rowBytes() >> 2;
} returntrue;
} case kRGBA_1010102_SkColorType: case kBGRA_1010102_SkColorType: {
uint32_t c = ~0; for (int y = 0; y < height; ++y) { const uint32_t* row = this->addr32(0, y); for (int x = 0; x < width; ++x) {
c &= row[x];
} if (0b11 != c >> 30) { returnfalse;
}
} returntrue;
} case kBGRA_10101010_XR_SkColorType:{ static constexpr uint64_t kOne = 510 + 384; for (int y = 0; y < height; ++y) { const uint64_t* row = this->addr64(0, y); for (int x = 0; x < width; ++x) { if ((row[x] >> 54) < kOne) { returnfalse;
}
}
} returntrue;
} case kRGBA_10x6_SkColorType: {
uint16_t acc = 0xFFC0; // Ignore bottom six bits for (int y = 0; y < height; ++y) { const uint64_t* row = this->addr64(0, y); for (int x = 0; x < width; ++x) {
acc &= (row[x] >> 48);
} if (0xFFC0 != acc) { returnfalse;
}
} returntrue;
} case kR16G16B16A16_unorm_SkColorType: {
uint16_t acc = 0xFFFF; for (int y = 0; y < height; ++y) { const uint64_t* row = this->addr64(0, y); for (int x = 0; x < width; ++x) {
acc &= (row[x] >> 48);
} if (0xFFFF != acc) { returnfalse;
}
} returntrue;
} case kUnknown_SkColorType:
SkDEBUGFAIL(""); break;
} returnfalse;
}
SkIRect clip = this->bounds(); if (subset && !clip.intersect(*subset)) { returnfalse; // is this check really needed (i.e. to return false in this case?)
}
// Erase is meant to simulate drawing in kSRC mode -- which means we have to convert out // unpremul input into premul (which we always do when we draw). constauto c = color.premul();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.