SkBitmap::ComputeIsOpaque -> SkPixmap::computeIsOpaque
Motivation: Twice internal Skia clients have to do something awkward like this: bool ComputeIsOpaque(const SkPixmap& pixmap) { SkBitmap bm; return bm.installPixels(pixmap) && SkBitmap::ComputeIsOpaque(bm); } Change-Id: I7263c06f754c1305ecb07c4c005d9cfb9d1f523d Reviewed-on: https://skia-review.googlesource.com/5684 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Hal Canary <halcanary@google.com>
This commit is contained in:
parent
e1f29c7b3c
commit
58a769490a
@ -215,7 +215,10 @@ public:
|
||||
* this (isOpaque). Only call this if you need to compute this value from
|
||||
* "unknown" pixels.
|
||||
*/
|
||||
static bool ComputeIsOpaque(const SkBitmap&);
|
||||
static bool ComputeIsOpaque(const SkBitmap& bm) {
|
||||
SkAutoPixmapUnlock result;
|
||||
return bm.requestLock(&result) && result.pixmap().computeIsOpaque();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bitmap's bounds [0, 0, width, height] as an SkRect
|
||||
|
@ -90,6 +90,12 @@ public:
|
||||
uint64_t getSafeSize64() const { return fInfo.getSafeSize64(fRowBytes); }
|
||||
size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
|
||||
|
||||
/**
|
||||
* This will brute-force return true if all of the pixels in the pixmap
|
||||
* are opaque. If there are no pixels, or encounters an error, returns false.
|
||||
*/
|
||||
bool computeIsOpaque() const;
|
||||
|
||||
/**
|
||||
* Converts the pixel at the specified coordinate to an unpremultiplied
|
||||
* SkColor. Note: this ignores any SkColorSpace information, and may return
|
||||
|
@ -562,94 +562,6 @@ void* SkBitmap::getAddr(int x, int y) const {
|
||||
return base;
|
||||
}
|
||||
|
||||
static bool compute_is_opaque(const SkPixmap& pmap) {
|
||||
const int height = pmap.height();
|
||||
const int width = pmap.width();
|
||||
|
||||
switch (pmap.colorType()) {
|
||||
case kAlpha_8_SkColorType: {
|
||||
unsigned a = 0xFF;
|
||||
for (int y = 0; y < height; ++y) {
|
||||
const uint8_t* row = pmap.addr8(0, y);
|
||||
for (int x = 0; x < width; ++x) {
|
||||
a &= row[x];
|
||||
}
|
||||
if (0xFF != a) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} break;
|
||||
case kIndex_8_SkColorType: {
|
||||
const SkColorTable* ctable = pmap.ctable();
|
||||
if (nullptr == ctable) {
|
||||
return false;
|
||||
}
|
||||
const SkPMColor* table = ctable->readColors();
|
||||
SkPMColor c = (SkPMColor)~0;
|
||||
for (int i = ctable->count() - 1; i >= 0; --i) {
|
||||
c &= table[i];
|
||||
}
|
||||
return 0xFF == SkGetPackedA32(c);
|
||||
} break;
|
||||
case kRGB_565_SkColorType:
|
||||
case kGray_8_SkColorType:
|
||||
return true;
|
||||
break;
|
||||
case kARGB_4444_SkColorType: {
|
||||
unsigned c = 0xFFFF;
|
||||
for (int y = 0; y < height; ++y) {
|
||||
const SkPMColor16* row = pmap.addr16(0, y);
|
||||
for (int x = 0; x < width; ++x) {
|
||||
c &= row[x];
|
||||
}
|
||||
if (0xF != SkGetPackedA4444(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} break;
|
||||
case kBGRA_8888_SkColorType:
|
||||
case kRGBA_8888_SkColorType: {
|
||||
SkPMColor c = (SkPMColor)~0;
|
||||
for (int y = 0; y < height; ++y) {
|
||||
const SkPMColor* row = pmap.addr32(0, y);
|
||||
for (int x = 0; x < width; ++x) {
|
||||
c &= row[x];
|
||||
}
|
||||
if (0xFF != SkGetPackedA32(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case kRGBA_F16_SkColorType: {
|
||||
const SkHalf* row = (const SkHalf*)pmap.addr();
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
if (row[4 * x + 3] < SK_Half1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
row += pmap.rowBytes() >> 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) {
|
||||
SkAutoPixmapUnlock result;
|
||||
if (!bm.requestLock(&result)) {
|
||||
return false;
|
||||
}
|
||||
return compute_is_opaque(result.pixmap());
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -332,3 +332,82 @@ SkColor SkPixmap::getColor(int x, int y) const {
|
||||
return SkColorSetARGB(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool SkPixmap::computeIsOpaque() const {
|
||||
const int height = this->height();
|
||||
const int width = this->width();
|
||||
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} break;
|
||||
case kIndex_8_SkColorType: {
|
||||
const SkColorTable* ctable = this->ctable();
|
||||
if (nullptr == ctable) {
|
||||
return false;
|
||||
}
|
||||
const SkPMColor* table = ctable->readColors();
|
||||
SkPMColor c = (SkPMColor)~0;
|
||||
for (int i = ctable->count() - 1; i >= 0; --i) {
|
||||
c &= table[i];
|
||||
}
|
||||
return 0xFF == SkGetPackedA32(c);
|
||||
} break;
|
||||
case kRGB_565_SkColorType:
|
||||
case kGray_8_SkColorType:
|
||||
return true;
|
||||
break;
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} break;
|
||||
case kBGRA_8888_SkColorType:
|
||||
case kRGBA_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)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
row += this->rowBytes() >> 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user