diff options
-rw-r--r-- | gyp/core.gypi | 1 | ||||
-rw-r--r-- | include/core/SkBitmap.h | 7 | ||||
-rw-r--r-- | include/core/SkImage.h | 1 | ||||
-rw-r--r-- | include/core/SkImageInfo.h | 23 | ||||
-rw-r--r-- | include/core/SkPixelRef.h | 6 | ||||
-rw-r--r-- | src/core/SkBitmap.cpp | 42 | ||||
-rw-r--r-- | src/image/SkImagePriv.cpp | 52 | ||||
-rw-r--r-- | src/image/SkImagePriv.h | 7 | ||||
-rw-r--r-- | src/images/SkDecodingImageGenerator.cpp | 4 | ||||
-rw-r--r-- | tests/PixelRefTest.cpp | 36 |
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); } |