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 81 const SkImageInfo& info() const { return fInfo; } 82 83 int width() const { return fInfo.width(); } 84 int height() const { return fInfo.height(); } 85 SkColorType colorType() const { return fInfo.colorType(); } 86 SkAlphaType alphaType() const { return fInfo.alphaType(); } 87 SkColorSpace* colorSpace() const { return fInfo.colorSpace(); } 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 */ 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 */ 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 */ 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 */ 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 */ 121 bool isNull() const { return nullptr == fPixelRef; } 122 123 /** Return true iff drawing this bitmap has no effect. 124 */ 125 bool drawsNothing() const { 126 return this->empty() || this->isNull(); 127 } 128 129 /** Return the number of bytes between subsequent rows of the bitmap. */ 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 */ 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 */ 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 */ 157 size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); } 158 159 /** 160 * Return the full size of the bitmap, in bytes. 161 */ 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 */ 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 */ 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 */ 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 232 SkIRect bounds() const { return fInfo.bounds(); } 233 SkISize dimensions() const { return fInfo.dimensions(); } 234 // Returns the bounds of this bitmap, offset by its pixelref origin. 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); 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 280 void allocPixels(const SkImageInfo& info, size_t rowBytes) { 281 if (!this->tryAllocPixels(info, rowBytes)) { 282 sk_throw(); 283 } 284 } 285 286 bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info) { 287 return this->tryAllocPixels(info, info.minRowBytes()); 288 } 289 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 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 */ 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 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 */ 382 bool SK_WARN_UNUSED_RESULT tryAllocPixels() { 383 return this->tryAllocPixels((Allocator*)nullptr); 384 } 385 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 410 void allocPixels(Allocator* allocator) { 411 if (!this->tryAllocPixels(allocator)) { 412 sk_throw(); 413 } 414 } 415 416 #ifdef SK_SUPPORT_LEGACY_COLORTABLE 417 void setPixels(void* p, SkColorTable*) { 418 this->setPixels(p); 419 } 420 bool SK_WARN_UNUSED_RESULT tryAllocPixels(SkColorTable*) { 421 return this->tryAllocPixels(); 422 } 423 424 void allocPixels(SkColorTable*) { 425 this->allocPixels(); 426 } 427 bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator, SkColorTable*) { 428 return this->tryAllocPixels(allocator); 429 } 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 */ 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 */ 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 */ 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 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 */ 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") 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 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 */ 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; 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; 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 */ 632 bool writePixels(const SkPixmap& src, int dstX, int dstY) { 633 return this->writePixels(src, dstX, dstY, SkTransferFunctionBehavior::kRespect); 634 } 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 641 bool hasHardwareMipMap() const { 642 return (fFlags & kHasHardwareMipMap_Flag) != 0; 643 } 644 645 void setHasHardwareMipMap(bool hasHardwareMipMap) { 646 if (hasHardwareMipMap) { 647 fFlags |= kHasHardwareMipMap_Flag; 648 } else { 649 fFlags &= ~kHasHardwareMipMap_Flag; 650 } 651 } 652 #endif 653 654 bool extractAlpha(SkBitmap* dst) const { 655 return this->extractAlpha(dst, NULL, NULL, NULL); 656 } 657 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 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 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 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 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