• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
13 #include "SkColorTable.h"
14 #endif
15 #include "SkImageInfo.h"
16 #include "SkPixmap.h"
17 #include "SkPoint.h"
18 #include "SkRefCnt.h"
19 
20 struct SkMask;
21 struct SkIRect;
22 struct SkRect;
23 class SkPaint;
24 class SkPixelRef;
25 class SkString;
26 
27 /** \class SkBitmap
28 
29     The SkBitmap class specifies a raster bitmap. A bitmap has an integer width
30     and height, and a format (colortype), and a pointer to the actual pixels.
31     Bitmaps can be drawn into a SkCanvas, but they are also used to specify the
32     target of a SkCanvas' drawing operations.
33     A const SkBitmap exposes getAddr(), which lets a caller write its pixels;
34     the constness is considered to apply to the bitmap's configuration, not
35     its contents.
36 
37     SkBitmap is not thread safe.  Each thread must use its own (shallow) copy.
38 */
39 class SK_API SkBitmap {
40 public:
41     class SK_API Allocator;
42 
43     /**
44      *  Default construct creates a bitmap with zero width and height, and no pixels.
45      *  Its colortype is set to kUnknown_SkColorType.
46      */
47     SkBitmap();
48 
49     /**
50      *  Copy the settings from the src into this bitmap. If the src has pixels
51      *  allocated, they will be shared, not copied, so that the two bitmaps will
52      *  reference the same memory for the pixels.
53      */
54     SkBitmap(const SkBitmap& src);
55 
56     /**
57      *  Copy the settings from the src into this bitmap. If the src has pixels
58      *  allocated, ownership of the pixels will be taken.
59      */
60     SkBitmap(SkBitmap&& src);
61 
62     ~SkBitmap();
63 
64     /** Copies the src bitmap into this bitmap. Ownership of the src
65         bitmap's pixels is shared with the src bitmap.
66     */
67     SkBitmap& operator=(const SkBitmap& src);
68 
69     /** Copies the src bitmap into this bitmap. Takes ownership of the src
70         bitmap's pixels.
71     */
72     SkBitmap& operator=(SkBitmap&& src);
73 
74     /** Swap the fields of the two bitmaps. This routine is guaranteed to never fail or throw.
75     */
76     //  This method is not exported to java.
77     void swap(SkBitmap& other);
78 
79     ///////////////////////////////////////////////////////////////////////////
80 
info()81     const SkImageInfo& info() const { return fInfo; }
82 
width()83     int width() const { return fInfo.width(); }
height()84     int height() const { return fInfo.height(); }
colorType()85     SkColorType colorType() const { return fInfo.colorType(); }
alphaType()86     SkAlphaType alphaType() const { return fInfo.alphaType(); }
colorSpace()87     SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
refColorSpace()88     sk_sp<SkColorSpace> refColorSpace() const { return fInfo.refColorSpace(); }
89 
90     /**
91      *  Return the number of bytes per pixel based on the colortype. If the colortype is
92      *  kUnknown_SkColorType, then 0 is returned.
93      */
bytesPerPixel()94     int bytesPerPixel() const { return fInfo.bytesPerPixel(); }
95 
96     /**
97      *  Return the rowbytes expressed as a number of pixels (like width and height).
98      *  If the colortype is kUnknown_SkColorType, then 0 is returned.
99      */
rowBytesAsPixels()100     int rowBytesAsPixels() const {
101         return fRowBytes >> this->shiftPerPixel();
102     }
103 
104     /**
105      *  Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel
106      *  colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType.
107      */
shiftPerPixel()108     int shiftPerPixel() const { return this->fInfo.shiftPerPixel(); }
109 
110     ///////////////////////////////////////////////////////////////////////////
111 
112     /** Return true iff the bitmap has empty dimensions.
113      *  Hey!  Before you use this, see if you really want to know drawsNothing() instead.
114      */
empty()115     bool empty() const { return fInfo.isEmpty(); }
116 
117     /** Return true iff the bitmap has no pixelref. Note: this can return true even if the
118      *  dimensions of the bitmap are > 0 (see empty()).
119      *  Hey!  Before you use this, see if you really want to know drawsNothing() instead.
120      */
isNull()121     bool isNull() const { return nullptr == fPixelRef; }
122 
123     /** Return true iff drawing this bitmap has no effect.
124      */
drawsNothing()125     bool drawsNothing() const {
126         return this->empty() || this->isNull();
127     }
128 
129     /** Return the number of bytes between subsequent rows of the bitmap. */
rowBytes()130     size_t rowBytes() const { return fRowBytes; }
131 
132     /**
133      *  Set the bitmap's alphaType, returning true on success. If false is
134      *  returned, then the specified new alphaType is incompatible with the
135      *  colortype, and the current alphaType is unchanged.
136      *
137      *  Note: this changes the alphatype for the underlying pixels, which means
138      *  that all bitmaps that might be sharing (subsets of) the pixels will
139      *  be affected.
140      */
141     bool setAlphaType(SkAlphaType);
142 
143     /** Return the address of the pixels for this SkBitmap.
144     */
getPixels()145     void* getPixels() const { return fPixels; }
146 
147     /** Return the byte size of the pixels, based on the height and rowBytes.
148         Note this truncates the result to 32bits. Call getSize64() to detect
149         if the real size exceeds 32bits.
150     */
getSize()151     size_t getSize() const { return fInfo.height() * fRowBytes; }
152 
153     /** Return the number of bytes from the pointer returned by getPixels()
154         to the end of the allocated space in the buffer. Required in
155         cases where extractSubset has been called.
156     */
getSafeSize()157     size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
158 
159     /**
160      *  Return the full size of the bitmap, in bytes.
161      */
computeSize64()162     int64_t computeSize64() const {
163         return sk_64_mul(fInfo.height(), fRowBytes);
164     }
165 
166     /**
167      *  Return the number of bytes from the pointer returned by getPixels()
168      *  to the end of the allocated space in the buffer. This may be smaller
169      *  than computeSize64() if there is any rowbytes padding beyond the width.
170      */
computeSafeSize64()171     int64_t computeSafeSize64() const {
172         return fInfo.getSafeSize64(fRowBytes);
173     }
174 
175     /** Returns true if this bitmap is marked as immutable, meaning that the
176         contents of its pixels will not change for the lifetime of the bitmap.
177     */
178     bool isImmutable() const;
179 
180     /** Marks this bitmap as immutable, meaning that the contents of its
181         pixels will not change for the lifetime of the bitmap and of the
182         underlying pixelref. This state can be set, but it cannot be
183         cleared once it is set. This state propagates to all other bitmaps
184         that share the same pixelref.
185     */
186     void setImmutable();
187 
188     /** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
189     */
isOpaque()190     bool isOpaque() const {
191         return SkAlphaTypeIsOpaque(this->alphaType());
192     }
193 
194     /** Returns true if the bitmap is volatile (i.e. should not be cached by devices.)
195     */
196     bool isVolatile() const;
197 
198     /** Specify whether this bitmap is volatile. Bitmaps are not volatile by
199         default. Temporary bitmaps that are discarded after use should be
200         marked as volatile. This provides a hint to the device that the bitmap
201         should not be cached. Providing this hint when appropriate can
202         improve performance by avoiding unnecessary overhead and resource
203         consumption on the device.
204     */
205     void setIsVolatile(bool);
206 
207     /** Reset the bitmap to its initial state (see default constructor). If we are a (shared)
208         owner of the pixels, that ownership is decremented.
209     */
210     void reset();
211 
212     /**
213      *  This will brute-force return true if all of the pixels in the bitmap
214      *  are opaque. If it fails to read the pixels, or encounters an error,
215      *  it will return false.
216      *
217      *  Since this can be an expensive operation, the bitmap stores a flag for
218      *  this (isOpaque). Only call this if you need to compute this value from
219      *  "unknown" pixels.
220      */
ComputeIsOpaque(const SkBitmap & bm)221     static bool ComputeIsOpaque(const SkBitmap& bm) {
222         SkPixmap pmap;
223         return bm.peekPixels(&pmap) && pmap.computeIsOpaque();
224     }
225 
226     /**
227      *  Return the bitmap's bounds [0, 0, width, height] as an SkRect
228      */
229     void getBounds(SkRect* bounds) const;
230     void getBounds(SkIRect* bounds) const;
231 
bounds()232     SkIRect bounds() const { return fInfo.bounds(); }
dimensions()233     SkISize dimensions() const { return fInfo.dimensions(); }
234     // Returns the bounds of this bitmap, offset by its pixelref origin.
getSubset()235     SkIRect getSubset() const {
236         return SkIRect::MakeXYWH(fPixelRefOrigin.x(), fPixelRefOrigin.y(),
237                                  fInfo.width(), fInfo.height());
238     }
239 
240     bool setInfo(const SkImageInfo&, size_t rowBytes = 0);
241 
242     enum AllocFlags {
243         kZeroPixels_AllocFlag   = 1 << 0,
244     };
245 
246     /**
247      *  Allocate the bitmap's pixels to match the requested image info. If the Factory
248      *  is non-null, call it to allcoate the pixelref. If the ImageInfo requires
249      *  a colortable, then ColorTable must be non-null.
250      *
251      *  On failure, the bitmap will be set to empty and return false.
252      */
253     bool SK_WARN_UNUSED_RESULT tryAllocPixelsFlags(const SkImageInfo& info, uint32_t flags);
allocPixelsFlags(const SkImageInfo & info,uint32_t flags)254     void allocPixelsFlags(const SkImageInfo& info, uint32_t flags) {
255         if (!this->tryAllocPixelsFlags(info, flags)) {
256             sk_throw();
257         }
258     }
259 
260 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
261     bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, sk_sp<SkColorTable>,
262                                               uint32_t flags = 0) {
263         return this->tryAllocPixelsFlags(info, flags);
264     }
265     void allocPixels(const SkImageInfo& info, sk_sp<SkColorTable>, uint32_t flags = 0) {
266         this->allocPixels(info, flags);
267     }
268 #endif
269 
270     /**
271      *  Allocate the bitmap's pixels to match the requested image info and
272      *  rowBytes. If the request cannot be met (e.g. the info is invalid or
273      *  the requested rowBytes are not compatible with the info
274      *  (e.g. rowBytes < info.minRowBytes() or rowBytes is not aligned with
275      *  the pixel size specified by info.colorType()) then false is returned
276      *  and the bitmap is set to empty.
277      */
278     bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, size_t rowBytes);
279 
allocPixels(const SkImageInfo & info,size_t rowBytes)280     void allocPixels(const SkImageInfo& info, size_t rowBytes) {
281         if (!this->tryAllocPixels(info, rowBytes)) {
282             sk_throw();
283         }
284     }
285 
tryAllocPixels(const SkImageInfo & info)286     bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info) {
287         return this->tryAllocPixels(info, info.minRowBytes());
288     }
289 
allocPixels(const SkImageInfo & info)290     void allocPixels(const SkImageInfo& info) {
291         this->allocPixels(info, info.minRowBytes());
292     }
293 
294     bool SK_WARN_UNUSED_RESULT tryAllocN32Pixels(int width, int height, bool isOpaque = false) {
295         SkImageInfo info = SkImageInfo::MakeN32(width, height,
296                                             isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
297         return this->tryAllocPixels(info);
298     }
299 
300     void allocN32Pixels(int width, int height, bool isOpaque = false) {
301         SkImageInfo info = SkImageInfo::MakeN32(width, height,
302                                             isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
303         this->allocPixels(info);
304     }
305 
306 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
307     // TEMPORARY -- remove after updating Android BitmapTests.cpp:35
allocPixels(const SkImageInfo & info,std::nullptr_t,SkColorTable *)308     void allocPixels(const SkImageInfo& info, std::nullptr_t, SkColorTable*) {
309         this->allocPixels(info);
310     }
311 #endif
312 
313     /**
314      *  Install a pixelref that wraps the specified pixels and rowBytes, and
315      *  optional ReleaseProc and context. When the pixels are no longer
316      *  referenced, if releaseProc is not null, it will be called with the
317      *  pixels and context as parameters.
318      *  On failure, the bitmap will be set to empty and return false.
319      *
320      *  If specified, the releaseProc will always be called, even on failure. It is also possible
321      *  for success but the releaseProc is immediately called (e.g. valid Info but NULL pixels).
322      */
323     bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes,
324                        void (*releaseProc)(void* addr, void* context), void* context);
325 
326     /**
327      *  Call installPixels with no ReleaseProc specified. This means that the
328      *  caller must ensure that the specified pixels are valid for the lifetime
329      *  of the created bitmap (and its pixelRef).
330      */
installPixels(const SkImageInfo & info,void * pixels,size_t rowBytes)331     bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
332         return this->installPixels(info, pixels, rowBytes, nullptr, nullptr);
333     }
334 
335 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
installPixels(const SkImageInfo & info,void * pixels,size_t rowBytes,SkColorTable *,void (* releaseProc)(void * addr,void * context),void * context)336     bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkColorTable*,
337                        void (*releaseProc)(void* addr, void* context), void* context) {
338         return this->installPixels(info, pixels, rowBytes, releaseProc, context);
339     }
340 #endif
341 
342     /**
343      *  Call installPixels with no ReleaseProc specified. This means
344      *  that the caller must ensure that the specified pixels and
345      *  colortable are valid for the lifetime of the created bitmap
346      *  (and its pixelRef).
347      */
348     bool installPixels(const SkPixmap&);
349 
350     /**
351      *  Calls installPixels() with the value in the SkMask. The caller must
352      *  ensure that the specified mask pixels are valid for the lifetime
353      *  of the created bitmap (and its pixelRef).
354      */
355     bool installMaskPixels(const SkMask&);
356 
357     /** Use this to assign a new pixel address for an existing bitmap. This
358         will automatically release any pixelref previously installed. Only call
359         this if you are handling ownership/lifetime of the pixel memory.
360 
361         If the bitmap retains a reference to the colortable (assuming it is
362         not null) it will take care of incrementing the reference count.
363 
364         @param pixels   Address for the pixels, managed by the caller.
365         @param ctable   ColorTable (or null) that matches the specified pixels
366     */
367     void setPixels(void* p);
368 
369     /** Use the standard HeapAllocator to create the pixelref that manages the
370         pixel memory. It will be sized based on the current ImageInfo.
371         If this is called multiple times, a new pixelref object will be created
372         each time.
373 
374         If the bitmap retains a reference to the colortable (assuming it is
375         not null) it will take care of incrementing the reference count.
376 
377         @param ctable   ColorTable (or null) to use with the pixels that will
378                         be allocated. Only used if colortype == kIndex_8_SkColorType
379         @return true if the allocation succeeds. If not the pixelref field of
380                      the bitmap will be unchanged.
381     */
tryAllocPixels()382     bool SK_WARN_UNUSED_RESULT tryAllocPixels() {
383         return this->tryAllocPixels((Allocator*)nullptr);
384     }
385 
allocPixels()386     void allocPixels() {
387         this->allocPixels((Allocator*)nullptr);
388     }
389 
390     /** Use the specified Allocator to create the pixelref that manages the
391         pixel memory. It will be sized based on the current ImageInfo.
392         If this is called multiple times, a new pixelref object will be created
393         each time.
394 
395         If the bitmap retains a reference to the colortable (assuming it is
396         not null) it will take care of incrementing the reference count.
397 
398         @param allocator The Allocator to use to create a pixelref that can
399                          manage the pixel memory for the current ImageInfo.
400                          If allocator is NULL, the standard HeapAllocator will be used.
401         @param ctable   ColorTable (or null) to use with the pixels that will
402                         be allocated. Only used if colortype == kIndex_8_SkColorType.
403                         If it is non-null and the colortype is not indexed, it will
404                         be ignored.
405         @return true if the allocation succeeds. If not the pixelref field of
406                      the bitmap will be unchanged.
407     */
408     bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator);
409 
allocPixels(Allocator * allocator)410     void allocPixels(Allocator* allocator) {
411         if (!this->tryAllocPixels(allocator)) {
412             sk_throw();
413         }
414     }
415 
416 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
setPixels(void * p,SkColorTable *)417     void setPixels(void* p, SkColorTable*) {
418         this->setPixels(p);
419     }
tryAllocPixels(SkColorTable *)420     bool SK_WARN_UNUSED_RESULT tryAllocPixels(SkColorTable*) {
421         return this->tryAllocPixels();
422     }
423 
allocPixels(SkColorTable *)424     void allocPixels(SkColorTable*) {
425         this->allocPixels();
426     }
tryAllocPixels(Allocator * allocator,SkColorTable *)427     bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator, SkColorTable*) {
428         return this->tryAllocPixels(allocator);
429     }
allocPixels(Allocator * allocator,SkColorTable *)430     void allocPixels(Allocator* allocator, SkColorTable*) {
431         this->allocPixels(allocator);
432     }
433 #endif
434 
435     /**
436      *  Return the current pixelref object or NULL if there is none. This does
437      *  not affect the refcount of the pixelref.
438      */
pixelRef()439     SkPixelRef* pixelRef() const { return fPixelRef.get(); }
440 
441     /**
442      *  A bitmap can reference a subset of a pixelref's pixels. That means the
443      *  bitmap's width/height can be <= the dimensions of the pixelref. The
444      *  pixelref origin is the x,y location within the pixelref's pixels for
445      *  the bitmap's top/left corner. To be valid the following must be true:
446      *
447      *  origin_x + bitmap_width  <= pixelref_width
448      *  origin_y + bitmap_height <= pixelref_height
449      *
450      *  pixelRefOrigin() returns this origin, or (0,0) if there is no pixelRef.
451      */
pixelRefOrigin()452     SkIPoint pixelRefOrigin() const { return fPixelRefOrigin; }
453 
454     /**
455      * Assign a pixelref and origin to the bitmap.  (dx,dy) specify the offset
456      * within the pixelref's pixels for the top/left corner of the bitmap. For
457      * a bitmap that encompases the entire pixels of the pixelref, these will
458      * be (0,0).
459      */
460     void setPixelRef(sk_sp<SkPixelRef>, int dx, int dy);
461 
462     /** Call this to be sure that the bitmap is valid enough to be drawn (i.e.
463         it has non-null pixels, and if required by its colortype, it has a
464         non-null colortable. Returns true if all of the above are met.
465     */
readyToDraw()466     bool readyToDraw() const {
467         return this->getPixels() != NULL;
468     }
469 
470     /** Return the bitmap's colortable, if it uses one (i.e. colorType is
471         Index_8).
472         Otherwise returns NULL. Does not affect the colortable's
473         reference count.
474     */
475 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
getColorTable()476     SkColorTable* getColorTable() const { return nullptr; }
477 #endif
478 
479     /** Returns a non-zero, unique value corresponding to the pixels in our
480         pixelref. Each time the pixels are changed (and notifyPixelsChanged
481         is called), a different generation ID will be returned. Finally, if
482         there is no pixelRef then zero is returned.
483     */
484     uint32_t getGenerationID() const;
485 
486     /** Call this if you have changed the contents of the pixels. This will in-
487         turn cause a different generation ID value to be returned from
488         getGenerationID().
489     */
490     void notifyPixelsChanged() const;
491 
492     /**
493      *  Fill the entire bitmap with the specified color.
494      *  If the bitmap's colortype does not support alpha (e.g. 565) then the alpha
495      *  of the color is ignored (treated as opaque). If the colortype only supports
496      *  alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
497      */
498     void eraseColor(SkColor c) const;
499 
500     /**
501      *  Fill the entire bitmap with the specified color.
502      *  If the bitmap's colortype does not support alpha (e.g. 565) then the alpha
503      *  of the color is ignored (treated as opaque). If the colortype only supports
504      *  alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
505      */
eraseARGB(U8CPU a,U8CPU r,U8CPU g,U8CPU b)506     void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const {
507         this->eraseColor(SkColorSetARGB(a, r, g, b));
508     }
509 
510     SK_ATTR_DEPRECATED("use eraseARGB or eraseColor")
eraseRGB(U8CPU r,U8CPU g,U8CPU b)511     void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
512         this->eraseARGB(0xFF, r, g, b);
513     }
514 
515     /**
516      *  Fill the specified area of this bitmap with the specified color.
517      *  If the bitmap's colortype does not support alpha (e.g. 565) then the alpha
518      *  of the color is ignored (treated as opaque). If the colortype only supports
519      *  alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
520      */
521     void erase(SkColor c, const SkIRect& area) const;
522 
523     // DEPRECATED
eraseArea(const SkIRect & area,SkColor c)524     void eraseArea(const SkIRect& area, SkColor c) const {
525         this->erase(c, area);
526     }
527 
528     /**
529      *  Converts the pixel at the specified coordinate to an unpremultiplied
530      *  SkColor. Note: this ignores any SkColorSpace information, and may return
531      *  lower precision data than is actually in the pixel. Alpha only
532      *  colortypes (e.g. kAlpha_8_SkColorType) return black with the appropriate
533      *  alpha set.  The value is undefined for kUnknown_SkColorType or if x or y
534      *  are out of bounds, or if the bitmap does not have any pixels.
535      */
getColor(int x,int y)536     SkColor getColor(int x, int y) const {
537         SkPixmap pixmap;
538         SkAssertResult(this->peekPixels(&pixmap));
539         return pixmap.getColor(x, y);
540     }
541 
542     /** Returns the address of the specified pixel. This performs a runtime
543         check to know the size of the pixels, and will return the same answer
544         as the corresponding size-specific method (e.g. getAddr16). Since the
545         check happens at runtime, it is much slower than using a size-specific
546         version. Unlike the size-specific methods, this routine also checks if
547         getPixels() returns null, and returns that. The size-specific routines
548         perform a debugging assert that getPixels() is not null, but they do
549         not do any runtime checks.
550     */
551     void* getAddr(int x, int y) const;
552 
553     /** Returns the address of the pixel specified by x,y for 32bit pixels.
554      *  In debug build, this asserts that the pixels are allocated and that the
555      *  colortype is 32-bit, however none of these checks are performed
556      *  in the release build.
557      */
558     inline uint32_t* getAddr32(int x, int y) const;
559 
560     /** Returns the address of the pixel specified by x,y for 16bit pixels.
561      *  In debug build, this asserts that the pixels are allocated
562      *  and that the colortype is 16-bit, however none of these checks are performed
563      *  in the release build.
564      */
565     inline uint16_t* getAddr16(int x, int y) const;
566 
567     /** Returns the address of the pixel specified by x,y for 8bit pixels.
568      *  In debug build, this asserts that the pixels are allocated
569      *  and that the colortype is 8-bit, however none of these checks are performed
570      *  in the release build.
571      */
572     inline uint8_t* getAddr8(int x, int y) const;
573 
574     /** Returns the color corresponding to the pixel specified by x,y for
575      *  colortable based bitmaps.
576      *  In debug build, this asserts that the pixels are allocated,
577      *  that the colortype is indexed, and that the colortable is allocated,
578      *  however none of these checks are performed in the release build.
579      */
580     inline SkPMColor getIndex8Color(int x, int y) const;
581 
582     /** Set dst to be a setset of this bitmap. If possible, it will share the
583         pixel memory, and just point into a subset of it. However, if the colortype
584         does not support this, a local copy will be made and associated with
585         the dst bitmap. If the subset rectangle, intersected with the bitmap's
586         dimensions is empty, or if there is an unsupported colortype, false will be
587         returned and dst will be untouched.
588         @param dst  The bitmap that will be set to a subset of this bitmap
589         @param subset The rectangle of pixels in this bitmap that dst will
590                       reference.
591         @return true if the subset copy was successfully made.
592     */
593     bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
594 
595     /**
596      *  Copy the bitmap's pixels into the specified buffer (pixels + rowBytes),
597      *  converting them into the requested format (SkImageInfo). The src pixels are read
598      *  starting at the specified (srcX,srcY) offset, relative to the top-left corner.
599      *
600      *  The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
601      *
602      *      srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
603      *
604      *  srcR is intersected with the bounds of the bitmap. If this intersection is not empty,
605      *  then we have two sets of pixels (of equal size). Replace the dst pixels with the
606      *  corresponding src pixels, performing any colortype/alphatype transformations needed
607      *  (in the case where the src and dst have different colortypes or alphatypes).
608      *
609      *  This call can fail, returning false, for several reasons:
610      *  - If srcR does not intersect the bitmap bounds.
611      *  - If the requested colortype/alphatype cannot be converted from the src's types.
612      *  - If the src pixels are not available.
613      */
614     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
615                     int srcX, int srcY, SkTransferFunctionBehavior behavior) const;
readPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY)616     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
617                     int srcX, int srcY) const {
618         return this->readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY,
619                 SkTransferFunctionBehavior::kRespect);
620     }
621     bool readPixels(const SkPixmap& dst, int srcX, int srcY) const;
readPixels(const SkPixmap & dst)622     bool readPixels(const SkPixmap& dst) const {
623         return this->readPixels(dst, 0, 0);
624     }
625 
626     /**
627      *  Copy the src pixmap's pixels into this bitmap, offset by dstX, dstY.
628      *
629      *  This is logically the same as creating a bitmap around src, and calling readPixels on it
630      *  with this bitmap as the dst.
631      */
writePixels(const SkPixmap & src,int dstX,int dstY)632     bool writePixels(const SkPixmap& src, int dstX, int dstY) {
633         return this->writePixels(src, dstX, dstY, SkTransferFunctionBehavior::kRespect);
634     }
writePixels(const SkPixmap & src)635     bool writePixels(const SkPixmap& src) {
636         return this->writePixels(src, 0, 0);
637     }
638     bool writePixels(const SkPixmap& src, int x, int y, SkTransferFunctionBehavior behavior);
639 
640 #ifdef SK_BUILD_FOR_ANDROID
hasHardwareMipMap()641     bool hasHardwareMipMap() const {
642         return (fFlags & kHasHardwareMipMap_Flag) != 0;
643     }
644 
setHasHardwareMipMap(bool hasHardwareMipMap)645     void setHasHardwareMipMap(bool hasHardwareMipMap) {
646         if (hasHardwareMipMap) {
647             fFlags |= kHasHardwareMipMap_Flag;
648         } else {
649             fFlags &= ~kHasHardwareMipMap_Flag;
650         }
651     }
652 #endif
653 
extractAlpha(SkBitmap * dst)654     bool extractAlpha(SkBitmap* dst) const {
655         return this->extractAlpha(dst, NULL, NULL, NULL);
656     }
657 
extractAlpha(SkBitmap * dst,const SkPaint * paint,SkIPoint * offset)658     bool extractAlpha(SkBitmap* dst, const SkPaint* paint,
659                       SkIPoint* offset) const {
660         return this->extractAlpha(dst, paint, NULL, offset);
661     }
662 
663     /** Set dst to contain alpha layer of this bitmap. If destination bitmap
664         fails to be initialized, e.g. because allocator can't allocate pixels
665         for it, dst will not be modified and false will be returned.
666 
667         @param dst The bitmap to be filled with alpha layer
668         @param paint The paint to draw with
669         @param allocator Allocator used to allocate the pixelref for the dst
670                          bitmap. If this is null, the standard HeapAllocator
671                          will be used.
672         @param offset If not null, it is set to top-left coordinate to position
673                       the returned bitmap so that it visually lines up with the
674                       original
675     */
676     bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
677                       SkIPoint* offset) const;
678 
679     /**
680      *  If the pixels are available from this bitmap return true, and fill out the
681      *  specified pixmap (if not null). If there are no pixels, return false and
682      *  ignore the pixmap parameter.
683      *
684      *  Note: if this returns true, the results (in the pixmap) are only valid until the bitmap
685      *  is changed in any way, in which case the results are invalid.
686      */
687     bool peekPixels(SkPixmap*) const;
688 
SkDEBUGCODE(void validate ()const;)689     SkDEBUGCODE(void validate() const;)
690 
691     class Allocator : public SkRefCnt {
692     public:
693         /** Allocate the pixel memory for the bitmap, given its dimensions and
694             colortype. Return true on success, where success means either setPixels
695             or setPixelRef was called. If the colortype requires a colortable,
696             it also must be installed via setColorTable. If false is returned,
697             the bitmap and colortable should be left unchanged.
698         */
699 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
700         virtual bool allocPixelRef(SkBitmap*, SkColorTable*) = 0;
701 #else
702         virtual bool allocPixelRef(SkBitmap*) = 0;
703 #endif
704     private:
705         typedef SkRefCnt INHERITED;
706     };
707 
708     /** Subclass of Allocator that returns a pixelref that allocates its pixel
709         memory from the heap. This is the default Allocator invoked by
710         allocPixels().
711     */
712     class HeapAllocator : public Allocator {
713     public:
714 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
715         bool allocPixelRef(SkBitmap*, SkColorTable*) override;
716 #else
717         bool allocPixelRef(SkBitmap*) override;
718 #endif
719     };
720 
721     SK_TO_STRING_NONVIRT()
722 
723 private:
724     enum Flags {
725         kImageIsVolatile_Flag   = 0x02,
726 #ifdef SK_BUILD_FOR_ANDROID
727         /* A hint for the renderer responsible for drawing this bitmap
728          * indicating that it should attempt to use mipmaps when this bitmap
729          * is drawn scaled down.
730          */
731         kHasHardwareMipMap_Flag = 0x08,
732 #endif
733     };
734 
735     sk_sp<SkPixelRef>   fPixelRef;
736     void*               fPixels;
737     SkIPoint            fPixelRefOrigin;
738     SkImageInfo         fInfo;
739     uint32_t            fRowBytes;
740     uint8_t             fFlags;
741 
742     /*  Unreference any pixelrefs or colortables
743     */
744     void freePixels();
745     void updatePixelsFromRef();
746 
747     static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&);
748     static bool ReadRawPixels(SkReadBuffer*, SkBitmap*);
749 
750     friend class SkReadBuffer;        // unflatten, rawpixels
751     friend class SkBinaryWriteBuffer; // rawpixels
752 };
753 
754 ///////////////////////////////////////////////////////////////////////////////
755 
getAddr32(int x,int y)756 inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
757     SkASSERT(fPixels);
758     SkASSERT(4 == this->bytesPerPixel());
759     SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
760     return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
761 }
762 
getAddr16(int x,int y)763 inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
764     SkASSERT(fPixels);
765     SkASSERT(2 == this->bytesPerPixel());
766     SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
767     return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
768 }
769 
getAddr8(int x,int y)770 inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
771     SkASSERT(fPixels);
772     SkASSERT(1 == this->bytesPerPixel());
773     SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
774     return (uint8_t*)fPixels + y * fRowBytes + x;
775 }
776 
777 #endif
778