aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core
diff options
context:
space:
mode:
authorGravatar mike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-02-11 02:20:17 +0000
committerGravatar mike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-02-11 02:20:17 +0000
commit169a0ed50a5e451711c341795572e7177a540a24 (patch)
tree57874a07c8cb6652cedd414e2ba8eed4d8e83d6c /include/core
parent7e90e8dbb96f2084f7dd4a6a20cb4b880b362438 (diff)
SkBitmap now really stores SkImageInfo -- config is just a ruse
Diffstat (limited to 'include/core')
-rw-r--r--include/core/SkBitmap.h114
-rw-r--r--include/core/SkImageInfo.h48
2 files changed, 105 insertions, 57 deletions
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index 87d4649228..ad47dfadf4 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -79,10 +79,42 @@ 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 0 == fWidth || 0 == fHeight; }
+ bool empty() const { return fInfo.isEmpty(); }
/** Return true iff the bitmap has no pixelref. Note: this can return true even if the
* dimensions of the bitmap are > 0 (see empty()).
@@ -95,41 +127,14 @@ public:
bool drawsNothing() const { return this->empty() || this->isNull(); }
/** Return the config for the bitmap. */
- Config config() const { return (Config)fConfig; }
+ Config config() const;
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
@@ -149,19 +154,19 @@ public:
Note this truncates the result to 32bits. Call getSize64() to detect
if the real size exceeds 32bits.
*/
- size_t getSize() const { return fHeight * fRowBytes; }
+ size_t getSize() const { return fInfo.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 ;
+ size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
/**
* Return the full size of the bitmap, in bytes.
*/
int64_t computeSize64() const {
- return sk_64_mul(fHeight, fRowBytes);
+ return sk_64_mul(fInfo.fHeight, fRowBytes);
}
/**
@@ -170,7 +175,7 @@ public:
* than computeSize64() if there is any rowbytes padding beyond the width.
*/
int64_t computeSafeSize64() const {
- return ComputeSafeSize64((Config)fConfig, fWidth, fHeight, fRowBytes);
+ return fInfo.getSafeSize64(fRowBytes);
}
/** Returns true if this bitmap is marked as immutable, meaning that the
@@ -304,11 +309,18 @@ public:
void* context);
/**
- * 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.
+ * DEPRECATED: call info().
*/
- bool asImageInfo(SkImageInfo* info) const;
+ bool asImageInfo(SkImageInfo* info) const {
+ // compatibility: return false for kUnknown
+ if (kUnknown_SkColorType == this->colorType()) {
+ return false;
+ }
+ if (info) {
+ *info = this->info();
+ }
+ return true;
+ }
/** Use this to assign a new pixel address for an existing bitmap. This
will automatically release any pixelref previously installed. Only call
@@ -450,8 +462,8 @@ public:
*/
GrTexture* getTexture() const;
- /** Return the bitmap's colortable, if it uses one (i.e. fConfig is
- kIndex8_Config) and the pixels are locked.
+ /** Return the bitmap's colortable, if it uses one (i.e. colorType is
+ Index_8) and the pixels are locked.
Otherwise returns NULL. Does not affect the colortable's
reference count.
*/
@@ -742,13 +754,11 @@ 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;
@@ -860,29 +870,29 @@ private:
inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
SkASSERT(fPixels);
- SkASSERT(fConfig == kARGB_8888_Config);
- SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
+ SkASSERT(this->config() == kARGB_8888_Config);
+ SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
}
inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
SkASSERT(fPixels);
- SkASSERT(fConfig == kRGB_565_Config || fConfig == kARGB_4444_Config);
- SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
+ SkASSERT(this->config() == kRGB_565_Config || this->config() == kARGB_4444_Config);
+ SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
}
inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
SkASSERT(fPixels);
- SkASSERT(fConfig == kA8_Config || fConfig == kIndex8_Config);
- SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
+ SkASSERT(this->config() == kA8_Config || this->config() == kIndex8_Config);
+ SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
return (uint8_t*)fPixels + y * fRowBytes + x;
}
inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
SkASSERT(fPixels);
- SkASSERT(fConfig == kIndex8_Config);
- SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
+ SkASSERT(this->config() == kIndex8_Config);
+ SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
SkASSERT(fColorTable);
return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
}
diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h
index 722ff27437..73b8b8c12c 100644
--- a/include/core/SkImageInfo.h
+++ b/include/core/SkImageInfo.h
@@ -8,7 +8,7 @@
#ifndef SkImageInfo_DEFINED
#define SkImageInfo_DEFINED
-#include "SkTypes.h"
+#include "SkMath.h"
#include "SkSize.h"
class SkWriteBuffer;
@@ -59,12 +59,17 @@ 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,
@@ -85,6 +90,7 @@ enum SkColorType {
static int SkColorTypeBytesPerPixel(SkColorType ct) {
static const uint8_t gSize[] = {
+ 0, // Unknown
1, // Alpha_8
2, // RGB_565
2, // ARGB_4444
@@ -99,6 +105,14 @@ 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;
+}
+
///////////////////////////////////////////////////////////////////////////////
/**
@@ -159,18 +173,31 @@ 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 fWidth * this->bytesPerPixel();
+ return (size_t)this->minRowBytes64();
}
-
+
bool operator==(const SkImageInfo& other) const {
return 0 == memcmp(this, &other, sizeof(other));
}
@@ -181,12 +208,23 @@ struct SkImageInfo {
void unflatten(SkReadBuffer&);
void flatten(SkWriteBuffer&) const;
- size_t getSafeSize(size_t rowBytes) const {
+ int64_t getSafeSize64(size_t rowBytes) const {
if (0 == fHeight) {
return 0;
}
- return (fHeight - 1) * rowBytes + fWidth * this->bytesPerPixel();
+ return sk_64_mul(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