aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkBitmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/SkBitmap.cpp')
-rw-r--r--src/core/SkBitmap.cpp188
1 files changed, 49 insertions, 139 deletions
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index c0d93957ac..cb8ac7231b 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -129,7 +129,7 @@ SkBitmap& SkBitmap::operator=(const SkBitmap& src) {
void SkBitmap::swap(SkBitmap& other) {
SkTSwap(fColorTable, other.fColorTable);
SkTSwap(fPixelRef, other.fPixelRef);
- SkTSwap(fPixelRefOffset, other.fPixelRefOffset);
+ SkTSwap(fPixelRefOrigin, other.fPixelRefOrigin);
SkTSwap(fPixelLockCount, other.fPixelLockCount);
SkTSwap(fMipMap, other.fMipMap);
SkTSwap(fPixels, other.fPixels);
@@ -340,7 +340,9 @@ void SkBitmap::updatePixelsFromRef() const {
void* p = fPixelRef->pixels();
if (NULL != p) {
- p = (char*)p + fPixelRefOffset;
+ p = (char*)p
+ + fPixelRef->rowBytes() * fPixelRefOrigin.fY
+ + fPixelRefOrigin.fX * fBytesPerPixel;
}
fPixels = p;
SkRefCnt_SafeAssign(fColorTable, fPixelRef->colorTable());
@@ -397,13 +399,9 @@ bool SkBitmap::asImageInfo(SkImageInfo* info) const {
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) {
- offset = 0;
- }
+SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) {
#ifdef SK_DEBUG
- else {
+ if (pr) {
SkImageInfo info;
if (this->asImageInfo(&info)) {
const SkImageInfo& prInfo = pr->info();
@@ -428,7 +426,16 @@ SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, size_t offset) {
}
#endif
- if (fPixelRef != pr || fPixelRefOffset != offset) {
+ if (pr) {
+ const SkImageInfo& info = pr->info();
+ fPixelRefOrigin.set(SkPin32(dx, 0, info.fWidth),
+ SkPin32(dy, 0, info.fHeight));
+ } else {
+ // ignore dx,dy if there is no pixelref
+ fPixelRefOrigin.setZero();
+ }
+
+ if (fPixelRef != pr) {
if (fPixelRef != pr) {
this->freePixels();
SkASSERT(NULL == fPixelRef);
@@ -436,7 +443,6 @@ SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, size_t offset) {
SkSafeRef(pr);
fPixelRef = pr;
}
- fPixelRefOffset = offset;
this->updatePixelsFromRef();
}
@@ -468,19 +474,19 @@ bool SkBitmap::lockPixelsAreWritable() const {
void SkBitmap::setPixels(void* p, SkColorTable* ctable) {
if (NULL == p) {
- this->setPixelRef(NULL, 0);
+ this->setPixelRef(NULL);
return;
}
SkImageInfo info;
if (!this->asImageInfo(&info)) {
- this->setPixelRef(NULL, 0);
+ this->setPixelRef(NULL);
return;
}
SkPixelRef* pr = SkMallocPixelRef::NewDirect(info, p, fRowBytes, ctable);
if (NULL == pr) {
- this->setPixelRef(NULL, 0);
+ this->setPixelRef(NULL);
return;
}
@@ -515,7 +521,7 @@ void SkBitmap::freePixels() {
}
fPixelRef->unref();
fPixelRef = NULL;
- fPixelRefOffset = 0;
+ fPixelRefOrigin.setZero();
}
fPixelLockCount = 0;
fPixels = NULL;
@@ -562,7 +568,7 @@ bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst,
return false;
}
- dst->setPixelRef(pr, 0)->unref();
+ dst->setPixelRef(pr)->unref();
// since we're already allocated, we lockPixels right away
dst->lockPixels();
return true;
@@ -887,84 +893,6 @@ void SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const {
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
-#define SUB_OFFSET_FAILURE ((size_t)-1)
-
-/**
- * Based on the Config and rowBytes() of bm, return the offset into an SkPixelRef of the pixel at
- * (x, y).
- * Note that the SkPixelRef does not need to be set yet. deepCopyTo takes advantage of this fact.
- * Also note that (x, y) may be outside the range of (0 - width(), 0 - height()), so long as it is
- * within the bounds of the SkPixelRef being used.
- */
-static size_t get_sub_offset(const SkBitmap& bm, int x, int y) {
- switch (bm.config()) {
- case SkBitmap::kA8_Config:
- case SkBitmap:: kIndex8_Config:
- // x is fine as is for the calculation
- break;
-
- case SkBitmap::kRGB_565_Config:
- case SkBitmap::kARGB_4444_Config:
- x <<= 1;
- break;
-
- case SkBitmap::kARGB_8888_Config:
- x <<= 2;
- break;
-
- case SkBitmap::kNo_Config:
- default:
- return SUB_OFFSET_FAILURE;
- }
- return y * bm.rowBytes() + x;
-}
-
-/**
- * Using the pixelRefOffset(), rowBytes(), and Config of bm, determine the (x, y) coordinate of the
- * upper left corner of bm relative to its SkPixelRef.
- * x and y must be non-NULL.
- */
-bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t rowBytes,
- int32_t* x, int32_t* y);
-bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t rowBytes,
- int32_t* x, int32_t* y) {
- SkASSERT(x != NULL && y != NULL);
- if (0 == offset) {
- *x = *y = 0;
- return true;
- }
- // Use integer division to find the correct y position.
- // The remainder will be the x position, after we reverse get_sub_offset.
- SkTDivMod(offset, rowBytes, y, x);
- switch (config) {
- case SkBitmap::kA8_Config:
- // Fall through.
- case SkBitmap::kIndex8_Config:
- // x is unmodified
- break;
-
- case SkBitmap::kRGB_565_Config:
- // Fall through.
- case SkBitmap::kARGB_4444_Config:
- *x >>= 1;
- break;
-
- case SkBitmap::kARGB_8888_Config:
- *x >>= 2;
- break;
-
- case SkBitmap::kNo_Config:
- // Fall through.
- default:
- return false;
- }
- return true;
-}
-
-static bool get_upper_left_from_offset(const SkBitmap& bm, int32_t* x, int32_t* y) {
- return get_upper_left_from_offset(bm.config(), bm.pixelRefOffset(), bm.rowBytes(), x, y);
-}
-
bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
SkDEBUGCODE(this->validate();)
@@ -998,19 +926,17 @@ bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width()));
SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height()));
- size_t offset = get_sub_offset(*this, r.fLeft, r.fTop);
- if (SUB_OFFSET_FAILURE == offset) {
- return false; // config not supported
- }
-
SkBitmap dst;
dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes(),
this->alphaType());
dst.setIsVolatile(this->isVolatile());
if (fPixelRef) {
+ SkIPoint origin = fPixelRefOrigin;
+ origin.fX += r.fLeft;
+ origin.fY += r.fTop;
// share the pixelref with a custom offset
- dst.setPixelRef(fPixelRef, fPixelRefOffset + offset);
+ dst.setPixelRef(fPixelRef, origin);
}
SkDEBUGCODE(dst.validate();)
@@ -1059,26 +985,23 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
if (fPixelRef) {
SkIRect subset;
- if (get_upper_left_from_offset(*this, &subset.fLeft, &subset.fTop)) {
- subset.fRight = subset.fLeft + fWidth;
- subset.fBottom = subset.fTop + fHeight;
- if (fPixelRef->readPixels(&tmpSrc, &subset)) {
- SkASSERT(tmpSrc.width() == this->width());
- SkASSERT(tmpSrc.height() == this->height());
-
- // did we get lucky and we can just return tmpSrc?
- if (tmpSrc.config() == dstConfig && NULL == alloc) {
- dst->swap(tmpSrc);
- if (dst->pixelRef() && this->config() == dstConfig) {
- // TODO(scroggo): fix issue 1742
- dst->pixelRef()->cloneGenID(*fPixelRef);
- }
- return true;
+ subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, fWidth, fHeight);
+ if (fPixelRef->readPixels(&tmpSrc, &subset)) {
+ SkASSERT(tmpSrc.width() == this->width());
+ SkASSERT(tmpSrc.height() == this->height());
+
+ // did we get lucky and we can just return tmpSrc?
+ if (tmpSrc.config() == dstConfig && NULL == alloc) {
+ dst->swap(tmpSrc);
+ if (dst->pixelRef() && this->config() == dstConfig) {
+ // TODO(scroggo): fix issue 1742
+ dst->pixelRef()->cloneGenID(*fPixelRef);
}
-
- // fall through to the raster case
- src = &tmpSrc;
+ return true;
}
+
+ // fall through to the raster case
+ src = &tmpSrc;
}
}
@@ -1176,24 +1099,7 @@ bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
rowBytes = 0;
}
dst->setConfig(dstConfig, fWidth, fHeight, rowBytes);
-
- size_t pixelRefOffset;
- if (0 == fPixelRefOffset || dstConfig == fConfig) {
- // Use the same offset as the original.
- pixelRefOffset = fPixelRefOffset;
- } else {
- // Find the correct offset in the new config. This needs to be done after calling
- // setConfig so dst's fConfig and fRowBytes have been set properly.
- int32_t x, y;
- if (!get_upper_left_from_offset(*this, &x, &y)) {
- return false;
- }
- pixelRefOffset = get_sub_offset(*dst, x, y);
- if (SUB_OFFSET_FAILURE == pixelRefOffset) {
- return false;
- }
- }
- dst->setPixelRef(pixelRef, pixelRefOffset)->unref();
+ dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref();
return true;
}
}
@@ -1604,7 +1510,8 @@ void SkBitmap::flatten(SkFlattenableWriteBuffer& buffer) const {
if (fPixelRef) {
if (fPixelRef->getFactory()) {
buffer.writeInt(SERIALIZE_PIXELTYPE_REF_DATA);
- buffer.writeUInt(SkToU32(fPixelRefOffset));
+ buffer.writeInt(fPixelRefOrigin.fX);
+ buffer.writeInt(fPixelRefOrigin.fY);
buffer.writeFlattenable(fPixelRef);
return;
}
@@ -1637,13 +1544,16 @@ void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) {
(SERIALIZE_PIXELTYPE_NONE == reftype))) {
switch (reftype) {
case SERIALIZE_PIXELTYPE_REF_DATA: {
- size_t offset = buffer.readUInt();
+ SkIPoint origin;
+ origin.fX = buffer.readInt();
+ origin.fY = buffer.readInt();
+ size_t offset = origin.fY * rowBytes + origin.fX * fBytesPerPixel;
SkPixelRef* pr = buffer.readPixelRef();
if (!buffer.validate((NULL == pr) ||
(pr->getAllocatedSizeInBytes() >= (offset + this->getSafeSize())))) {
- offset = 0;
+ origin.setZero();
}
- SkSafeUnref(this->setPixelRef(pr, offset));
+ SkSafeUnref(this->setPixelRef(pr, origin));
break;
}
case SERIALIZE_PIXELTYPE_NONE: