aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/core.gypi1
-rw-r--r--include/core/SkBitmap.h7
-rw-r--r--include/core/SkImage.h1
-rw-r--r--include/core/SkImageInfo.h23
-rw-r--r--include/core/SkPixelRef.h6
-rw-r--r--src/core/SkBitmap.cpp42
-rw-r--r--src/image/SkImagePriv.cpp52
-rw-r--r--src/image/SkImagePriv.h7
-rw-r--r--src/images/SkDecodingImageGenerator.cpp4
-rw-r--r--tests/PixelRefTest.cpp36
10 files changed, 122 insertions, 57 deletions
diff --git a/gyp/core.gypi b/gyp/core.gypi
index 69e8a56882..11da86827e 100644
--- a/gyp/core.gypi
+++ b/gyp/core.gypi
@@ -106,6 +106,7 @@
'<(skia_src_path)/core/SkInstCnt.cpp',
'<(skia_src_path)/core/SkImageFilter.cpp',
'<(skia_src_path)/core/SkImageFilterUtils.cpp',
+ '<(skia_src_path)/core/SkImageInfo.cpp',
'<(skia_src_path)/core/SkLineClipper.cpp',
'<(skia_src_path)/core/SkMallocPixelRef.cpp',
'<(skia_src_path)/core/SkMask.cpp',
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index cd85b6a9b1..c0e299ab94 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -250,6 +250,13 @@ public:
bool setConfig(const SkImageInfo& info, size_t rowBytes = 0);
+ /**
+ * 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;
+
/** Use this to assign a new pixel address for an existing bitmap. This
will automatically release any pixelref previously installed. Only call
this if you are handling ownership/lifetime of the pixel memory.
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index accfc0db79..0bff589f48 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -41,6 +41,7 @@ public:
typedef SkColorType ColorType;
static const SkColorType kAlpha_8_ColorType = kAlpha_8_SkColorType;
+ static const SkColorType kARGB_4444_ColorType = kARGB_4444_SkColorType;
static const SkColorType kRGB_565_ColorType = kRGB_565_SkColorType;
static const SkColorType kRGBA_8888_ColorType = kRGBA_8888_SkColorType;
static const SkColorType kBGRA_8888_ColorType = kBGRA_8888_SkColorType;
diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h
index c22249b842..1165479f74 100644
--- a/include/core/SkImageInfo.h
+++ b/include/core/SkImageInfo.h
@@ -10,6 +10,9 @@
#include "SkTypes.h"
+class SkFlattenableWriteBuffer;
+class SkFlattenableReadBuffer;
+
/**
* Describes how to interpret the alpha compoent of a pixel.
*/
@@ -63,11 +66,12 @@ static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
enum SkColorType {
kAlpha_8_SkColorType,
kRGB_565_SkColorType,
+ kARGB_4444_SkColorType,
kRGBA_8888_SkColorType,
kBGRA_8888_SkColorType,
- kIndex8_SkColorType,
+ kIndex_8_SkColorType,
- kLastEnum_SkColorType = kIndex8_SkColorType,
+ kLastEnum_SkColorType = kIndex_8_SkColorType,
#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
kPMColor_SkColorType = kBGRA_8888_SkColorType
@@ -82,6 +86,7 @@ static int SkColorTypeBytesPerPixel(SkColorType ct) {
static const uint8_t gSize[] = {
1, // Alpha_8
2, // RGB_565
+ 2, // ARGB_4444
4, // RGBA_8888
4, // BGRA_8888
1, // kIndex_8
@@ -112,12 +117,26 @@ struct SkImageInfo {
return SkColorTypeBytesPerPixel(fColorType);
}
+ size_t minRowBytes() const {
+ return fWidth * this->bytesPerPixel();
+ }
+
bool operator==(const SkImageInfo& other) const {
return 0 == memcmp(this, &other, sizeof(other));
}
bool operator!=(const SkImageInfo& other) const {
return 0 != memcmp(this, &other, sizeof(other));
}
+
+ void unflatten(SkFlattenableReadBuffer&);
+ void flatten(SkFlattenableWriteBuffer&) const;
+
+ size_t getSafeSize(size_t rowBytes) const {
+ if (0 == fHeight) {
+ return 0;
+ }
+ return (fHeight - 1) * rowBytes + fWidth * this->bytesPerPixel();
+ }
};
#endif
diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h
index c4a7c4e33d..b87b0dc114 100644
--- a/include/core/SkPixelRef.h
+++ b/include/core/SkPixelRef.h
@@ -60,6 +60,10 @@ public:
SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex);
virtual ~SkPixelRef();
+ const SkImageInfo& info() const {
+ return fInfo;
+ }
+
/** Return the pixel memory returned from lockPixels, or null if the
lockCount is 0.
*/
@@ -291,6 +295,8 @@ protected:
private:
SkBaseMutex* fMutex; // must remain in scope for the life of this object
+ SkImageInfo fInfo;
+
void* fPixels;
SkColorTable* fColorTable; // we do not track ownership, subclass does
int fLockCount;
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 7e204f22d3..25a6b1dba4 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -361,6 +361,48 @@ void SkBitmap::updatePixelsFromRef() const {
}
}
+static bool config_to_colorType(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;
+}
+
+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, size_t offset) {
// do this first, we that we never have a non-zero offset with a null ref
if (NULL == pr) {
diff --git a/src/image/SkImagePriv.cpp b/src/image/SkImagePriv.cpp
index f1916c6c1c..1e24c48c5b 100644
--- a/src/image/SkImagePriv.cpp
+++ b/src/image/SkImagePriv.cpp
@@ -14,13 +14,16 @@ SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo& info) {
case kAlpha_8_SkColorType:
return SkBitmap::kA8_Config;
+ case kARGB_4444_SkColorType:
+ return SkBitmap::kARGB_4444_Config;
+
case kRGB_565_SkColorType:
return SkBitmap::kRGB_565_Config;
-
+
case kPMColor_SkColorType:
return SkBitmap::kARGB_8888_Config;
- case kIndex8_SkColorType:
+ case kIndex_8_SkColorType:
return SkBitmap::kIndex8_Config;
default:
@@ -30,52 +33,9 @@ SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo& info) {
return SkBitmap::kNo_Config;
}
-int SkImageBytesPerPixel(SkColorType ct) {
- static const uint8_t gColorTypeBytesPerPixel[] = {
- 1, // kAlpha_8_SkColorType
- 2, // kRGB_565_SkColorType
- 4, // kRGBA_8888_SkColorType
- 4, // kBGRA_8888_SkColorType
- 4, // kPMColor_SkColorType
- 1, // kIndex8_SkColorType
- };
-
- SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel));
- return gColorTypeBytesPerPixel[ct];
-}
-
-bool SkBitmapToImageInfo(const SkBitmap& bm, SkImageInfo* info) {
- switch (bm.config()) {
- case SkBitmap::kA8_Config:
- info->fColorType = kAlpha_8_SkColorType;
- break;
-
- case SkBitmap::kIndex8_Config:
- info->fColorType = kIndex8_SkColorType;
- break;
-
- case SkBitmap::kRGB_565_Config:
- info->fColorType = kRGB_565_SkColorType;
- break;
-
- case SkBitmap::kARGB_8888_Config:
- info->fColorType = kPMColor_SkColorType;
- break;
-
- default:
- return false;
- }
-
- info->fWidth = bm.width();
- info->fHeight = bm.height();
- info->fAlphaType = bm.isOpaque() ? kOpaque_SkAlphaType :
- kPremul_SkAlphaType;
- return true;
-}
-
SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
SkImageInfo info;
- if (!SkBitmapToImageInfo(bm, &info)) {
+ if (!bm.asImageInfo(&info)) {
return NULL;
}
diff --git a/src/image/SkImagePriv.h b/src/image/SkImagePriv.h
index 188b16d530..bf28f598c5 100644
--- a/src/image/SkImagePriv.h
+++ b/src/image/SkImagePriv.h
@@ -15,10 +15,6 @@ class SkPicture;
extern SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo&);
-extern int SkImageBytesPerPixel(SkColorType);
-
-extern bool SkBitmapToImageInfo(const SkBitmap&, SkImageInfo*);
-
// Call this if you explicitly want to use/share this pixelRef in the image
extern SkImage* SkNewImageFromPixelRef(const SkImageInfo&, SkPixelRef*,
size_t rowBytes);
@@ -48,8 +44,7 @@ extern void SkImagePrivDrawPicture(SkCanvas*, SkPicture*,
extern SkImage* SkNewImageFromPicture(const SkPicture*);
static inline size_t SkImageMinRowBytes(const SkImageInfo& info) {
- size_t rb = info.fWidth * SkImageBytesPerPixel(info.fColorType);
- return SkAlign4(rb);
+ return SkAlign4(info.minRowBytes());
}
// Given an image created from SkNewImageFromBitmap, return its pixelref. This
diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp
index 2b80444141..e49f9a4f24 100644
--- a/src/images/SkDecodingImageGenerator.cpp
+++ b/src/images/SkDecodingImageGenerator.cpp
@@ -119,11 +119,9 @@ bool SkDecodingImageGenerator::getInfo(SkImageInfo* info) {
if (bitmap.config() == SkBitmap::kNo_Config) {
return false;
}
- if (!SkBitmapToImageInfo(bitmap, &fInfo)) {
+ if (!bitmap.asImageInfo(&fInfo)) {
// We can't use bitmap.config() as is.
- // Must be kARGB_4444_Config.
if (!bitmap.canCopyTo(SkBitmap::kARGB_8888_Config)) {
- // kARGB_4444_Config can copy to kARGB_8888.
SkDEBUGFAIL("!bitmap->canCopyTo(SkBitmap::kARGB_8888_Config)");
return false;
}
diff --git a/tests/PixelRefTest.cpp b/tests/PixelRefTest.cpp
index ce2575e830..470221c0fe 100644
--- a/tests/PixelRefTest.cpp
+++ b/tests/PixelRefTest.cpp
@@ -4,6 +4,40 @@
#include "SkPixelRef.h"
#include "SkMallocPixelRef.h"
+static void test_info(skiatest::Reporter* reporter) {
+ static const struct {
+ SkBitmap::Config fConfig;
+ SkAlphaType fAlphaType;
+ SkColorType fExpectedColorType;
+ bool fExpectedSuccess;
+ } gRec[] = {
+ { SkBitmap::kNo_Config, kPremul_SkAlphaType, kPMColor_SkColorType, false },
+ { SkBitmap::kARGB_8888_Config, kPremul_SkAlphaType, kPMColor_SkColorType, true },
+ { SkBitmap::kARGB_8888_Config, kOpaque_SkAlphaType, kPMColor_SkColorType, true },
+ { SkBitmap::kRGB_565_Config, kOpaque_SkAlphaType, kRGB_565_SkColorType, true },
+ { SkBitmap::kARGB_4444_Config, kPremul_SkAlphaType, kARGB_4444_SkColorType, true },
+ { SkBitmap::kARGB_4444_Config, kOpaque_SkAlphaType, kARGB_4444_SkColorType, true },
+ { SkBitmap::kA8_Config, kPremul_SkAlphaType, kAlpha_8_SkColorType, true },
+ { SkBitmap::kA8_Config, kOpaque_SkAlphaType, kAlpha_8_SkColorType, true },
+ { SkBitmap::kIndex8_Config, kPremul_SkAlphaType, kIndex_8_SkColorType, true },
+ { SkBitmap::kIndex8_Config, kOpaque_SkAlphaType, kIndex_8_SkColorType, true },
+ };
+
+ SkBitmap bitmap;
+ SkImageInfo info;
+
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
+ bool success = bitmap.setConfig(gRec[i].fConfig, 10, 10, 0, gRec[i].fAlphaType);
+ REPORTER_ASSERT(reporter, success);
+ success = bitmap.asImageInfo(&info);
+ REPORTER_ASSERT(reporter, success == gRec[i].fExpectedSuccess);
+ if (gRec[i].fExpectedSuccess) {
+ REPORTER_ASSERT(reporter, info.fAlphaType == gRec[i].fAlphaType);
+ REPORTER_ASSERT(reporter, info.fColorType == gRec[i].fExpectedColorType);
+ }
+ }
+}
+
namespace {
class TestListener : public SkPixelRef::GenIDChangeListener {
@@ -46,4 +80,6 @@ DEF_TEST(PixelRef_GenIDChange, r) {
REPORTER_ASSERT(r, 0 != pixelRef.getGenerationID());
pixelRef.addGenIDChangeListener(NULL);
pixelRef.notifyPixelsChanged();
+
+ test_info(r);
}