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:
parent
6e764859da
commit
183b57f309
@ -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) {}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user