Index: include/core/SkPixmap.h |
diff --git a/include/core/SkPixmap.h b/include/core/SkPixmap.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a2ce6cd7889fc10b73f34feb61ea00378da7d312 |
--- /dev/null |
+++ b/include/core/SkPixmap.h |
@@ -0,0 +1,152 @@ |
+/* |
+ * Copyright 2015 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#ifndef SkPixmap_DEFINED |
+#define SkPixmap_DEFINED |
+ |
+#include "SkImageInfo.h" |
+ |
+class SkColorTable; |
+ |
+/** |
+ * Pairs SkImageInfo with actual pixels and rowbytes. This class does not try to manage the |
+ * lifetime of the pixel memory (nor the colortable if provided). |
+ */ |
+class SkPixmap { |
+public: |
+ SkPixmap() |
+ : fPixels(NULL), fCTable(NULL), fRowBytes(0), fInfo(SkImageInfo::MakeUnknown(0, 0)) |
+ {} |
+ |
+ SkPixmap(const SkImageInfo& info, const void* addr, size_t rowBytes, |
+ SkColorTable* ctable = NULL) |
+ : fPixels(addr), fCTable(ctable), fRowBytes(rowBytes), fInfo(info) |
+ { |
+ if (kIndex_8_SkColorType == info.colorType()) { |
+ SkASSERT(ctable); |
+ } else { |
+ SkASSERT(NULL == ctable); |
+ } |
+ } |
+ |
+ const SkImageInfo& info() const { return fInfo; } |
+ size_t rowBytes() const { return fRowBytes; } |
+ const void* addr() const { return fPixels; } |
+ SkColorTable* ctable() const { return fCTable; } |
+ |
+ int width() const { return fInfo.width(); } |
+ int height() const { return fInfo.height(); } |
+ SkColorType colorType() const { return fInfo.colorType(); } |
+ SkAlphaType alphaType() const { return fInfo.alphaType(); } |
+ bool isOpaque() const { return fInfo.isOpaque(); } |
+ |
+ int64_t getSafeSize64() const { return fInfo.getSafeSize64(fRowBytes); } |
+ size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); } |
+ |
+ const uint32_t* addr32() const { |
+ SkASSERT(4 == SkColorTypeBytesPerPixel(fInfo.colorType())); |
+ return reinterpret_cast<const uint32_t*>(fPixels); |
+ } |
+ |
+ const uint16_t* addr16() const { |
+ SkASSERT(2 == SkColorTypeBytesPerPixel(fInfo.colorType())); |
+ return reinterpret_cast<const uint16_t*>(fPixels); |
+ } |
+ |
+ const uint8_t* addr8() const { |
+ SkASSERT(1 == SkColorTypeBytesPerPixel(fInfo.colorType())); |
+ return reinterpret_cast<const uint8_t*>(fPixels); |
+ } |
+ |
+ const uint32_t* addr32(int x, int y) const { |
+ SkASSERT((unsigned)x < (unsigned)fInfo.width()); |
+ SkASSERT((unsigned)y < (unsigned)fInfo.height()); |
+ return (const uint32_t*)((const char*)this->addr32() + y * fRowBytes + (x << 2)); |
+ } |
+ const uint16_t* addr16(int x, int y) const { |
+ SkASSERT((unsigned)x < (unsigned)fInfo.width()); |
+ SkASSERT((unsigned)y < (unsigned)fInfo.height()); |
+ return (const uint16_t*)((const char*)this->addr16() + y * fRowBytes + (x << 1)); |
+ } |
+ const uint8_t* addr8(int x, int y) const { |
+ SkASSERT((unsigned)x < (unsigned)fInfo.width()); |
+ SkASSERT((unsigned)y < (unsigned)fInfo.height()); |
+ return (const uint8_t*)((const char*)this->addr8() + y * fRowBytes + (x << 0)); |
+ } |
+ const void* addr(int x, int y) const { |
+ return (const char*)fPixels + fInfo.computeOffset(x, y, fRowBytes); |
+ } |
+ |
+ // Writable versions |
+ |
+ void* writable_addr() const { return const_cast<void*>(fPixels); } |
+ uint32_t* writable_addr32(int x, int y) const { |
+ return const_cast<uint32_t*>(this->addr32(x, y)); |
+ } |
+ uint16_t* writable_addr16(int x, int y) const { |
+ return const_cast<uint16_t*>(this->addr16(x, y)); |
+ } |
+ uint8_t* writable_addr8(int x, int y) const { |
+ return const_cast<uint8_t*>(this->addr8(x, y)); |
+ } |
+ |
+private: |
+ const void* fPixels; |
+ SkColorTable* fCTable; |
+ size_t fRowBytes; |
+ SkImageInfo fInfo; |
+}; |
+ |
+///////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+class SkAutoPixmapUnlock : ::SkNoncopyable { |
+public: |
+ SkAutoPixmapUnlock() : fUnlockProc(NULL), fIsLocked(false) {} |
+ SkAutoPixmapUnlock(const SkPixmap& pm, void (*unlock)(void*), void* ctx) |
+ : fUnlockProc(unlock), fUnlockContext(ctx), fPixmap(pm), fIsLocked(true) |
+ {} |
+ ~SkAutoPixmapUnlock() { this->unlock(); } |
+ |
+ /** |
+ * Return the currently locked pixmap. Undefined if it has been unlocked. |
+ */ |
+ const SkPixmap& pixmap() const { |
+ SkASSERT(this->isLocked()); |
+ return fPixmap; |
+ } |
+ |
+ bool isLocked() const { return fIsLocked; } |
+ |
+ /** |
+ * Unlocks the pixmap. Can safely be called more than once as it will only call the underlying |
+ * unlock-proc once. |
+ */ |
+ void unlock() { |
+ if (fUnlockProc) { |
+ SkASSERT(fIsLocked); |
+ fUnlockProc(fUnlockContext); |
+ fUnlockProc = NULL; |
+ fIsLocked = false; |
+ } |
+ } |
+ |
+ /** |
+ * If there is a currently locked pixmap, unlock it, then copy the specified pixmap |
+ * and (optional) unlock proc/context. |
+ */ |
+ void reset(const SkPixmap& pm, void (*unlock)(void*), void* ctx); |
+ |
+private: |
+ void (*fUnlockProc)(void*); |
+ void* fUnlockContext; |
+ SkPixmap fPixmap; |
+ bool fIsLocked; |
+ |
+ friend class SkBitmap; |
+}; |
scroggo
2015/05/22 18:42:33
Should this be SK_REQUIRE_LOCAL_VAR?
|
+ |
+#endif |