| Index: src/core/SkBitmap.cpp
|
| diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
|
| index 96d683c0e2592765351bcf5e9912085b660093a6..ed2f32c0f78695b442e4c1808836d67ad6af8f48 100644
|
| --- a/src/core/SkBitmap.cpp
|
| +++ b/src/core/SkBitmap.cpp
|
| @@ -142,73 +142,6 @@ void SkBitmap::reset() {
|
| sk_bzero(this, sizeof(*this));
|
| }
|
|
|
| -SkBitmap::Config SkBitmap::config() const {
|
| - return SkColorTypeToBitmapConfig(fInfo.colorType());
|
| -}
|
| -
|
| -int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) {
|
| - int bpp;
|
| - switch (config) {
|
| - case kNo_Config:
|
| - bpp = 0; // not applicable
|
| - break;
|
| - case kA8_Config:
|
| - case kIndex8_Config:
|
| - bpp = 1;
|
| - break;
|
| - case kRGB_565_Config:
|
| - case kARGB_4444_Config:
|
| - bpp = 2;
|
| - break;
|
| - case kARGB_8888_Config:
|
| - bpp = 4;
|
| - break;
|
| - default:
|
| - SkDEBUGFAIL("unknown config");
|
| - bpp = 0; // error
|
| - break;
|
| - }
|
| - return bpp;
|
| -}
|
| -
|
| -size_t SkBitmap::ComputeRowBytes(Config c, int width) {
|
| - return SkColorTypeMinRowBytes(SkBitmapConfigToColorType(c), width);
|
| -}
|
| -
|
| -int64_t SkBitmap::ComputeSize64(Config config, int width, int height) {
|
| - SkColorType ct = SkBitmapConfigToColorType(config);
|
| - int64_t rowBytes = sk_64_mul(SkColorTypeBytesPerPixel(ct), width);
|
| - return rowBytes * height;
|
| -}
|
| -
|
| -size_t SkBitmap::ComputeSize(Config c, int width, int height) {
|
| - int64_t size = SkBitmap::ComputeSize64(c, width, height);
|
| - return sk_64_isS32(size) ? sk_64_asS32(size) : 0;
|
| -}
|
| -
|
| -int64_t SkBitmap::ComputeSafeSize64(Config config,
|
| - uint32_t width,
|
| - uint32_t height,
|
| - size_t rowBytes) {
|
| - SkImageInfo info = SkImageInfo::Make(width, height,
|
| - SkBitmapConfigToColorType(config),
|
| - kPremul_SkAlphaType);
|
| - return info.getSafeSize64(rowBytes);
|
| -}
|
| -
|
| -size_t SkBitmap::ComputeSafeSize(Config config,
|
| - uint32_t width,
|
| - uint32_t height,
|
| - size_t rowBytes) {
|
| - int64_t safeSize = ComputeSafeSize64(config, width, height, rowBytes);
|
| - int32_t safeSize32 = (int32_t)safeSize;
|
| -
|
| - if (safeSize32 != safeSize) {
|
| - safeSize32 = 0;
|
| - }
|
| - return safeSize32;
|
| -}
|
| -
|
| void SkBitmap::getBounds(SkRect* bounds) const {
|
| SkASSERT(bounds);
|
| bounds->set(0, 0,
|
| @@ -282,13 +215,6 @@ bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) {
|
| return true;
|
| }
|
|
|
| -bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes,
|
| - SkAlphaType alphaType) {
|
| - SkColorType ct = SkBitmapConfigToColorType(config);
|
| - return this->setConfig(SkImageInfo::Make(width, height, ct, alphaType),
|
| - rowBytes);
|
| -}
|
| -
|
| bool SkBitmap::setAlphaType(SkAlphaType alphaType) {
|
| if (!validate_alphaType(fInfo.fColorType, alphaType, &alphaType)) {
|
| return false;
|
| @@ -323,34 +249,6 @@ 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;
|
| -}
|
| -
|
| SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) {
|
| #ifdef SK_DEBUG
|
| if (pr) {
|
| @@ -507,17 +405,6 @@ bool SkBitmap::installPixels(const SkImageInfo& info, void* pixels, size_t rb,
|
| return true;
|
| }
|
|
|
| -bool SkBitmap::allocConfigPixels(Config config, int width, int height,
|
| - bool isOpaque) {
|
| - SkColorType ct;
|
| - if (!config_to_colorType(config, &ct)) {
|
| - return false;
|
| - }
|
| -
|
| - SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
|
| - return this->allocPixels(SkImageInfo::Make(width, height, ct, at));
|
| -}
|
| -
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| void SkBitmap::freePixels() {
|
| @@ -566,13 +453,7 @@ GrTexture* SkBitmap::getTexture() const {
|
| */
|
| bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst,
|
| SkColorTable* ctable) {
|
| - SkImageInfo info;
|
| - if (!dst->asImageInfo(&info)) {
|
| -// SkDebugf("unsupported config for info %d\n", dst->config());
|
| - return false;
|
| - }
|
| -
|
| - SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, dst->rowBytes(),
|
| + SkPixelRef* pr = SkMallocPixelRef::NewAllocate(dst->info(), dst->rowBytes(),
|
| ctable);
|
| if (NULL == pr) {
|
| return false;
|
| @@ -606,7 +487,7 @@ bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize,
|
| SkAutoLockPixels lock(*this);
|
| // This implementation will write bytes beyond the end of each row,
|
| // excluding the last row, if the bitmap's stride is greater than
|
| - // strictly required by the current config.
|
| + // strictly required by the current colorType.
|
| memcpy(dst, getPixels(), safeSize);
|
|
|
| return true;
|
| @@ -679,7 +560,7 @@ void* SkBitmap::getAddr(int x, int y) const {
|
| base += x;
|
| break;
|
| default:
|
| - SkDEBUGFAIL("Can't return addr for config");
|
| + SkDEBUGFAIL("Can't return addr for colorType");
|
| base = NULL;
|
| break;
|
| }
|
| @@ -956,201 +837,34 @@ bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
|
| return true;
|
| }
|
|
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -#include "SkCanvas.h"
|
| -#include "SkPaint.h"
|
| -
|
| -bool SkBitmap::canCopyTo(Config dstConfig) const {
|
| - if (this->config() == kNo_Config) {
|
| +bool SkBitmap::canCopyTo(SkColorType dstColorType) const {
|
| + if (kUnknown_SkColorType == this->colorType()) {
|
| return false;
|
| }
|
|
|
| - bool sameConfigs = (this->config() == dstConfig);
|
| - switch (dstConfig) {
|
| - case kA8_Config:
|
| - case kRGB_565_Config:
|
| - case kARGB_8888_Config:
|
| + bool sameColorTypes = (this->colorType() == dstColorType);
|
| + switch (dstColorType) {
|
| + case kAlpha_8_SkColorType:
|
| + case kRGB_565_SkColorType:
|
| + case kPMColor_SkColorType:
|
| break;
|
| - case kIndex8_Config:
|
| - if (!sameConfigs) {
|
| + case kIndex_8_SkColorType:
|
| + if (!sameColorTypes) {
|
| return false;
|
| }
|
| break;
|
| - case kARGB_4444_Config:
|
| - return sameConfigs || kARGB_8888_Config == this->config();
|
| + case kARGB_4444_SkColorType:
|
| + return sameColorTypes || kPMColor_SkColorType == this->colorType();
|
| default:
|
| return false;
|
| }
|
| return true;
|
| }
|
|
|
| -bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
|
| - if (!this->canCopyTo(dstConfig)) {
|
| - return false;
|
| - }
|
| -
|
| - // if we have a texture, first get those pixels
|
| - SkBitmap tmpSrc;
|
| - const SkBitmap* src = this;
|
| -
|
| - if (fPixelRef) {
|
| - SkIRect subset;
|
| - subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY,
|
| - fInfo.width(), fInfo.height());
|
| - 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 the result is an exact copy, clone the gen ID.
|
| - if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->info()) {
|
| - dst->pixelRef()->cloneGenID(*fPixelRef);
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - // fall through to the raster case
|
| - src = &tmpSrc;
|
| - }
|
| - }
|
| -
|
| - // we lock this now, since we may need its colortable
|
| - SkAutoLockPixels srclock(*src);
|
| - if (!src->readyToDraw()) {
|
| - return false;
|
| - }
|
| -
|
| - // The only way to be readyToDraw is if fPixelRef is non NULL.
|
| - SkASSERT(fPixelRef != NULL);
|
| -
|
| - SkBitmap tmpDst;
|
| - tmpDst.setConfig(dstConfig, src->width(), src->height(), 0,
|
| - src->alphaType());
|
| -
|
| - // allocate colortable if srcConfig == kIndex8_Config
|
| - SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
|
| - new SkColorTable(*src->getColorTable()) : NULL;
|
| - SkAutoUnref au(ctable);
|
| - if (!tmpDst.allocPixels(alloc, ctable)) {
|
| - return false;
|
| - }
|
| -
|
| - if (!tmpDst.readyToDraw()) {
|
| - // allocator/lock failed
|
| - return false;
|
| - }
|
| -
|
| - // pixelRef must be non NULL or tmpDst.readyToDraw() would have
|
| - // returned false.
|
| - SkASSERT(tmpDst.pixelRef() != NULL);
|
| -
|
| - /* do memcpy for the same configs cases, else use drawing
|
| - */
|
| - if (src->config() == dstConfig) {
|
| - if (tmpDst.getSize() == src->getSize()) {
|
| - memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
|
| - SkPixelRef* pixelRef = tmpDst.pixelRef();
|
| -
|
| - // In order to reach this point, we know that the width, config and
|
| - // rowbytes of the SkPixelRefs are the same, but it is possible for
|
| - // the heights to differ, if this SkBitmap's height is a subset of
|
| - // fPixelRef. Only if the SkPixelRefs' heights match are we
|
| - // guaranteed that this is an exact copy, meaning we should clone
|
| - // the genID.
|
| - if (pixelRef->info().fHeight == fPixelRef->info().fHeight) {
|
| - // TODO: what to do if the two infos match, BUT
|
| - // fPixelRef is premul and pixelRef is opaque?
|
| - // skipping assert for now
|
| - // https://code.google.com/p/skia/issues/detail?id=2012
|
| -// SkASSERT(pixelRef->info() == fPixelRef->info());
|
| - SkASSERT(pixelRef->info().fWidth == fPixelRef->info().fWidth);
|
| - SkASSERT(pixelRef->info().fColorType == fPixelRef->info().fColorType);
|
| - pixelRef->cloneGenID(*fPixelRef);
|
| - }
|
| - } else {
|
| - const char* srcP = reinterpret_cast<const char*>(src->getPixels());
|
| - char* dstP = reinterpret_cast<char*>(tmpDst.getPixels());
|
| - // to be sure we don't read too much, only copy our logical pixels
|
| - size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
|
| - for (int y = 0; y < tmpDst.height(); y++) {
|
| - memcpy(dstP, srcP, bytesToCopy);
|
| - srcP += src->rowBytes();
|
| - dstP += tmpDst.rowBytes();
|
| - }
|
| - }
|
| - } else if (SkBitmap::kARGB_4444_Config == dstConfig
|
| - && SkBitmap::kARGB_8888_Config == src->config()) {
|
| - SkASSERT(src->height() == tmpDst.height());
|
| - SkASSERT(src->width() == tmpDst.width());
|
| - for (int y = 0; y < src->height(); ++y) {
|
| - SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y);
|
| - SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y);
|
| - DITHER_4444_SCAN(y);
|
| - for (int x = 0; x < src->width(); ++x) {
|
| - dstRow[x] = SkDitherARGB32To4444(srcRow[x],
|
| - DITHER_VALUE(x));
|
| - }
|
| - }
|
| - } else {
|
| - // Always clear the dest in case one of the blitters accesses it
|
| - // TODO: switch the allocation of tmpDst to call sk_calloc_throw
|
| - tmpDst.eraseColor(SK_ColorTRANSPARENT);
|
| -
|
| - SkCanvas canvas(tmpDst);
|
| - SkPaint paint;
|
| -
|
| - paint.setDither(true);
|
| - canvas.drawBitmap(*src, 0, 0, &paint);
|
| - }
|
| -
|
| - dst->swap(tmpDst);
|
| - return true;
|
| -}
|
| -
|
| -bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
|
| - const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig);
|
| -
|
| - if (!this->canCopyTo(dstConfig)) {
|
| - return false;
|
| - }
|
| -
|
| - // If we have a PixelRef, and it supports deep copy, use it.
|
| - // Currently supported only by texture-backed bitmaps.
|
| - if (fPixelRef) {
|
| - SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig);
|
| - if (pixelRef) {
|
| - uint32_t rowBytes;
|
| - if (this->colorType() == dstCT) {
|
| - // Since there is no subset to pass to deepCopy, and deepCopy
|
| - // succeeded, the new pixel ref must be identical.
|
| - SkASSERT(fPixelRef->info() == pixelRef->info());
|
| - pixelRef->cloneGenID(*fPixelRef);
|
| - // Use the same rowBytes as the original.
|
| - rowBytes = fRowBytes;
|
| - } else {
|
| - // With the new config, an appropriate fRowBytes will be computed by setConfig.
|
| - rowBytes = 0;
|
| - }
|
| -
|
| - SkImageInfo info = fInfo;
|
| - info.fColorType = dstCT;
|
| - if (!dst->setConfig(info, rowBytes)) {
|
| - return false;
|
| - }
|
| - dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref();
|
| - return true;
|
| - }
|
| - }
|
| +///////////////////////////////////////////////////////////////////////////////
|
|
|
| - if (this->getTexture()) {
|
| - return false;
|
| - } else {
|
| - return this->copyTo(dst, dstConfig, NULL);
|
| - }
|
| -}
|
| +#include "SkCanvas.h"
|
| +#include "SkPaint.h"
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| ///////////////////////////////////////////////////////////////////////////////
|
| @@ -1265,20 +979,19 @@ void SkBitmap::buildMipMap(bool forceRebuild) {
|
|
|
| void (*proc)(SkBitmap* dst, int x, int y, const SkBitmap& src);
|
|
|
| - const SkBitmap::Config config = this->config();
|
| + const SkColorType ct = this->colorType();
|
|
|
| - switch (config) {
|
| - case kARGB_8888_Config:
|
| + switch (ct) {
|
| + case kRGBA_8888_SkColorType:
|
| + case kBGRA_8888_SkColorType:
|
| proc = downsampleby2_proc32;
|
| break;
|
| - case kRGB_565_Config:
|
| + case kRGB_565_SkColorType:
|
| proc = downsampleby2_proc16;
|
| break;
|
| - case kARGB_4444_Config:
|
| + case kARGB_4444_SkColorType:
|
| proc = downsampleby2_proc4444;
|
| break;
|
| - case kIndex8_Config:
|
| - case kA8_Config:
|
| default:
|
| return; // don't build mipmaps for these configs
|
| }
|
| @@ -1300,7 +1013,7 @@ void SkBitmap::buildMipMap(bool forceRebuild) {
|
| if (0 == width || 0 == height) {
|
| break;
|
| }
|
| - size += ComputeRowBytes(config, width) * height;
|
| + size += SkColorTypeMinRowBytes(ct, width) * height;
|
| maxLevels += 1;
|
| }
|
| }
|
| @@ -1331,15 +1044,17 @@ void SkBitmap::buildMipMap(bool forceRebuild) {
|
| for (int i = 0; i < maxLevels; i++) {
|
| width >>= 1;
|
| height >>= 1;
|
| - rowBytes = SkToU32(ComputeRowBytes(config, width));
|
| + rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width));
|
|
|
| level[i].fPixels = addr;
|
| level[i].fWidth = width;
|
| level[i].fHeight = height;
|
| level[i].fRowBytes = rowBytes;
|
|
|
| - dstBM.setConfig(config, width, height, rowBytes);
|
| - dstBM.setPixels(addr);
|
| + SkImageInfo info = this->info();
|
| + info.fWidth = width;
|
| + info.fHeight = height;
|
| + dstBM.installPixels(info, addr, rowBytes, NULL, NULL);
|
|
|
| srcBM.lockPixels();
|
| for (int y = 0; y < height; y++) {
|
|
|