Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Unified Diff: src/core/SkBitmapConfig.cpp

Issue 137753017: move all Config specific APIs into SkBitmapConfig.cpp -- Config is deprecated (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkBitmap.cpp ('k') | src/core/SkMipMap.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkBitmapConfig.cpp
diff --git a/src/core/SkBitmapConfig.cpp b/src/core/SkBitmapConfig.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f3ff9240a7ca38ac440cf3799194152e9304f57c
--- /dev/null
+++ b/src/core/SkBitmapConfig.cpp
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkColorPriv.h"
+#include "SkDither.h"
+#include "SkImagePriv.h"
+#include "SkPixelRef.h"
+
+#ifdef SK_SUPPORT_LEGACY_BITMAP_COMPUTESIZE
+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;
+}
+#endif
+
+#ifdef SK_SUPPORT_LEGACY_BITMAPCONFIG
+
+SkBitmap::Config SkBitmap::config() const {
+ return SkColorTypeToBitmapConfig(fInfo.colorType());
+}
+
+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::allocConfigPixels(Config config, int width, int height,
+ bool isOpaque) {
+ SkColorType ct = SkBitmapConfigToColorType(config);
+ SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
+ return this->allocPixels(SkImageInfo::Make(width, height, ct, at));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool SkBitmap::canCopyTo(Config dstConfig) const {
+ return this->canCopyTo(SkBitmapConfigToColorType(dstConfig));
+}
+
+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);
+ }
+}
+
+#endif
« no previous file with comments | « src/core/SkBitmap.cpp ('k') | src/core/SkMipMap.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698