Revert "SkBitmap now really stores SkImageInfo -- config is just a ruse"
BUG=skia: Review URL: https://codereview.chromium.org/147733004 git-svn-id: http://skia.googlecode.com/svn/trunk@13395 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
b53317c6fa
commit
1195a28892
@ -79,42 +79,10 @@ public:
|
||||
// This method is not exported to java.
|
||||
void swap(SkBitmap& other);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const SkImageInfo& info() const { return fInfo; }
|
||||
|
||||
int width() const { return fInfo.fWidth; }
|
||||
int height() const { return fInfo.fHeight; }
|
||||
SkColorType colorType() const { return fInfo.fColorType; }
|
||||
SkAlphaType alphaType() const { return fInfo.fAlphaType; }
|
||||
|
||||
/** Return the number of bytes per pixel based on the config. If the config
|
||||
does not have at least 1 byte per (e.g. kA1_Config) then 0 is returned.
|
||||
*/
|
||||
int bytesPerPixel() const { return fInfo.bytesPerPixel(); }
|
||||
|
||||
/** Return the rowbytes expressed as a number of pixels (like width and
|
||||
height). Note, for 1-byte per pixel configs like kA8_Config, this will
|
||||
return the same as rowBytes(). Is undefined for configs that are less
|
||||
than 1-byte per pixel (e.g. kA1_Config)
|
||||
*/
|
||||
int rowBytesAsPixels() const {
|
||||
return fRowBytes >> this->shiftPerPixel();
|
||||
}
|
||||
|
||||
/** Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for
|
||||
2-bytes per pixel configs, 2 for 4-bytes per pixel configs). Return 0
|
||||
for configs that are not at least 1-byte per pixel (e.g. kA1_Config
|
||||
or kNo_Config)
|
||||
*/
|
||||
int shiftPerPixel() const { return this->bytesPerPixel() >> 1; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Return true iff the bitmap has empty dimensions.
|
||||
* Hey! Before you use this, see if you really want to know drawsNothing() instead.
|
||||
*/
|
||||
bool empty() const { return fInfo.isEmpty(); }
|
||||
bool empty() const { return 0 == fWidth || 0 == fHeight; }
|
||||
|
||||
/** Return true iff the bitmap has no pixelref. Note: this can return true even if the
|
||||
* dimensions of the bitmap are > 0 (see empty()).
|
||||
@ -127,14 +95,41 @@ public:
|
||||
bool drawsNothing() const { return this->empty() || this->isNull(); }
|
||||
|
||||
/** Return the config for the bitmap. */
|
||||
Config config() const;
|
||||
Config config() const { return (Config)fConfig; }
|
||||
|
||||
SK_ATTR_DEPRECATED("use config()")
|
||||
Config getConfig() const { return this->config(); }
|
||||
|
||||
/** Return the bitmap's width, in pixels. */
|
||||
int width() const { return fWidth; }
|
||||
|
||||
/** Return the bitmap's height, in pixels. */
|
||||
int height() const { return fHeight; }
|
||||
|
||||
/** Return the number of bytes between subsequent rows of the bitmap. */
|
||||
size_t rowBytes() const { return fRowBytes; }
|
||||
|
||||
/** Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for
|
||||
2-bytes per pixel configs, 2 for 4-bytes per pixel configs). Return 0
|
||||
for configs that are not at least 1-byte per pixel (e.g. kA1_Config
|
||||
or kNo_Config)
|
||||
*/
|
||||
int shiftPerPixel() const { return fBytesPerPixel >> 1; }
|
||||
|
||||
/** Return the number of bytes per pixel based on the config. If the config
|
||||
does not have at least 1 byte per (e.g. kA1_Config) then 0 is returned.
|
||||
*/
|
||||
int bytesPerPixel() const { return fBytesPerPixel; }
|
||||
|
||||
/** Return the rowbytes expressed as a number of pixels (like width and
|
||||
height). Note, for 1-byte per pixel configs like kA8_Config, this will
|
||||
return the same as rowBytes(). Is undefined for configs that are less
|
||||
than 1-byte per pixel (e.g. kA1_Config)
|
||||
*/
|
||||
int rowBytesAsPixels() const { return fRowBytes >> (fBytesPerPixel >> 1); }
|
||||
|
||||
SkAlphaType alphaType() const { return (SkAlphaType)fAlphaType; }
|
||||
|
||||
/**
|
||||
* Set the bitmap's alphaType, returning true on success. If false is
|
||||
* returned, then the specified new alphaType is incompatible with the
|
||||
@ -154,19 +149,19 @@ public:
|
||||
Note this truncates the result to 32bits. Call getSize64() to detect
|
||||
if the real size exceeds 32bits.
|
||||
*/
|
||||
size_t getSize() const { return fInfo.fHeight * fRowBytes; }
|
||||
size_t getSize() const { return fHeight * fRowBytes; }
|
||||
|
||||
/** Return the number of bytes from the pointer returned by getPixels()
|
||||
to the end of the allocated space in the buffer. Required in
|
||||
cases where extractSubset has been called.
|
||||
*/
|
||||
size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
|
||||
size_t getSafeSize() const ;
|
||||
|
||||
/**
|
||||
* Return the full size of the bitmap, in bytes.
|
||||
*/
|
||||
int64_t computeSize64() const {
|
||||
return sk_64_mul(fInfo.fHeight, fRowBytes);
|
||||
return sk_64_mul(fHeight, fRowBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,7 +170,7 @@ public:
|
||||
* than computeSize64() if there is any rowbytes padding beyond the width.
|
||||
*/
|
||||
int64_t computeSafeSize64() const {
|
||||
return fInfo.getSafeSize64(fRowBytes);
|
||||
return ComputeSafeSize64((Config)fConfig, fWidth, fHeight, fRowBytes);
|
||||
}
|
||||
|
||||
/** Returns true if this bitmap is marked as immutable, meaning that the
|
||||
@ -309,18 +304,11 @@ public:
|
||||
void* context);
|
||||
|
||||
/**
|
||||
* DEPRECATED: call info().
|
||||
* If the bitmap's config can be represented as SkImageInfo, return true,
|
||||
* and if info is not-null, set it to the bitmap's info. If it cannot be
|
||||
* represented as SkImageInfo, return false and ignore the info parameter.
|
||||
*/
|
||||
bool asImageInfo(SkImageInfo* info) const {
|
||||
// compatibility: return false for kUnknown
|
||||
if (kUnknown_SkColorType == this->colorType()) {
|
||||
return false;
|
||||
}
|
||||
if (info) {
|
||||
*info = this->info();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool asImageInfo(SkImageInfo* info) const;
|
||||
|
||||
/** Use this to assign a new pixel address for an existing bitmap. This
|
||||
will automatically release any pixelref previously installed. Only call
|
||||
@ -462,8 +450,8 @@ public:
|
||||
*/
|
||||
GrTexture* getTexture() const;
|
||||
|
||||
/** Return the bitmap's colortable, if it uses one (i.e. colorType is
|
||||
Index_8) and the pixels are locked.
|
||||
/** Return the bitmap's colortable, if it uses one (i.e. fConfig is
|
||||
kIndex8_Config) and the pixels are locked.
|
||||
Otherwise returns NULL. Does not affect the colortable's
|
||||
reference count.
|
||||
*/
|
||||
@ -754,11 +742,13 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
SkImageInfo fInfo;
|
||||
|
||||
uint32_t fRowBytes;
|
||||
|
||||
uint32_t fWidth;
|
||||
uint32_t fHeight;
|
||||
uint8_t fConfig;
|
||||
uint8_t fAlphaType;
|
||||
uint8_t fFlags;
|
||||
uint8_t fBytesPerPixel; // based on config
|
||||
|
||||
void internalErase(const SkIRect&, U8CPU a, U8CPU r, U8CPU g, U8CPU b)const;
|
||||
|
||||
@ -870,29 +860,29 @@ private:
|
||||
|
||||
inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(this->config() == kARGB_8888_Config);
|
||||
SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
|
||||
SkASSERT(fConfig == kARGB_8888_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
|
||||
}
|
||||
|
||||
inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(this->config() == kRGB_565_Config || this->config() == kARGB_4444_Config);
|
||||
SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
|
||||
SkASSERT(fConfig == kRGB_565_Config || fConfig == kARGB_4444_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
|
||||
}
|
||||
|
||||
inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(this->config() == kA8_Config || this->config() == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
|
||||
SkASSERT(fConfig == kA8_Config || fConfig == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint8_t*)fPixels + y * fRowBytes + x;
|
||||
}
|
||||
|
||||
inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(this->config() == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
|
||||
SkASSERT(fConfig == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
SkASSERT(fColorTable);
|
||||
return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef SkImageInfo_DEFINED
|
||||
#define SkImageInfo_DEFINED
|
||||
|
||||
#include "SkMath.h"
|
||||
#include "SkTypes.h"
|
||||
#include "SkSize.h"
|
||||
|
||||
class SkWriteBuffer;
|
||||
@ -59,17 +59,12 @@ static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
|
||||
return (unsigned)at <= kOpaque_SkAlphaType;
|
||||
}
|
||||
|
||||
static inline bool SkAlphaTypeIsValid(unsigned value) {
|
||||
return value <= kLastEnum_SkAlphaType;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Describes how to interpret the components of a pixel.
|
||||
*/
|
||||
enum SkColorType {
|
||||
kUnknown_SkColorType,
|
||||
kAlpha_8_SkColorType,
|
||||
kRGB_565_SkColorType,
|
||||
kARGB_4444_SkColorType,
|
||||
@ -90,7 +85,6 @@ enum SkColorType {
|
||||
|
||||
static int SkColorTypeBytesPerPixel(SkColorType ct) {
|
||||
static const uint8_t gSize[] = {
|
||||
0, // Unknown
|
||||
1, // Alpha_8
|
||||
2, // RGB_565
|
||||
2, // ARGB_4444
|
||||
@ -105,14 +99,6 @@ static int SkColorTypeBytesPerPixel(SkColorType ct) {
|
||||
return gSize[ct];
|
||||
}
|
||||
|
||||
static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) {
|
||||
return width * SkColorTypeBytesPerPixel(ct);
|
||||
}
|
||||
|
||||
static inline bool SkColorTypeIsValid(unsigned value) {
|
||||
return value <= kLastEnum_SkColorType;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
@ -173,29 +159,16 @@ struct SkImageInfo {
|
||||
return info;
|
||||
}
|
||||
|
||||
int width() const { return fWidth; }
|
||||
int height() const { return fHeight; }
|
||||
SkColorType colorType() const { return fColorType; }
|
||||
SkAlphaType alphaType() const { return fAlphaType; }
|
||||
|
||||
bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; }
|
||||
|
||||
bool isOpaque() const {
|
||||
return SkAlphaTypeIsOpaque(fAlphaType);
|
||||
}
|
||||
|
||||
SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
|
||||
|
||||
int bytesPerPixel() const {
|
||||
return SkColorTypeBytesPerPixel(fColorType);
|
||||
}
|
||||
|
||||
uint64_t minRowBytes64() const {
|
||||
return sk_64_mul(fWidth, this->bytesPerPixel());
|
||||
}
|
||||
|
||||
size_t minRowBytes() const {
|
||||
return (size_t)this->minRowBytes64();
|
||||
return fWidth * this->bytesPerPixel();
|
||||
}
|
||||
|
||||
bool operator==(const SkImageInfo& other) const {
|
||||
@ -208,23 +181,12 @@ struct SkImageInfo {
|
||||
void unflatten(SkReadBuffer&);
|
||||
void flatten(SkWriteBuffer&) const;
|
||||
|
||||
int64_t getSafeSize64(size_t rowBytes) const {
|
||||
size_t getSafeSize(size_t rowBytes) const {
|
||||
if (0 == fHeight) {
|
||||
return 0;
|
||||
}
|
||||
return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel();
|
||||
return (fHeight - 1) * rowBytes + fWidth * this->bytesPerPixel();
|
||||
}
|
||||
|
||||
size_t getSafeSize(size_t rowBytes) const {
|
||||
return (size_t)this->getSafeSize64(rowBytes);
|
||||
}
|
||||
|
||||
bool validRowBytes(size_t rowBytes) const {
|
||||
uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel());
|
||||
return rowBytes >= rb;
|
||||
}
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -106,7 +106,7 @@ public:
|
||||
|
||||
// In some cases we need to inject a leading moveTo before we add points
|
||||
// for lineTo, quadTo, conicTo, cubicTo
|
||||
//
|
||||
//
|
||||
// SkPath path; path.lineTo(...); <--- need a leading moveTo(0, 0)
|
||||
// SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo)
|
||||
void injectMoveToIfNeeded() { fPathRef->injectMoveToIfNeeded(); }
|
||||
|
@ -24,11 +24,6 @@
|
||||
#include "SkPackBits.h"
|
||||
#include <new>
|
||||
|
||||
static bool reset_return_false(SkBitmap* bm) {
|
||||
bm->reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
struct MipLevel {
|
||||
void* fPixels;
|
||||
uint32_t fRowBytes;
|
||||
@ -130,9 +125,13 @@ void SkBitmap::swap(SkBitmap& other) {
|
||||
SkTSwap(fPixelLockCount, other.fPixelLockCount);
|
||||
SkTSwap(fMipMap, other.fMipMap);
|
||||
SkTSwap(fPixels, other.fPixels);
|
||||
SkTSwap(fInfo, other.fInfo);
|
||||
SkTSwap(fRowBytes, other.fRowBytes);
|
||||
SkTSwap(fWidth, other.fWidth);
|
||||
SkTSwap(fHeight, other.fHeight);
|
||||
SkTSwap(fConfig, other.fConfig);
|
||||
SkTSwap(fAlphaType, other.fAlphaType);
|
||||
SkTSwap(fFlags, other.fFlags);
|
||||
SkTSwap(fBytesPerPixel, other.fBytesPerPixel);
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
}
|
||||
@ -142,10 +141,6 @@ void SkBitmap::reset() {
|
||||
sk_bzero(this, sizeof(*this));
|
||||
}
|
||||
|
||||
SkBitmap::Config SkBitmap::config() const {
|
||||
return SkColorTypeToBitmapConfig(fInfo.colorType());
|
||||
}
|
||||
|
||||
int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) {
|
||||
int bpp;
|
||||
switch (config) {
|
||||
@ -172,12 +167,39 @@ int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) {
|
||||
}
|
||||
|
||||
size_t SkBitmap::ComputeRowBytes(Config c, int width) {
|
||||
return SkColorTypeMinRowBytes(SkBitmapConfigToColorType(c), width);
|
||||
if (width < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t rowBytes = 0;
|
||||
|
||||
switch (c) {
|
||||
case kNo_Config:
|
||||
break;
|
||||
case kA8_Config:
|
||||
case kIndex8_Config:
|
||||
rowBytes = width;
|
||||
break;
|
||||
case kRGB_565_Config:
|
||||
case kARGB_4444_Config:
|
||||
// assign and then shift, so we don't overflow int
|
||||
rowBytes = width;
|
||||
rowBytes <<= 1;
|
||||
break;
|
||||
case kARGB_8888_Config:
|
||||
// assign and then shift, so we don't overflow int
|
||||
rowBytes = width;
|
||||
rowBytes <<= 2;
|
||||
break;
|
||||
default:
|
||||
SkDEBUGFAIL("unknown config");
|
||||
break;
|
||||
}
|
||||
return sk_64_isS32(rowBytes) ? sk_64_asS32(rowBytes) : 0;
|
||||
}
|
||||
|
||||
int64_t SkBitmap::ComputeSize64(Config config, int width, int height) {
|
||||
SkColorType ct = SkBitmapConfigToColorType(config);
|
||||
int64_t rowBytes = sk_64_mul(SkColorTypeBytesPerPixel(ct), width);
|
||||
int64_t rowBytes = sk_64_mul(ComputeBytesPerPixel(config), width);
|
||||
return rowBytes * height;
|
||||
}
|
||||
|
||||
@ -190,10 +212,13 @@ int64_t SkBitmap::ComputeSafeSize64(Config config,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
size_t rowBytes) {
|
||||
SkImageInfo info = SkImageInfo::Make(width, height,
|
||||
SkBitmapConfigToColorType(config),
|
||||
kPremul_SkAlphaType);
|
||||
return info.getSafeSize64(rowBytes);
|
||||
int64_t safeSize = 0;
|
||||
if (height > 0) {
|
||||
int64_t lastRow = sk_64_mul(ComputeBytesPerPixel(config), width);
|
||||
safeSize = sk_64_mul(height - 1, rowBytes) + lastRow;
|
||||
}
|
||||
SkASSERT(safeSize >= 0);
|
||||
return safeSize;
|
||||
}
|
||||
|
||||
size_t SkBitmap::ComputeSafeSize(Config config,
|
||||
@ -212,36 +237,35 @@ size_t SkBitmap::ComputeSafeSize(Config config,
|
||||
void SkBitmap::getBounds(SkRect* bounds) const {
|
||||
SkASSERT(bounds);
|
||||
bounds->set(0, 0,
|
||||
SkIntToScalar(fInfo.fWidth), SkIntToScalar(fInfo.fHeight));
|
||||
SkIntToScalar(fWidth), SkIntToScalar(fHeight));
|
||||
}
|
||||
|
||||
void SkBitmap::getBounds(SkIRect* bounds) const {
|
||||
SkASSERT(bounds);
|
||||
bounds->set(0, 0, fInfo.fWidth, fInfo.fHeight);
|
||||
bounds->set(0, 0, fWidth, fHeight);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool validate_alphaType(SkColorType colorType, SkAlphaType alphaType,
|
||||
static bool validate_alphaType(SkBitmap::Config config, SkAlphaType alphaType,
|
||||
SkAlphaType* canonical = NULL) {
|
||||
switch (colorType) {
|
||||
case kUnknown_SkColorType:
|
||||
switch (config) {
|
||||
case SkBitmap::kNo_Config:
|
||||
alphaType = kIgnore_SkAlphaType;
|
||||
break;
|
||||
case kAlpha_8_SkColorType:
|
||||
case SkBitmap::kA8_Config:
|
||||
if (kUnpremul_SkAlphaType == alphaType) {
|
||||
alphaType = kPremul_SkAlphaType;
|
||||
}
|
||||
// fall-through
|
||||
case kIndex_8_SkColorType:
|
||||
case kARGB_4444_SkColorType:
|
||||
case kRGBA_8888_SkColorType:
|
||||
case kBGRA_8888_SkColorType:
|
||||
case SkBitmap::kIndex8_Config:
|
||||
case SkBitmap::kARGB_4444_Config:
|
||||
case SkBitmap::kARGB_8888_Config:
|
||||
if (kIgnore_SkAlphaType == alphaType) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case kRGB_565_SkColorType:
|
||||
case SkBitmap::kRGB_565_Config:
|
||||
alphaType = kOpaque_SkAlphaType;
|
||||
break;
|
||||
default:
|
||||
@ -253,48 +277,52 @@ static bool validate_alphaType(SkColorType colorType, SkAlphaType alphaType,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) {
|
||||
// require that rowBytes fit in 31bits
|
||||
int64_t mrb = info.minRowBytes64();
|
||||
if ((int32_t)mrb != mrb) {
|
||||
return reset_return_false(this);
|
||||
bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes,
|
||||
SkAlphaType alphaType) {
|
||||
if ((width | height) < 0) {
|
||||
goto BAD_CONFIG;
|
||||
}
|
||||
if ((int64_t)rowBytes != (int32_t)rowBytes) {
|
||||
return reset_return_false(this);
|
||||
if (rowBytes == 0) {
|
||||
rowBytes = SkBitmap::ComputeRowBytes(config, width);
|
||||
if (0 == rowBytes && kNo_Config != config && width > 0) {
|
||||
goto BAD_CONFIG;
|
||||
}
|
||||
}
|
||||
|
||||
if (info.width() < 0 || info.height() < 0) {
|
||||
return reset_return_false(this);
|
||||
}
|
||||
|
||||
if (kUnknown_SkColorType == info.colorType()) {
|
||||
rowBytes = 0;
|
||||
} else if (0 == rowBytes) {
|
||||
rowBytes = (size_t)mrb;
|
||||
} else if (rowBytes < info.minRowBytes()) {
|
||||
return reset_return_false(this);
|
||||
if (!validate_alphaType(config, alphaType, &alphaType)) {
|
||||
goto BAD_CONFIG;
|
||||
}
|
||||
|
||||
this->freePixels();
|
||||
|
||||
fInfo = info;
|
||||
fRowBytes = SkToU32(rowBytes);
|
||||
fConfig = SkToU8(config);
|
||||
fAlphaType = SkToU8(alphaType);
|
||||
fWidth = width;
|
||||
fHeight = height;
|
||||
fRowBytes = SkToU32(rowBytes);
|
||||
|
||||
fBytesPerPixel = (uint8_t)ComputeBytesPerPixel(config);
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
return true;
|
||||
|
||||
// if we got here, we had an error, so we reset the bitmap to empty
|
||||
BAD_CONFIG:
|
||||
this->reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes,
|
||||
SkAlphaType alphaType) {
|
||||
SkColorType ct = SkBitmapConfigToColorType(config);
|
||||
return this->setConfig(SkImageInfo::Make(width, height, ct, alphaType),
|
||||
rowBytes);
|
||||
bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) {
|
||||
return this->setConfig(SkImageInfoToBitmapConfig(info), info.fWidth,
|
||||
info.fHeight, rowBytes, info.fAlphaType);
|
||||
}
|
||||
|
||||
bool SkBitmap::setAlphaType(SkAlphaType alphaType) {
|
||||
if (!validate_alphaType(fInfo.fColorType, alphaType, &alphaType)) {
|
||||
if (!validate_alphaType(this->config(), alphaType, &alphaType)) {
|
||||
return false;
|
||||
}
|
||||
if (fInfo.fAlphaType != alphaType) {
|
||||
fInfo.fAlphaType = alphaType;
|
||||
if (fAlphaType != alphaType) {
|
||||
fAlphaType = SkToU8(alphaType);
|
||||
if (fPixelRef) {
|
||||
fPixelRef->changeAlphaType(alphaType);
|
||||
}
|
||||
@ -311,7 +339,7 @@ void SkBitmap::updatePixelsFromRef() const {
|
||||
if (NULL != p) {
|
||||
p = (char*)p
|
||||
+ fPixelRefOrigin.fY * fRowBytes
|
||||
+ fPixelRefOrigin.fX * fInfo.bytesPerPixel();
|
||||
+ fPixelRefOrigin.fX * fBytesPerPixel;
|
||||
}
|
||||
fPixels = p;
|
||||
fColorTable = fPixelRef->colorTable();
|
||||
@ -351,6 +379,20 @@ static bool config_to_colorType(SkBitmap::Config config, SkColorType* ctOut) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkBitmap::asImageInfo(SkImageInfo* info) const {
|
||||
SkColorType ct;
|
||||
if (!config_to_colorType(this->config(), &ct)) {
|
||||
return false;
|
||||
}
|
||||
if (info) {
|
||||
info->fWidth = fWidth;
|
||||
info->fHeight = fHeight;
|
||||
info->fAlphaType = this->alphaType();
|
||||
info->fColorType = ct;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) {
|
||||
#ifdef SK_DEBUG
|
||||
if (pr) {
|
||||
@ -362,7 +404,7 @@ SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) {
|
||||
SkASSERT(info.fColorType == prInfo.fColorType);
|
||||
switch (prInfo.fAlphaType) {
|
||||
case kIgnore_SkAlphaType:
|
||||
SkASSERT(fInfo.fAlphaType == kIgnore_SkAlphaType);
|
||||
SkASSERT(fAlphaType == kIgnore_SkAlphaType);
|
||||
break;
|
||||
case kOpaque_SkAlphaType:
|
||||
case kPremul_SkAlphaType:
|
||||
@ -460,6 +502,11 @@ bool SkBitmap::allocPixels(Allocator* allocator, SkColorTable* ctable) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool reset_return_false(SkBitmap* bm) {
|
||||
bm->reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkBitmap::allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory,
|
||||
SkColorTable* ctable) {
|
||||
if (kIndex_8_SkColorType == info.fColorType && NULL == ctable) {
|
||||
@ -515,6 +562,10 @@ bool SkBitmap::allocConfigPixels(Config config, int width, int height,
|
||||
}
|
||||
|
||||
SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
|
||||
if (!validate_alphaType(config, at, &at)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->allocPixels(SkImageInfo::Make(width, height, ct, at));
|
||||
}
|
||||
|
||||
@ -586,6 +637,13 @@ bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t SkBitmap::getSafeSize() const {
|
||||
// This is intended to be a size_t version of ComputeSafeSize64(), just
|
||||
// faster. The computation is meant to be identical.
|
||||
return (fHeight ? ((fHeight - 1) * fRowBytes) +
|
||||
ComputeRowBytes(this->config(), fWidth): 0);
|
||||
}
|
||||
|
||||
bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize,
|
||||
size_t dstRowBytes, bool preserveDstPad) const {
|
||||
|
||||
@ -593,10 +651,9 @@ bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize,
|
||||
dstRowBytes = fRowBytes;
|
||||
}
|
||||
|
||||
if (dstRowBytes < fInfo.minRowBytes() ||
|
||||
dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) {
|
||||
if (dstRowBytes < ComputeRowBytes(this->config(), fWidth) ||
|
||||
dst == NULL || (getPixels() == NULL && pixelRef() == NULL))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) {
|
||||
size_t safeSize = this->getSafeSize();
|
||||
@ -613,15 +670,16 @@ bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize,
|
||||
}
|
||||
} else {
|
||||
// If destination has different stride than us, then copy line by line.
|
||||
if (fInfo.getSafeSize(dstRowBytes) > dstSize) {
|
||||
if (ComputeSafeSize(this->config(), fWidth, fHeight, dstRowBytes) >
|
||||
dstSize)
|
||||
return false;
|
||||
} else {
|
||||
else {
|
||||
// Just copy what we need on each line.
|
||||
size_t rowBytes = fInfo.minRowBytes();
|
||||
size_t rowBytes = ComputeRowBytes(this->config(), fWidth);
|
||||
SkAutoLockPixels lock(*this);
|
||||
const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels());
|
||||
uint8_t* dstP = reinterpret_cast<uint8_t*>(dst);
|
||||
for (int row = 0; row < fInfo.fHeight;
|
||||
for (uint32_t row = 0; row < fHeight;
|
||||
row++, srcP += fRowBytes, dstP += dstRowBytes) {
|
||||
memcpy(dstP, srcP, rowBytes);
|
||||
}
|
||||
@ -665,19 +723,19 @@ void* SkBitmap::getAddr(int x, int y) const {
|
||||
char* base = (char*)this->getPixels();
|
||||
if (base) {
|
||||
base += y * this->rowBytes();
|
||||
switch (this->colorType()) {
|
||||
case kRGBA_8888_SkColorType:
|
||||
case kBGRA_8888_SkColorType:
|
||||
switch (this->config()) {
|
||||
case SkBitmap::kARGB_8888_Config:
|
||||
base += x << 2;
|
||||
break;
|
||||
case kARGB_4444_SkColorType:
|
||||
case kRGB_565_SkColorType:
|
||||
case SkBitmap::kARGB_4444_Config:
|
||||
case SkBitmap::kRGB_565_Config:
|
||||
base += x << 1;
|
||||
break;
|
||||
case kAlpha_8_SkColorType:
|
||||
case kIndex_8_SkColorType:
|
||||
case SkBitmap::kA8_Config:
|
||||
case SkBitmap::kIndex8_Config:
|
||||
base += x;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
SkDEBUGFAIL("Can't return addr for config");
|
||||
base = NULL;
|
||||
@ -815,12 +873,8 @@ void SkBitmap::internalErase(const SkIRect& area,
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (fInfo.colorType()) {
|
||||
case kUnknown_SkColorType:
|
||||
case kIndex_8_SkColorType:
|
||||
return; // can't erase
|
||||
default:
|
||||
break;
|
||||
if (kNo_Config == fConfig || kIndex8_Config == fConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkAutoLockPixels alp(*this);
|
||||
@ -840,8 +894,8 @@ void SkBitmap::internalErase(const SkIRect& area,
|
||||
b = SkAlphaMul(b, a);
|
||||
}
|
||||
|
||||
switch (this->colorType()) {
|
||||
case kAlpha_8_SkColorType: {
|
||||
switch (fConfig) {
|
||||
case kA8_Config: {
|
||||
uint8_t* p = this->getAddr8(area.fLeft, area.fTop);
|
||||
while (--height >= 0) {
|
||||
memset(p, a, width);
|
||||
@ -849,12 +903,12 @@ void SkBitmap::internalErase(const SkIRect& area,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kARGB_4444_SkColorType:
|
||||
case kRGB_565_SkColorType: {
|
||||
case kARGB_4444_Config:
|
||||
case kRGB_565_Config: {
|
||||
uint16_t* p = this->getAddr16(area.fLeft, area.fTop);;
|
||||
uint16_t v;
|
||||
|
||||
if (kARGB_4444_SkColorType == this->colorType()) {
|
||||
if (kARGB_4444_Config == fConfig) {
|
||||
v = pack_8888_to_4444(a, r, g, b);
|
||||
} else {
|
||||
v = SkPackRGB16(r >> (8 - SK_R16_BITS),
|
||||
@ -867,9 +921,7 @@ void SkBitmap::internalErase(const SkIRect& area,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kPMColor_SkColorType: {
|
||||
// what to do about BGRA or RGBA (which ever is != PMColor ?
|
||||
// for now we don't support them.
|
||||
case kARGB_8888_Config: {
|
||||
uint32_t* p = this->getAddr32(area.fLeft, area.fTop);
|
||||
uint32_t v = SkPackARGB32(a, r, g, b);
|
||||
|
||||
@ -879,8 +931,6 @@ void SkBitmap::internalErase(const SkIRect& area,
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return; // no change, so don't call notifyPixelsChanged()
|
||||
}
|
||||
|
||||
this->notifyPixelsChanged();
|
||||
@ -996,8 +1046,7 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
|
||||
|
||||
if (fPixelRef) {
|
||||
SkIRect subset;
|
||||
subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY,
|
||||
fInfo.width(), fInfo.height());
|
||||
subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, fWidth, fHeight);
|
||||
if (fPixelRef->readPixels(&tmpSrc, &subset)) {
|
||||
SkASSERT(tmpSrc.width() == this->width());
|
||||
SkASSERT(tmpSrc.height() == this->height());
|
||||
@ -1111,8 +1160,6 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
|
||||
}
|
||||
|
||||
bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
|
||||
const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig);
|
||||
|
||||
if (!this->canCopyTo(dstConfig)) {
|
||||
return false;
|
||||
}
|
||||
@ -1123,7 +1170,7 @@ bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
|
||||
SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig);
|
||||
if (pixelRef) {
|
||||
uint32_t rowBytes;
|
||||
if (this->colorType() == dstCT) {
|
||||
if (dstConfig == fConfig) {
|
||||
// Since there is no subset to pass to deepCopy, and deepCopy
|
||||
// succeeded, the new pixel ref must be identical.
|
||||
SkASSERT(fPixelRef->info() == pixelRef->info());
|
||||
@ -1134,12 +1181,7 @@ bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
|
||||
// With the new config, an appropriate fRowBytes will be computed by setConfig.
|
||||
rowBytes = 0;
|
||||
}
|
||||
|
||||
SkImageInfo info = fInfo;
|
||||
info.fColorType = dstCT;
|
||||
if (!dst->setConfig(info, rowBytes)) {
|
||||
return false;
|
||||
}
|
||||
dst->setConfig(dstConfig, fWidth, fHeight, rowBytes);
|
||||
dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref();
|
||||
return true;
|
||||
}
|
||||
@ -1542,8 +1584,11 @@ enum {
|
||||
};
|
||||
|
||||
void SkBitmap::flatten(SkWriteBuffer& buffer) const {
|
||||
fInfo.flatten(buffer);
|
||||
buffer.writeInt(fWidth);
|
||||
buffer.writeInt(fHeight);
|
||||
buffer.writeInt(fRowBytes);
|
||||
buffer.writeInt(fConfig);
|
||||
buffer.writeInt(fAlphaType);
|
||||
|
||||
if (fPixelRef) {
|
||||
if (fPixelRef->getFactory()) {
|
||||
@ -1563,17 +1608,19 @@ void SkBitmap::flatten(SkWriteBuffer& buffer) const {
|
||||
void SkBitmap::unflatten(SkReadBuffer& buffer) {
|
||||
this->reset();
|
||||
|
||||
SkImageInfo info;
|
||||
info.unflatten(buffer);
|
||||
size_t rowBytes = buffer.readInt();
|
||||
buffer.validate((info.width() >= 0) && (info.height() >= 0) &&
|
||||
SkColorTypeIsValid(info.fColorType) &&
|
||||
SkAlphaTypeIsValid(info.fAlphaType) &&
|
||||
validate_alphaType(info.fColorType, info.fAlphaType) &&
|
||||
info.validRowBytes(rowBytes));
|
||||
int width = buffer.readInt();
|
||||
int height = buffer.readInt();
|
||||
int rowBytes = buffer.readInt();
|
||||
Config config = (Config)buffer.readInt();
|
||||
SkAlphaType alphaType = (SkAlphaType)buffer.readInt();
|
||||
buffer.validate((width >= 0) && (height >= 0) && (rowBytes >= 0) &&
|
||||
SkIsValidConfig(config) && validate_alphaType(config, alphaType));
|
||||
|
||||
bool configIsValid = this->setConfig(info, rowBytes);
|
||||
buffer.validate(configIsValid);
|
||||
bool configIsValid = this->setConfig(config, width, height, rowBytes, alphaType);
|
||||
// Note : Using (fRowBytes >= (fWidth * fBytesPerPixel)) in the following test can create false
|
||||
// positives if the multiplication causes an integer overflow. Use the division instead.
|
||||
buffer.validate(configIsValid && (fBytesPerPixel > 0) &&
|
||||
((fRowBytes / fBytesPerPixel) >= fWidth));
|
||||
|
||||
int reftype = buffer.readInt();
|
||||
if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) ||
|
||||
@ -1583,7 +1630,7 @@ void SkBitmap::unflatten(SkReadBuffer& buffer) {
|
||||
SkIPoint origin;
|
||||
origin.fX = buffer.readInt();
|
||||
origin.fY = buffer.readInt();
|
||||
size_t offset = origin.fY * rowBytes + origin.fX * info.bytesPerPixel();
|
||||
size_t offset = origin.fY * rowBytes + origin.fX * fBytesPerPixel;
|
||||
SkPixelRef* pr = buffer.readPixelRef();
|
||||
if (!buffer.validate((NULL == pr) ||
|
||||
(pr->getAllocatedSizeInBytes() >= (offset + this->getSafeSize())))) {
|
||||
@ -1616,14 +1663,15 @@ SkBitmap::RLEPixels::~RLEPixels() {
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void SkBitmap::validate() const {
|
||||
fInfo.validate();
|
||||
SkASSERT(fInfo.validRowBytes(fRowBytes));
|
||||
SkASSERT(fConfig < kConfigCount);
|
||||
SkASSERT(fRowBytes >= (unsigned)ComputeRowBytes((Config)fConfig, fWidth));
|
||||
uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImmutable_Flag;
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
allFlags |= kHasHardwareMipMap_Flag;
|
||||
#endif
|
||||
SkASSERT(fFlags <= allFlags);
|
||||
SkASSERT(fPixelLockCount >= 0);
|
||||
SkASSERT((uint8_t)ComputeBytesPerPixel((Config)fConfig) == fBytesPerPixel);
|
||||
|
||||
if (fPixels) {
|
||||
SkASSERT(fPixelRef);
|
||||
@ -1632,9 +1680,9 @@ void SkBitmap::validate() const {
|
||||
SkASSERT(fPixelRef->rowBytes() == fRowBytes);
|
||||
SkASSERT(fPixelRefOrigin.fX >= 0);
|
||||
SkASSERT(fPixelRefOrigin.fY >= 0);
|
||||
SkASSERT(fPixelRef->info().width() >= (int)this->width() + fPixelRefOrigin.fX);
|
||||
SkASSERT(fPixelRef->info().fHeight >= (int)this->height() + fPixelRefOrigin.fY);
|
||||
SkASSERT(fPixelRef->rowBytes() >= fInfo.minRowBytes());
|
||||
SkASSERT(fPixelRef->info().fWidth >= (int)fWidth + fPixelRefOrigin.fX);
|
||||
SkASSERT(fPixelRef->info().fHeight >= (int)fHeight + fPixelRefOrigin.fY);
|
||||
SkASSERT(fPixelRef->rowBytes() >= fWidth * fBytesPerPixel);
|
||||
} else {
|
||||
SkASSERT(NULL == fColorTable);
|
||||
}
|
||||
@ -1680,14 +1728,3 @@ void SkBitmap::toString(SkString* str) const {
|
||||
str->append(")");
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void SkImageInfo::validate() const {
|
||||
SkASSERT(fWidth >= 0);
|
||||
SkASSERT(fHeight >= 0);
|
||||
SkASSERT(SkColorTypeIsValid(fColorType));
|
||||
SkASSERT(SkAlphaTypeIsValid(fAlphaType));
|
||||
}
|
||||
#endif
|
||||
|
@ -70,7 +70,7 @@ static bool path_needs_SW_renderer(GrContext* context,
|
||||
SkPath::FillType fillType = SkPath::ConvertToNonInverseFillType(origPath.getFillType());
|
||||
|
||||
// the 'false' parameter disallows use of the SW path renderer
|
||||
GrPathRenderer::AutoClearPath acp(context->getPathRenderer(origPath, stroke, gpu,
|
||||
GrPathRenderer::AutoClearPath acp(context->getPathRenderer(origPath, stroke, gpu,
|
||||
false, type, fillType));
|
||||
return NULL == acp.renderer();
|
||||
}
|
||||
@ -310,7 +310,7 @@ void setup_boolean_blendcoeffs(GrDrawState* drawState, SkRegion::Op op) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool GrClipMaskManager::drawFilledPath(GrTexture* target,
|
||||
GrPathRenderer* pathRenderer,
|
||||
GrPathRenderer* pathRenderer,
|
||||
bool isAA) {
|
||||
GrDrawState* drawState = fGpu->drawState();
|
||||
|
||||
@ -349,7 +349,7 @@ bool GrClipMaskManager::drawElement(GrTexture* target,
|
||||
GrPathRendererChain::kColor_DrawType;
|
||||
SkPath::FillType fillType = element->getPath().getFillType();
|
||||
GrPathRenderer::AutoClearPath acp(this->getContext()->getPathRenderer(
|
||||
element->getPath(),
|
||||
element->getPath(),
|
||||
stroke, fGpu, false, type,
|
||||
SkPath::ConvertToNonInverseFillType(fillType)));
|
||||
if (NULL == acp.renderer()) {
|
||||
@ -381,9 +381,9 @@ bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target,
|
||||
GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
|
||||
GrPathRendererChain::kStencilAndColor_DrawType;
|
||||
SkPath::FillType fillType = element->getPath().getFillType();
|
||||
acp->set(this->getContext()->getPathRenderer(element->getPath(),
|
||||
acp->set(this->getContext()->getPathRenderer(element->getPath(),
|
||||
stroke, fGpu, false, type,
|
||||
SkPath::ConvertToNonInverseFillType(fillType)));
|
||||
SkPath::ConvertToNonInverseFillType(fillType)));
|
||||
return NULL != acp->renderer();
|
||||
}
|
||||
default:
|
||||
|
@ -141,7 +141,7 @@ private:
|
||||
// Determines whether it is possible to draw the element to both the stencil buffer and the
|
||||
// alpha mask simultaneously. If so and the element is a path a compatible path renderer is
|
||||
// also returned.
|
||||
bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*,
|
||||
bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*,
|
||||
GrPathRenderer::AutoClearPath* pr);
|
||||
|
||||
void mergeMask(GrTexture* dstMask,
|
||||
|
@ -1155,7 +1155,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
|
||||
SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
|
||||
|
||||
// Try a 1st time without stroking the path and without allowing the SW renderer
|
||||
GrPathRenderer::AutoClearPath acp(this->getPathRenderer(*pathPtr, *stroke,
|
||||
GrPathRenderer::AutoClearPath acp(this->getPathRenderer(*pathPtr, *stroke,
|
||||
target, false, type,
|
||||
pathPtr->getFillType()));
|
||||
|
||||
|
@ -100,8 +100,8 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this path renderer is able to render the current path. Returning false
|
||||
* allows the caller to fallback to another path renderer This function is called when
|
||||
* Returns true if this path renderer is able to render the current path. Returning false
|
||||
* allows the caller to fallback to another path renderer This function is called when
|
||||
* searching for a path renderer capable of rendering a path.
|
||||
*
|
||||
* @param stroke The stroke information (width, join, cap)
|
||||
@ -114,8 +114,8 @@ public:
|
||||
const GrDrawTarget* target,
|
||||
bool antiAlias) const = 0;
|
||||
/**
|
||||
* Draws the current path into the draw target. If getStencilSupport() would return
|
||||
* kNoRestriction then the subclass must respect the stencil settings of the
|
||||
* Draws the current path into the draw target. If getStencilSupport() would return
|
||||
* kNoRestriction then the subclass must respect the stencil settings of the
|
||||
* target's draw state.
|
||||
*
|
||||
* @param stroke the stroke information (width, join, cap)
|
||||
@ -134,7 +134,7 @@ public:
|
||||
|
||||
/**
|
||||
* Draws the current path to the stencil buffer. Assume the writable stencil bits are already
|
||||
* initialized to zero. The pixels inside the path will have non-zero stencil values
|
||||
* initialized to zero. The pixels inside the path will have non-zero stencil values
|
||||
* afterwards.
|
||||
*
|
||||
* @param stroke the stroke information (width, join, cap)
|
||||
|
@ -37,19 +37,35 @@ SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo& info) {
|
||||
return SkColorTypeToBitmapConfig(info.fColorType);
|
||||
}
|
||||
|
||||
SkColorType SkBitmapConfigToColorType(SkBitmap::Config config) {
|
||||
static const SkColorType gCT[] = {
|
||||
kUnknown_SkColorType, // kNo_Config
|
||||
kAlpha_8_SkColorType, // kA8_Config
|
||||
kIndex_8_SkColorType, // kIndex8_Config
|
||||
kRGB_565_SkColorType, // kRGB_565_Config
|
||||
kARGB_4444_SkColorType, // kARGB_4444_Config
|
||||
kPMColor_SkColorType, // kARGB_8888_Config
|
||||
};
|
||||
SkASSERT((unsigned)config < SK_ARRAY_COUNT(gCT));
|
||||
return gCT[config];
|
||||
bool SkBitmapConfigToColorType(SkBitmap::Config config, SkColorType* ctOut) {
|
||||
SkColorType ct;
|
||||
switch (config) {
|
||||
case SkBitmap::kA8_Config:
|
||||
ct = kAlpha_8_SkColorType;
|
||||
break;
|
||||
case SkBitmap::kIndex8_Config:
|
||||
ct = kIndex_8_SkColorType;
|
||||
break;
|
||||
case SkBitmap::kRGB_565_Config:
|
||||
ct = kRGB_565_SkColorType;
|
||||
break;
|
||||
case SkBitmap::kARGB_4444_Config:
|
||||
ct = kARGB_4444_SkColorType;
|
||||
break;
|
||||
case SkBitmap::kARGB_8888_Config:
|
||||
ct = kPMColor_SkColorType;
|
||||
break;
|
||||
case SkBitmap::kNo_Config:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (ctOut) {
|
||||
*ctOut = ct;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
|
||||
SkImageInfo info;
|
||||
if (!bm.asImageInfo(&info)) {
|
||||
|
@ -15,7 +15,7 @@ class SkPicture;
|
||||
|
||||
extern SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo&);
|
||||
extern SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType);
|
||||
extern SkColorType SkBitmapConfigToColorType(SkBitmap::Config);
|
||||
extern bool SkBitmapConfigToColorType(SkBitmap::Config, SkColorType* ctOut);
|
||||
|
||||
// Call this if you explicitly want to use/share this pixelRef in the image
|
||||
extern SkImage* SkNewImageFromPixelRef(const SkImageInfo&, SkPixelRef*,
|
||||
|
@ -275,6 +275,11 @@ SkImageGenerator* SkDecodingImageGenerator::Create(
|
||||
info.fHeight = bitmap.height();
|
||||
info.fColorType = opts.fRequestedColorType;
|
||||
info.fAlphaType = bitmap.alphaType();
|
||||
|
||||
// Sanity check.
|
||||
SkDEBUGCODE(SkColorType tmp;)
|
||||
SkASSERT(SkBitmapConfigToColorType(config, &tmp));
|
||||
SkASSERT(tmp == opts.fRequestedColorType);
|
||||
}
|
||||
return SkNEW_ARGS(SkDecodingImageGenerator,
|
||||
(data, autoStream.detach(), info,
|
||||
|
@ -333,7 +333,10 @@ static SkPixelRef* install_pixel_ref(SkBitmap* bitmap,
|
||||
SkASSERT(stream != NULL);
|
||||
SkASSERT(stream->rewind());
|
||||
SkASSERT(stream->unique());
|
||||
SkColorType colorType = bitmap->colorType();
|
||||
SkColorType colorType;
|
||||
if (!SkBitmapConfigToColorType(bitmap->config(), &colorType)) {
|
||||
return NULL;
|
||||
}
|
||||
SkDecodingImageGenerator::Options opts(sampleSize, ditherImage, colorType);
|
||||
SkAutoTDelete<SkImageGenerator> gen(
|
||||
SkDecodingImageGenerator::Create(stream, opts));
|
||||
|
Loading…
Reference in New Issue
Block a user