Skia
2DGraphicsLibrary
 All Classes Namespaces 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 SkString;
24 
37 class SK_API SkBitmap {
38 public:
39  class SK_API Allocator;
40 
45  SkBitmap();
46 
52  SkBitmap(const SkBitmap& src);
53 
58  SkBitmap(SkBitmap&& src);
59 
60  ~SkBitmap();
61 
65  SkBitmap& operator=(const SkBitmap& src);
66 
70  SkBitmap& operator=(SkBitmap&& src);
71 
74  // This method is not exported to java.
75  void swap(SkBitmap& other);
76 
78 
79  const SkImageInfo& info() const { return fInfo; }
80 
81  int width() const { return fInfo.width(); }
82  int height() const { return fInfo.height(); }
83  SkColorType colorType() const { return fInfo.colorType(); }
84  SkAlphaType alphaType() const { return fInfo.alphaType(); }
85  SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
86  sk_sp<SkColorSpace> refColorSpace() const { return fInfo.refColorSpace(); }
87 
92  int bytesPerPixel() const { return fInfo.bytesPerPixel(); }
93 
98  int rowBytesAsPixels() const {
99  return fRowBytes >> this->shiftPerPixel();
100  }
101 
106  int shiftPerPixel() const { return this->fInfo.shiftPerPixel(); }
107 
109 
113  bool empty() const { return fInfo.isEmpty(); }
114 
119  bool isNull() const { return nullptr == fPixelRef; }
120 
123  bool drawsNothing() const { return this->empty() || this->isNull(); }
124 
126  size_t rowBytes() const { return fRowBytes; }
127 
137  bool setAlphaType(SkAlphaType);
138 
141  void* getPixels() const { return fPixels; }
142 
147  size_t getSize() const { return fInfo.height() * fRowBytes; }
148 
153  size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
154 
158  int64_t computeSize64() const {
159  return sk_64_mul(fInfo.height(), fRowBytes);
160  }
161 
167  int64_t computeSafeSize64() const {
168  return fInfo.getSafeSize64(fRowBytes);
169  }
170 
174  bool isImmutable() const;
175 
182  void setImmutable();
183 
186  bool isOpaque() const {
187  return SkAlphaTypeIsOpaque(this->alphaType());
188  }
189 
192  bool isVolatile() const;
193 
201  void setIsVolatile(bool);
202 
206  void reset();
207 
217  static bool ComputeIsOpaque(const SkBitmap& bm) {
218  SkPixmap pmap;
219  return bm.peekPixels(&pmap) && pmap.computeIsOpaque();
220  }
221 
225  void getBounds(SkRect* bounds) const;
226  void getBounds(SkIRect* bounds) const;
227 
228  SkIRect bounds() const { return fInfo.bounds(); }
229  SkISize dimensions() const { return fInfo.dimensions(); }
230  // Returns the bounds of this bitmap, offset by its pixelref origin.
231  SkIRect getSubset() const {
232  return SkIRect::MakeXYWH(fPixelRefOrigin.x(), fPixelRefOrigin.y(),
233  fInfo.width(), fInfo.height());
234  }
235 
236  bool setInfo(const SkImageInfo&, size_t rowBytes = 0);
237 
238  enum AllocFlags {
239  kZeroPixels_AllocFlag = 1 << 0,
240  };
248  bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, sk_sp<SkColorTable> ctable,
249  uint32_t flags = 0);
250  void allocPixels(const SkImageInfo& info, sk_sp<SkColorTable> ctable, uint32_t flags = 0) {
251  if (!this->tryAllocPixels(info, std::move(ctable), flags)) {
252  sk_throw();
253  }
254  }
255 
264  bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, size_t rowBytes);
265 
266  void allocPixels(const SkImageInfo& info, size_t rowBytes) {
267  if (!this->tryAllocPixels(info, rowBytes)) {
268  sk_throw();
269  }
270  }
271 
272  bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info) {
273  return this->tryAllocPixels(info, info.minRowBytes());
274  }
275 
276  void allocPixels(const SkImageInfo& info) {
277  this->allocPixels(info, info.minRowBytes());
278  }
279 
280  bool SK_WARN_UNUSED_RESULT tryAllocN32Pixels(int width, int height, bool isOpaque = false) {
281  SkImageInfo info = SkImageInfo::MakeN32(width, height,
282  isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
283  return this->tryAllocPixels(info);
284  }
285 
286  void allocN32Pixels(int width, int height, bool isOpaque = false) {
287  SkImageInfo info = SkImageInfo::MakeN32(width, height,
288  isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
289  this->allocPixels(info);
290  }
291 
292  // TEMPORARY -- remove after updating Android BitmapTests.cpp:35
293  void allocPixels(const SkImageInfo& info, std::nullptr_t, SkColorTable* ctable) {
294  this->allocPixels(info, sk_ref_sp(ctable));
295  }
296 
307  bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes, SkColorTable*,
308  void (*releaseProc)(void* addr, void* context), void* context);
309 
315  bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
316  return this->installPixels(info, pixels, rowBytes, NULL, NULL, NULL);
317  }
318 
325  bool installPixels(const SkPixmap&);
326 
332  bool installMaskPixels(const SkMask&);
333 
344  void setPixels(void* p, SkColorTable* ctable = NULL);
345 
359  bool SK_WARN_UNUSED_RESULT tryAllocPixels(SkColorTable* ctable = NULL) {
360  return this->tryAllocPixels(NULL, ctable);
361  }
362 
363  void allocPixels(SkColorTable* ctable = NULL) {
364  this->allocPixels(NULL, ctable);
365  }
366 
385  bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator, SkColorTable* ctable);
386 
387  void allocPixels(Allocator* allocator, SkColorTable* ctable) {
388  if (!this->tryAllocPixels(allocator, ctable)) {
389  sk_throw();
390  }
391  }
392 
397  SkPixelRef* pixelRef() const { return fPixelRef.get(); }
398 
410  SkIPoint pixelRefOrigin() const { return fPixelRefOrigin; }
411 
418  void setPixelRef(sk_sp<SkPixelRef>, int dx, int dy);
419 
424  bool readyToDraw() const {
425  return this->getPixels() != NULL &&
426  (this->colorType() != kIndex_8_SkColorType || this->getColorTable());
427  }
428 
434  SkColorTable* getColorTable() const;
435 
441  uint32_t getGenerationID() const;
442 
447  void notifyPixelsChanged() const;
448 
455  void eraseColor(SkColor c) const;
456 
463  void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const {
464  this->eraseColor(SkColorSetARGB(a, r, g, b));
465  }
466 
467  SK_ATTR_DEPRECATED("use eraseARGB or eraseColor")
468  void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
469  this->eraseARGB(0xFF, r, g, b);
470  }
471 
478  void erase(SkColor c, const SkIRect& area) const;
479 
480  // DEPRECATED
481  void eraseArea(const SkIRect& area, SkColor c) const {
482  this->erase(c, area);
483  }
484 
493  SkColor getColor(int x, int y) const {
494  SkPixmap pixmap;
495  SkAssertResult(this->peekPixels(&pixmap));
496  return pixmap.getColor(x, y);
497  }
498 
508  void* getAddr(int x, int y) const;
509 
515  inline uint32_t* getAddr32(int x, int y) const;
516 
522  inline uint16_t* getAddr16(int x, int y) const;
523 
529  inline uint8_t* getAddr8(int x, int y) const;
530 
537  inline SkPMColor getIndex8Color(int x, int y) const;
538 
550  bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
551 
571  bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
572  int srcX, int srcY, SkTransferFunctionBehavior behavior) const;
573  bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
574  int srcX, int srcY) const {
575  return this->readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY,
576  SkTransferFunctionBehavior::kRespect);
577  }
578  bool readPixels(const SkPixmap& dst, int srcX, int srcY) const;
579  bool readPixels(const SkPixmap& dst) const {
580  return this->readPixels(dst, 0, 0);
581  }
582 
589  bool writePixels(const SkPixmap& src, int dstX, int dstY) {
590  return this->writePixels(src, dstX, dstY, SkTransferFunctionBehavior::kRespect);
591  }
592  bool writePixels(const SkPixmap& src) {
593  return this->writePixels(src, 0, 0);
594  }
595  bool writePixels(const SkPixmap& src, int x, int y, SkTransferFunctionBehavior behavior);
596 
597 #ifdef SK_BUILD_FOR_ANDROID
598  bool hasHardwareMipMap() const {
599  return (fFlags & kHasHardwareMipMap_Flag) != 0;
600  }
601 
602  void setHasHardwareMipMap(bool hasHardwareMipMap) {
603  if (hasHardwareMipMap) {
604  fFlags |= kHasHardwareMipMap_Flag;
605  } else {
606  fFlags &= ~kHasHardwareMipMap_Flag;
607  }
608  }
609 #endif
610 
611  bool extractAlpha(SkBitmap* dst) const {
612  return this->extractAlpha(dst, NULL, NULL, NULL);
613  }
614 
615  bool extractAlpha(SkBitmap* dst, const SkPaint* paint,
616  SkIPoint* offset) const {
617  return this->extractAlpha(dst, paint, NULL, offset);
618  }
619 
633  bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
634  SkIPoint* offset) const;
635 
644  bool peekPixels(SkPixmap*) const;
645 
646  SkDEBUGCODE(void validate() const;)
647 
648  class Allocator : public SkRefCnt {
649  public:
656  virtual bool allocPixelRef(SkBitmap*, SkColorTable*) = 0;
657  private:
658  typedef SkRefCnt INHERITED;
659  };
660 
665  class HeapAllocator : public Allocator {
666  public:
667  bool allocPixelRef(SkBitmap*, SkColorTable*) override;
668  };
669 
670  SK_TO_STRING_NONVIRT()
671 
672 private:
673  enum Flags {
674  kImageIsVolatile_Flag = 0x02,
675 #ifdef SK_BUILD_FOR_ANDROID
676  /* A hint for the renderer responsible for drawing this bitmap
677  * indicating that it should attempt to use mipmaps when this bitmap
678  * is drawn scaled down.
679  */
680  kHasHardwareMipMap_Flag = 0x08,
681 #endif
682  };
683 
684  sk_sp<SkPixelRef> fPixelRef;
685  void* fPixels;
686  SkIPoint fPixelRefOrigin;
687  SkImageInfo fInfo;
688  uint32_t fRowBytes;
689  uint8_t fFlags;
690 
691  /* Unreference any pixelrefs or colortables
692  */
693  void freePixels();
694  void updatePixelsFromRef();
695 
696  static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&);
697  static bool ReadRawPixels(SkReadBuffer*, SkBitmap*);
698 
699  friend class SkReadBuffer; // unflatten, rawpixels
700  friend class SkBinaryWriteBuffer; // rawpixels
701 };
702 
704 
705 inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
706  SkASSERT(fPixels);
707  SkASSERT(4 == this->bytesPerPixel());
708  SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
709  return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
710 }
711 
712 inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
713  SkASSERT(fPixels);
714  SkASSERT(2 == this->bytesPerPixel());
715  SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
716  return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
717 }
718 
719 inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
720  SkASSERT(fPixels);
721  SkASSERT(1 == this->bytesPerPixel());
722  SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
723  return (uint8_t*)fPixels + y * fRowBytes + x;
724 }
725 
726 inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
727  SkASSERT(fPixels);
728  SkASSERT(kIndex_8_SkColorType == this->colorType());
729  SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
730  SkASSERT(this->getColorTable());
731  return (*this->getColorTable())[*((const uint8_t*)fPixels + y * fRowBytes + x)];
732 }
733 
734 #endif
size_t rowBytes() const
Return the number of bytes between subsequent rows of the bitmap.
Definition: SkBitmap.h:126
SkColor getColor(int x, int y) const
Converts the pixel at the specified coordinate to an unpremultiplied SkColor.
Definition: SkBitmap.h:493
bool peekPixels(SkPixmap *) const
If the pixels are available from this bitmap return true, and fill out the specified pixmap (if not n...
bool empty() const
Return true iff the bitmap has empty dimensions.
Definition: SkBitmap.h:113
int64_t computeSize64() const
Return the full size of the bitmap, in bytes.
Definition: SkBitmap.h:158
int shiftPerPixel() const
Return the shift amount per pixel (i.e.
Definition: SkBitmap.h:106
Definition: SkColorSpace.h:59
Describe an image's dimensions and pixel type.
Definition: SkImageInfo.h:181
SkPixelRef * pixelRef() const
Return the current pixelref object or NULL if there is none.
Definition: SkBitmap.h:397
uint16_t * getAddr16(int x, int y) const
Returns the address of the pixel specified by x,y for 16bit pixels.
Definition: SkBitmap.h:712
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:665
SkIPoint pixelRefOrigin() const
A bitmap can reference a subset of a pixelref's pixels.
Definition: SkBitmap.h:410
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:141
Definition: SkRefCnt.h:125
The SkPaint class holds the style and color information about how to draw geometries, text and bitmaps.
Definition: SkPaint.h:45
SkColorTable * getColorTable() const
Return the bitmap's colortable, if it uses one (i.e.
bool drawsNothing() const
Return true iff drawing this bitmap has no effect.
Definition: SkBitmap.h:123
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes)
Call installPixels with no ReleaseProc specified.
Definition: SkBitmap.h:315
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:463
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:76
static bool ComputeIsOpaque(const SkBitmap &bm)
This will brute-force return true if all of the pixels in the bitmap are opaque.
Definition: SkBitmap.h:217
size_t getSize() const
Return the byte size of the pixels, based on the height and rowBytes.
Definition: SkBitmap.h:147
bool isOpaque() const
Returns true if the bitmap is opaque (has no translucent/transparent pixels).
Definition: SkBitmap.h:186
The SkBitmap class specifies a raster bitmap.
Definition: SkBitmap.h:37
bool writePixels(const SkPixmap &src, int dstX, int dstY)
Copy the src pixmap's pixels into this bitmap, offset by dstX, dstY.
Definition: SkBitmap.h:589
This class is the smart container for pixel memory, and is used with SkBitmap.
Definition: SkPixelRef.h:33
Definition: SkSize.h:13
bool computeIsOpaque() const
This will brute-force return true if all of the pixels in the pixmap are opaque.
SkColor getColor(int x, int y) const
Converts the pixel at the specified coordinate to an unpremultiplied SkColor.
bool readyToDraw() const
Call this to be sure that the bitmap is valid enough to be drawn (i.e.
Definition: SkBitmap.h:424
uint32_t SkPMColor
32 bit ARGB color value, premultiplied.
Definition: SkColor.h:161
uint8_t * getAddr8(int x, int y) const
Returns the address of the pixel specified by x,y for 8bit pixels.
Definition: SkBitmap.h:719
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:153
int bytesPerPixel() const
Return the number of bytes per pixel based on the colortype.
Definition: SkBitmap.h:92
uint32_t SkColor
32 bit ARGB color value, not premultiplied.
Definition: SkColor.h:28
#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:27
Definition: SkRect.h:404
uint32_t * getAddr32(int x, int y) const
Returns the address of the pixel specified by x,y for 32bit pixels.
Definition: SkBitmap.h:705
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:167
int rowBytesAsPixels() const
Return the rowbytes expressed as a number of pixels (like width and height).
Definition: SkBitmap.h:98
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:119
unsigned U8CPU
Fast type for unsigned 8 bits.
Definition: SkTypes.h:191
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:359
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:726
Types and macros for colors.