Skia
2DGraphicsLibrary
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkBitmap.h
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkBitmap_DEFINED
9 #define SkBitmap_DEFINED
10 
11 #include "SkColor.h"
12 #include "SkColorTable.h"
13 #include "SkImageInfo.h"
14 #include "SkPixmap.h"
15 #include "SkPoint.h"
16 #include "SkRefCnt.h"
17 
18 struct SkMask;
19 struct SkIRect;
20 struct SkRect;
21 class SkPaint;
22 class SkPixelRef;
23 class SkPixelRefFactory;
24 class SkRegion;
25 class SkString;
26 
27 #ifdef SK_SUPPORT_LEGACY_BITMAP_GETTEXTURE
28 class GrTexture;
29 #endif
30 
41 class SK_API SkBitmap {
42 public:
43  class SK_API Allocator;
44 
49  SkBitmap();
50 
58  SkBitmap(const SkBitmap& src);
59 
64  SkBitmap(SkBitmap&& src);
65 
66  ~SkBitmap();
67 
71  SkBitmap& operator=(const SkBitmap& src);
72 
76  SkBitmap& operator=(SkBitmap&& src);
77 
80  // This method is not exported to java.
81  void swap(SkBitmap& other);
82 
84 
85  const SkImageInfo& info() const { return fInfo; }
86 
87  int width() const { return fInfo.width(); }
88  int height() const { return fInfo.height(); }
89  SkColorType colorType() const { return fInfo.colorType(); }
90  SkAlphaType alphaType() const { return fInfo.alphaType(); }
91  SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
92 
97  int bytesPerPixel() const { return fInfo.bytesPerPixel(); }
98 
103  int rowBytesAsPixels() const {
104  return fRowBytes >> this->shiftPerPixel();
105  }
106 
111  int shiftPerPixel() const { return this->fInfo.shiftPerPixel(); }
112 
114 
118  bool empty() const { return fInfo.isEmpty(); }
119 
124  bool isNull() const { return NULL == fPixelRef; }
125 
128  bool drawsNothing() const { return this->empty() || this->isNull(); }
129 
131  size_t rowBytes() const { return fRowBytes; }
132 
142  bool setAlphaType(SkAlphaType);
143 
146  void* getPixels() const { return fPixels; }
147 
152  size_t getSize() const { return fInfo.height() * fRowBytes; }
153 
158  size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
159 
163  int64_t computeSize64() const {
164  return sk_64_mul(fInfo.height(), fRowBytes);
165  }
166 
172  int64_t computeSafeSize64() const {
173  return fInfo.getSafeSize64(fRowBytes);
174  }
175 
179  bool isImmutable() const;
180 
187  void setImmutable();
188 
191  bool isOpaque() const {
192  return SkAlphaTypeIsOpaque(this->alphaType());
193  }
194 
197  bool isVolatile() const;
198 
206  void setIsVolatile(bool);
207 
211  void reset();
212 
222  static bool ComputeIsOpaque(const SkBitmap&);
223 
227  void getBounds(SkRect* bounds) const;
228  void getBounds(SkIRect* bounds) const;
229 
230  SkIRect bounds() const { return fInfo.bounds(); }
231  SkISize dimensions() const { return fInfo.dimensions(); }
232  // Returns the bounds of this bitmap, offset by its pixelref origin.
233  SkIRect getSubset() const {
234  return SkIRect::MakeXYWH(fPixelRefOrigin.x(), fPixelRefOrigin.y(),
235  fInfo.width(), fInfo.height());
236  }
237 
238  bool setInfo(const SkImageInfo&, size_t rowBytes = 0);
239 
246  bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
247 
248  void allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, SkColorTable* ctable) {
249  if (!this->tryAllocPixels(info, factory, ctable)) {
250  sk_throw();
251  }
252  }
253 
262  bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, size_t rowBytes);
263 
264  void allocPixels(const SkImageInfo& info, size_t rowBytes) {
265  if (!this->tryAllocPixels(info, rowBytes)) {
266  sk_throw();
267  }
268  }
269 
270  bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info) {
271  return this->tryAllocPixels(info, info.minRowBytes());
272  }
273 
274  void allocPixels(const SkImageInfo& info) {
275  this->allocPixels(info, info.minRowBytes());
276  }
277 
278  bool SK_WARN_UNUSED_RESULT tryAllocN32Pixels(int width, int height, bool isOpaque = false) {
279  SkImageInfo info = SkImageInfo::MakeN32(width, height,
280  isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
281  return this->tryAllocPixels(info);
282  }
283 
284  void allocN32Pixels(int width, int height, bool isOpaque = false) {
285  SkImageInfo info = SkImageInfo::MakeN32(width, height,
286  isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
287  this->allocPixels(info);
288  }
289 
300  bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes, SkColorTable*,
301  void (*releaseProc)(void* addr, void* context), void* context);
302 
308  bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
309  return this->installPixels(info, pixels, rowBytes, NULL, NULL, NULL);
310  }
311 
318  bool installPixels(const SkPixmap&);
319 
325  bool installMaskPixels(const SkMask&);
326 
337  void setPixels(void* p, SkColorTable* ctable = NULL);
338 
357  bool copyPixelsTo(void* const dst, size_t dstSize, size_t dstRowBytes = 0,
358  bool preserveDstPad = false) const;
359 
373  bool SK_WARN_UNUSED_RESULT tryAllocPixels(SkColorTable* ctable = NULL) {
374  return this->tryAllocPixels(NULL, ctable);
375  }
376 
377  void allocPixels(SkColorTable* ctable = NULL) {
378  this->allocPixels(NULL, ctable);
379  }
380 
399  bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator, SkColorTable* ctable);
400 
401  void allocPixels(Allocator* allocator, SkColorTable* ctable) {
402  if (!this->tryAllocPixels(allocator, ctable)) {
403  sk_throw();
404  }
405  }
406 
411  SkPixelRef* pixelRef() const { return fPixelRef; }
412 
424  SkIPoint pixelRefOrigin() const { return fPixelRefOrigin; }
425 
433  SkPixelRef* setPixelRef(SkPixelRef* pr, int dx, int dy);
434 
435  SkPixelRef* setPixelRef(SkPixelRef* pr, const SkIPoint& origin) {
436  return this->setPixelRef(pr, origin.fX, origin.fY);
437  }
438 
439  SkPixelRef* setPixelRef(SkPixelRef* pr) {
440  return this->setPixelRef(pr, 0, 0);
441  }
442 
447  void lockPixels() const;
453  void unlockPixels() const;
454 
461  // DEPRECATED
462  bool lockPixelsAreWritable() const;
463 
464  bool requestLock(SkAutoPixmapUnlock* result) const;
465 
470  bool readyToDraw() const {
471  return this->getPixels() != NULL &&
472  (this->colorType() != kIndex_8_SkColorType || fColorTable);
473  }
474 
475 #ifdef SK_SUPPORT_LEGACY_BITMAP_GETTEXTURE
476  GrTexture* getTexture() const { return nullptr; }
477 #endif
478 
484  SkColorTable* getColorTable() const { return fColorTable; }
485 
491  uint32_t getGenerationID() const;
492 
497  void notifyPixelsChanged() const;
498 
505  void eraseColor(SkColor c) const;
506 
513  void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const {
514  this->eraseColor(SkColorSetARGB(a, r, g, b));
515  }
516 
517  SK_ATTR_DEPRECATED("use eraseARGB or eraseColor")
518  void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
519  this->eraseARGB(0xFF, r, g, b);
520  }
521 
528  void erase(SkColor c, const SkIRect& area) const;
529 
530  // DEPRECATED
531  void eraseArea(const SkIRect& area, SkColor c) const {
532  this->erase(c, area);
533  }
534 
542  SkColor getColor(int x, int y) const;
543 
553  void* getAddr(int x, int y) const;
554 
560  inline uint32_t* getAddr32(int x, int y) const;
561 
567  inline uint16_t* getAddr16(int x, int y) const;
568 
574  inline uint8_t* getAddr8(int x, int y) const;
575 
582  inline SkPMColor getIndex8Color(int x, int y) const;
583 
595  bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
596 
609  bool copyTo(SkBitmap* dst, SkColorType ct, Allocator* = NULL) const;
610 
611  bool copyTo(SkBitmap* dst, Allocator* allocator = NULL) const {
612  return this->copyTo(dst, this->colorType(), allocator);
613  }
614 
634  bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
635  int srcX, int srcY) const;
636 
641  bool canCopyTo(SkColorType colorType) const;
642 
649  bool deepCopyTo(SkBitmap* dst) const;
650 
651 #ifdef SK_BUILD_FOR_ANDROID
652  bool hasHardwareMipMap() const {
653  return (fFlags & kHasHardwareMipMap_Flag) != 0;
654  }
655 
656  void setHasHardwareMipMap(bool hasHardwareMipMap) {
657  if (hasHardwareMipMap) {
658  fFlags |= kHasHardwareMipMap_Flag;
659  } else {
660  fFlags &= ~kHasHardwareMipMap_Flag;
661  }
662  }
663 #endif
664 
665  bool extractAlpha(SkBitmap* dst) const {
666  return this->extractAlpha(dst, NULL, NULL, NULL);
667  }
668 
669  bool extractAlpha(SkBitmap* dst, const SkPaint* paint,
670  SkIPoint* offset) const {
671  return this->extractAlpha(dst, paint, NULL, offset);
672  }
673 
687  bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
688  SkIPoint* offset) const;
689 
699  bool peekPixels(SkPixmap*) const;
700 
701  SkDEBUGCODE(void validate() const;)
702 
703  class Allocator : public SkRefCnt {
704  public:
712  virtual bool allocPixelRef(SkBitmap*, SkColorTable*) = 0;
713  private:
714  typedef SkRefCnt INHERITED;
715  };
716 
721  class HeapAllocator : public Allocator {
722  public:
723  bool allocPixelRef(SkBitmap*, SkColorTable*) override;
724  };
725 
726  class RLEPixels {
727  public:
728  RLEPixels(int width, int height);
729  virtual ~RLEPixels();
730 
731  uint8_t* packedAtY(int y) const {
732  SkASSERT((unsigned)y < (unsigned)fHeight);
733  return fYPtrs[y];
734  }
735 
736  // called by subclasses during creation
737  void setPackedAtY(int y, uint8_t* addr) {
738  SkASSERT((unsigned)y < (unsigned)fHeight);
739  fYPtrs[y] = addr;
740  }
741 
742  private:
743  uint8_t** fYPtrs;
744  int fHeight;
745  };
746 
747  SK_TO_STRING_NONVIRT()
748 
749 private:
750  mutable SkPixelRef* fPixelRef;
751  mutable int fPixelLockCount;
752  // These are just caches from the locked pixelref
753  mutable void* fPixels;
754  mutable SkColorTable* fColorTable; // only meaningful for kIndex8
755 
756  SkIPoint fPixelRefOrigin;
757 
758  enum Flags {
759  kImageIsVolatile_Flag = 0x02,
760 #ifdef SK_BUILD_FOR_ANDROID
761  /* A hint for the renderer responsible for drawing this bitmap
762  * indicating that it should attempt to use mipmaps when this bitmap
763  * is drawn scaled down.
764  */
765  kHasHardwareMipMap_Flag = 0x08,
766 #endif
767  };
768 
769  SkImageInfo fInfo;
770  uint32_t fRowBytes;
771  uint8_t fFlags;
772 
773  /* Unreference any pixelrefs or colortables
774  */
775  void freePixels();
776  void updatePixelsFromRef() const;
777 
778  static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&);
779  static bool ReadRawPixels(SkReadBuffer*, SkBitmap*);
780 
781  friend class SkReadBuffer; // unflatten, rawpixels
782  friend class SkBinaryWriteBuffer; // rawpixels
783  friend struct SkBitmapProcState;
784 };
785 
786 class SkAutoLockPixels : SkNoncopyable {
787 public:
788  SkAutoLockPixels(const SkBitmap& bm, bool doLock = true) : fBitmap(bm) {
789  fDidLock = doLock;
790  if (doLock) {
791  bm.lockPixels();
792  }
793  }
794  ~SkAutoLockPixels() {
795  if (fDidLock) {
796  fBitmap.unlockPixels();
797  }
798  }
799 
800 private:
801  const SkBitmap& fBitmap;
802  bool fDidLock;
803 };
804 //TODO(mtklein): uncomment when 71713004 lands and Chromium's fixed.
805 //#define SkAutoLockPixels(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockPixels)
806 
808 
809 inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
810  SkASSERT(fPixels);
811  SkASSERT(4 == this->bytesPerPixel());
812  SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
813  return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
814 }
815 
816 inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
817  SkASSERT(fPixels);
818  SkASSERT(2 == this->bytesPerPixel());
819  SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
820  return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
821 }
822 
823 inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
824  SkASSERT(fPixels);
825  SkASSERT(1 == this->bytesPerPixel());
826  SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
827  return (uint8_t*)fPixels + y * fRowBytes + x;
828 }
829 
830 inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
831  SkASSERT(fPixels);
832  SkASSERT(kIndex_8_SkColorType == this->colorType());
833  SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
834  SkASSERT(fColorTable);
835  return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
836 }
837 
838 #endif
size_t rowBytes() const
Return the number of bytes between subsequent rows of the bitmap.
Definition: SkBitmap.h:131
bool empty() const
Return true iff the bitmap has empty dimensions.
Definition: SkBitmap.h:118
int64_t computeSize64() const
Return the full size of the bitmap, in bytes.
Definition: SkBitmap.h:163
int shiftPerPixel() const
Return the shift amount per pixel (i.e.
Definition: SkBitmap.h:111
Definition: SkColorSpace.h:16
Describe an image's dimensions and pixel type.
Definition: SkImageInfo.h:181
void unlockPixels() const
When you are finished access the pixel memory, call this to balance a previous call to lockPixels()...
SkPixelRef * pixelRef() const
Return the current pixelref object or NULL if there is none.
Definition: SkBitmap.h:411
uint16_t * getAddr16(int x, int y) const
Returns the address of the pixel specified by x,y for 16bit pixels.
Definition: SkBitmap.h:816
SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by 8-bit bitmaps...
Definition: SkColorTable.h:25
Subclass of Allocator that returns a pixelref that allocates its pixel memory from the heap...
Definition: SkBitmap.h:721
SkIPoint pixelRefOrigin() const
A bitmap can reference a subset of a pixelref's pixels.
Definition: SkBitmap.h:424
Pairs SkImageInfo with actual pixels and rowbytes.
Definition: SkPixmap.h:23
void * getPixels() const
Return the address of the pixels for this SkBitmap.
Definition: SkBitmap.h:146
Definition: SkRefCnt.h:135
The SkPaint class holds the style and color information about how to draw geometries, text and bitmaps.
Definition: SkPaint.h:46
SkColorTable * getColorTable() const
Return the bitmap's colortable, if it uses one (i.e.
Definition: SkBitmap.h:484
bool drawsNothing() const
Return true iff drawing this bitmap has no effect.
Definition: SkBitmap.h:128
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes)
Call installPixels with no ReleaseProc specified.
Definition: SkBitmap.h:308
SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or the 3-channel 3D format.
Definition: SkMask.h:19
void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const
Fill the entire bitmap with the specified color.
Definition: SkBitmap.h:513
static SkImageInfo MakeN32(int width, int height, SkAlphaType at, sk_sp< SkColorSpace > cs=nullptr)
Sets colortype to the native ARGB32 type.
Definition: SkImageInfo.h:199
Concrete implementation that serializes to a flat binary blob.
Definition: SkWriteBuffer.h:68
size_t getSize() const
Return the byte size of the pixels, based on the height and rowBytes.
Definition: SkBitmap.h:152
bool isOpaque() const
Returns true if the bitmap is opaque (has no translucent/transparent pixels).
Definition: SkBitmap.h:191
The SkBitmap class specifies a raster bitmap.
Definition: SkBitmap.h:41
This class is the smart container for pixel memory, and is used with SkBitmap.
Definition: SkPixelRef.h:38
Definition: SkPixmap.h:209
The SkRegion class encapsulates the geometric region used to specify clipping areas for drawing...
Definition: SkRegion.h:30
bool readyToDraw() const
Call this to be sure that the bitmap is valid enough to be drawn (i.e.
Definition: SkBitmap.h:470
uint32_t SkPMColor
32 bit ARGB color value, premultiplied.
Definition: SkColor.h:147
uint8_t * getAddr8(int x, int y) const
Returns the address of the pixel specified by x,y for 8bit pixels.
Definition: SkBitmap.h:823
size_t getSafeSize() const
Return the number of bytes from the pointer returned by getPixels() to the end of the allocated space...
Definition: SkBitmap.h:158
int bytesPerPixel() const
Return the number of bytes per pixel based on the colortype.
Definition: SkBitmap.h:97
uint32_t SkColor
32 bit ARGB color value, not premultiplied.
Definition: SkColor.h:28
Definition: SkBitmap.h:786
#define SkColorSetARGB(a, r, g, b)
gcc will generate static initializers for code of this form: static const SkColor kMyColor = SkColorS...
Definition: SkColor.h:53
Definition: SkWriteBuffer.h:26
Definition: SkRect.h:390
uint32_t * getAddr32(int x, int y) const
Returns the address of the pixel specified by x,y for 32bit pixels.
Definition: SkBitmap.h:809
int64_t computeSafeSize64() const
Return the number of bytes from the pointer returned by getPixels() to the end of the allocated space...
Definition: SkBitmap.h:172
Definition: SkPixelRef.h:394
int rowBytesAsPixels() const
Return the rowbytes expressed as a number of pixels (like width and height).
Definition: SkBitmap.h:103
SkIRect holds four 32 bit integer coordinates for a rectangle.
Definition: SkRect.h:20
bool isNull() const
Return true iff the bitmap has no pixelref.
Definition: SkBitmap.h:124
unsigned U8CPU
Fast type for unsigned 8 bits.
Definition: SkTypes.h:251
Definition: SkBitmap.h:726
Definition: GrTexture.h:19
SkIPoint holds two 32 bit integer coordinates.
Definition: SkPoint.h:40
bool SK_WARN_UNUSED_RESULT tryAllocPixels(SkColorTable *ctable=NULL)
Use the standard HeapAllocator to create the pixelref that manages the pixel memory.
Definition: SkBitmap.h:373
void lockPixels() const
Call this to ensure that the bitmap points to the current pixel address in the pixelref.
Light weight class for managing strings.
Definition: SkString.h:121
SkPMColor getIndex8Color(int x, int y) const
Returns the color corresponding to the pixel specified by x,y for colortable based bitmaps...
Definition: SkBitmap.h:830
Types and macros for colors.