add extractSubset and SkAutoPixmapStorage

extracted from larger CL in progress: https://codereview.chromium.org/1148793007

BUG=skia:
TBR=

Review URL: https://codereview.chromium.org/1162013008
This commit is contained in:
reed 2015-06-05 14:33:17 -07:00 committed by Commit bot
parent 6e764859da
commit 183b57f309
2 changed files with 112 additions and 0 deletions

View File

@ -11,6 +11,7 @@
#include "SkImageInfo.h"
class SkColorTable;
struct SkMask;
/**
* Pairs SkImageInfo with actual pixels and rowbytes. This class does not try to manage the
@ -36,6 +37,23 @@ public:
void reset();
void reset(const SkImageInfo& info, const void* addr, size_t rowBytes,
SkColorTable* ctable = NULL);
void reset(const SkImageInfo& info) {
this->reset(info, NULL, 0, NULL);
}
/**
* If supported, set this pixmap to point to the pixels in the specified mask and return true.
* On failure, return false and set this pixmap to empty.
*/
bool SK_WARN_UNUSED_RESULT reset(const SkMask&);
/**
* Computes the intersection of area and this pixmap. If that intersection is non-empty,
* set subset to that intersection and return true.
*
* On failure, return false and ignore the subset parameter.
*/
bool SK_WARN_UNUSED_RESULT extractSubset(SkPixmap* subset, const SkIRect& area) const;
const SkImageInfo& info() const { return fInfo; }
size_t rowBytes() const { return fRowBytes; }
@ -124,6 +142,35 @@ private:
/////////////////////////////////////////////////////////////////////////////////////////////
class SkAutoPixmapStorage : public SkPixmap {
public:
SkAutoPixmapStorage();
~SkAutoPixmapStorage();
/**
* Try to allocate memory for the pixels needed to match the specified Info. On success
* return true and fill out the pixmap to point to that memory. The storage will be freed
* when this object is destroyed, or if another call to tryAlloc() or alloc() is made.
*
* On failure, return false and reset() the pixmap to empty.
*/
bool tryAlloc(const SkImageInfo&);
/**
* Allocate memory for the pixels needed to match the specified Info and fill out the pixmap
* to point to that memory. The storage will be freed when this object is destroyed,
* or if another call to tryAlloc() or alloc() is made.
*
* If the memory cannot be allocated, calls sk_throw().
*/
void alloc(const SkImageInfo&);
private:
void* fStorage;
};
/////////////////////////////////////////////////////////////////////////////////////////////
class SkAutoPixmapUnlock : ::SkNoncopyable {
public:
SkAutoPixmapUnlock() : fUnlockProc(NULL), fIsLocked(false) {}

View File

@ -6,6 +6,7 @@
*/
#include "SkConfig8888.h"
#include "SkMask.h"
#include "SkPixmap.h"
void SkAutoPixmapUnlock::reset(const SkPixmap& pm, void (*unlock)(void*), void* ctx) {
@ -37,6 +38,37 @@ void SkPixmap::reset(const SkImageInfo& info, const void* addr, size_t rowBytes,
fInfo = info;
}
bool SkPixmap::reset(const SkMask& src) {
if (SkMask::kA8_Format == src.fFormat) {
this->reset(SkImageInfo::MakeA8(src.fBounds.width(), src.fBounds.height()),
src.fImage, src.fRowBytes, NULL);
return true;
}
this->reset();
return false;
}
bool SkPixmap::extractSubset(SkPixmap* result, const SkIRect& subset) const {
SkIRect srcRect, r;
srcRect.set(0, 0, this->width(), this->height());
if (!r.intersect(srcRect, subset)) {
return false; // r is empty (i.e. no intersection)
}
// If the upper left of the rectangle was outside the bounds of this SkBitmap, we should have
// exited above.
SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width()));
SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height()));
const void* pixels = NULL;
if (fPixels) {
const size_t bpp = fInfo.bytesPerPixel();
pixels = (const uint8_t*)fPixels + r.fTop * fRowBytes + r.fLeft * bpp;
}
result->reset(fInfo.makeWH(r.width(), r.height()), pixels, fRowBytes, fCTable);
return true;
}
bool SkPixmap::readPixels(const SkImageInfo& requestedDstInfo, void* dstPixels, size_t dstRB,
int x, int y) const {
if (kUnknown_SkColorType == requestedDstInfo.colorType()) {
@ -72,3 +104,36 @@ bool SkPixmap::readPixels(const SkImageInfo& requestedDstInfo, void* dstPixels,
return SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRB,
srcInfo, srcPixels, this->rowBytes(), this->ctable());
}
//////////////////////////////////////////////////////////////////////////////////////////////////
SkAutoPixmapStorage::SkAutoPixmapStorage() : fStorage(NULL) {}
SkAutoPixmapStorage::~SkAutoPixmapStorage() {
sk_free(fStorage);
}
bool SkAutoPixmapStorage::tryAlloc(const SkImageInfo& info) {
if (fStorage) {
sk_free(fStorage);
fStorage = NULL;
}
size_t rb = info.minRowBytes();
size_t size = info.getSafeSize(rb);
if (0 == size) {
return false;
}
fStorage = sk_malloc_flags(size, 0);
if (NULL == fStorage) {
return false;
}
this->reset(info, fStorage, rb);
return true;
}
void SkAutoPixmapStorage::alloc(const SkImageInfo& info) {
if (!this->tryAlloc(info)) {
sk_throw();
}
}