LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/core - SkBitmap.h (source / functions) Hit Total Coverage
Test: output.info Lines: 14 91 15.4 %
Date: 2017-07-14 16:53:18 Functions: 13 47 27.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13