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