make info real in SkPixelRef, and add bitmap::asImageInfo
BUG= R=scroggo@google.com Review URL: https://codereview.chromium.org/108663004 git-svn-id: http://skia.googlecode.com/svn/trunk@12586 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
331e237890
commit
9230ea2971
@ -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',
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user