LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/core - SkPixmap.h (source / functions) Hit Total Coverage
Test: output.info Lines: 53 84 63.1 %
Date: 2017-07-14 16:53:18 Functions: 31 45 68.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2015 Google Inc.
       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 SkPixmap_DEFINED
       9             : #define SkPixmap_DEFINED
      10             : 
      11             : #include "SkColor.h"
      12             : #include "SkFilterQuality.h"
      13             : #include "SkImageInfo.h"
      14             : 
      15             : class SkColorTable;
      16             : class SkData;
      17             : struct SkMask;
      18             : 
      19             : /**
      20             :  *  Pairs SkImageInfo with actual pixels and rowbytes. This class does not try to manage the
      21             :  *  lifetime of the pixel memory (nor the colortable if provided).
      22             :  */
      23        5109 : class SK_API SkPixmap {
      24             : public:
      25        2283 :     SkPixmap()
      26        2283 :         : fPixels(NULL), fCTable(NULL), fRowBytes(0), fInfo(SkImageInfo::MakeUnknown(0, 0))
      27        2283 :     {}
      28             : 
      29         243 :     SkPixmap(const SkImageInfo& info, const void* addr, size_t rowBytes,
      30             :              SkColorTable* ctable = NULL)
      31         243 :         : fPixels(addr), fCTable(ctable), fRowBytes(rowBytes), fInfo(info)
      32             :     {
      33         243 :         if (kIndex_8_SkColorType == info.colorType()) {
      34           0 :             SkASSERT(ctable);
      35             :         } else {
      36         243 :             SkASSERT(NULL == ctable);
      37             :         }
      38         243 :     }
      39             : 
      40             :     void reset();
      41             :     void reset(const SkImageInfo& info, const void* addr, size_t rowBytes,
      42             :                SkColorTable* ctable = NULL);
      43             :     void reset(const SkImageInfo& info) {
      44             :         this->reset(info, NULL, 0, NULL);
      45             :     }
      46             : 
      47             :     // overrides the colorspace in the SkImageInfo of the pixmap
      48             :     void setColorSpace(sk_sp<SkColorSpace>);
      49             : 
      50             :     /**
      51             :      *  If supported, set this pixmap to point to the pixels in the specified mask and return true.
      52             :      *  On failure, return false and set this pixmap to empty.
      53             :      */
      54             :     bool SK_WARN_UNUSED_RESULT reset(const SkMask&);
      55             : 
      56             :     /**
      57             :      *  Computes the intersection of area and this pixmap. If that intersection is non-empty,
      58             :      *  set subset to that intersection and return true.
      59             :      *
      60             :      *  On failure, return false and ignore the subset parameter.
      61             :      */
      62             :     bool SK_WARN_UNUSED_RESULT extractSubset(SkPixmap* subset, const SkIRect& area) const;
      63             : 
      64        2894 :     const SkImageInfo& info() const { return fInfo; }
      65        3339 :     size_t rowBytes() const { return fRowBytes; }
      66        4692 :     const void* addr() const { return fPixels; }
      67         334 :     SkColorTable* ctable() const { return fCTable; }
      68             : 
      69       25036 :     int width() const { return fInfo.width(); }
      70       21346 :     int height() const { return fInfo.height(); }
      71        3940 :     SkColorType colorType() const { return fInfo.colorType(); }
      72         259 :     SkAlphaType alphaType() const { return fInfo.alphaType(); }
      73         501 :     SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
      74         341 :     bool isOpaque() const { return fInfo.isOpaque(); }
      75             : 
      76          25 :     SkIRect bounds() const { return SkIRect::MakeWH(this->width(), this->height()); }
      77             : 
      78             :     /**
      79             :      *  Return the rowbytes expressed as a number of pixels (like width and height).
      80             :      */
      81           0 :     int rowBytesAsPixels() const { return int(fRowBytes >> this->shiftPerPixel()); }
      82             : 
      83             :     /**
      84             :      *  Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel
      85             :      *  colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType.
      86             :      */
      87          46 :     int shiftPerPixel() const { return fInfo.shiftPerPixel(); }
      88             : 
      89           0 :     uint64_t getSize64() const { return sk_64_mul(fInfo.height(), fRowBytes); }
      90             :     uint64_t getSafeSize64() const { return fInfo.getSafeSize64(fRowBytes); }
      91           0 :     size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
      92             : 
      93             :     /**
      94             :      *  This will brute-force return true if all of the pixels in the pixmap
      95             :      *  are opaque. If there are no pixels, or encounters an error, returns false.
      96             :      */
      97             :     bool computeIsOpaque() const;
      98             : 
      99             :     /**
     100             :      *  Converts the pixel at the specified coordinate to an unpremultiplied
     101             :      *  SkColor. Note: this ignores any SkColorSpace information, and may return
     102             :      *  lower precision data than is actually in the pixel. Alpha only
     103             :      *  colortypes (e.g. kAlpha_8_SkColorType) return black with the appropriate
     104             :      *  alpha set.  The value is undefined for kUnknown_SkColorType or if x or y
     105             :      *  are out of bounds, or if the pixtap does not have any pixels.
     106             :      */
     107             :     SkColor getColor(int x, int y) const;
     108             : 
     109          90 :     const void* addr(int x, int y) const {
     110          90 :         return (const char*)fPixels + fInfo.computeOffset(x, y, fRowBytes);
     111             :     }
     112          62 :     const uint8_t* addr8() const {
     113          62 :         SkASSERT(1 == SkColorTypeBytesPerPixel(fInfo.colorType()));
     114          62 :         return reinterpret_cast<const uint8_t*>(fPixels);
     115             :     }
     116           0 :     const uint16_t* addr16() const {
     117           0 :         SkASSERT(2 == SkColorTypeBytesPerPixel(fInfo.colorType()));
     118           0 :         return reinterpret_cast<const uint16_t*>(fPixels);
     119             :     }
     120       21508 :     const uint32_t* addr32() const {
     121       21508 :         SkASSERT(4 == SkColorTypeBytesPerPixel(fInfo.colorType()));
     122       21508 :         return reinterpret_cast<const uint32_t*>(fPixels);
     123             :     }
     124           0 :     const uint64_t* addr64() const {
     125           0 :         SkASSERT(8 == SkColorTypeBytesPerPixel(fInfo.colorType()));
     126           0 :         return reinterpret_cast<const uint64_t*>(fPixels);
     127             :     }
     128             :     const uint16_t* addrF16() const {
     129             :         SkASSERT(8 == SkColorTypeBytesPerPixel(fInfo.colorType()));
     130             :         SkASSERT(kRGBA_F16_SkColorType == fInfo.colorType());
     131             :         return reinterpret_cast<const uint16_t*>(fPixels);
     132             :     }
     133             : 
     134             :     // Offset by the specified x,y coordinates
     135             : 
     136          62 :     const uint8_t* addr8(int x, int y) const {
     137          62 :         SkASSERT((unsigned)x < (unsigned)fInfo.width());
     138          62 :         SkASSERT((unsigned)y < (unsigned)fInfo.height());
     139          62 :         return (const uint8_t*)((const char*)this->addr8() + y * fRowBytes + (x << 0));
     140             :     }
     141           0 :     const uint16_t* addr16(int x, int y) const {
     142           0 :         SkASSERT((unsigned)x < (unsigned)fInfo.width());
     143           0 :         SkASSERT((unsigned)y < (unsigned)fInfo.height());
     144           0 :         return (const uint16_t*)((const char*)this->addr16() + y * fRowBytes + (x << 1));
     145             :     }
     146       21508 :     const uint32_t* addr32(int x, int y) const {
     147       21508 :         SkASSERT((unsigned)x < (unsigned)fInfo.width());
     148       21508 :         SkASSERT((unsigned)y < (unsigned)fInfo.height());
     149       21508 :         return (const uint32_t*)((const char*)this->addr32() + y * fRowBytes + (x << 2));
     150             :     }
     151           0 :     const uint64_t* addr64(int x, int y) const {
     152           0 :         SkASSERT((unsigned)x < (unsigned)fInfo.width());
     153           0 :         SkASSERT((unsigned)y < (unsigned)fInfo.height());
     154           0 :         return (const uint64_t*)((const char*)this->addr64() + y * fRowBytes + (x << 3));
     155             :     }
     156             :     const uint16_t* addrF16(int x, int y) const {
     157             :         SkASSERT(kRGBA_F16_SkColorType == fInfo.colorType());
     158             :         return reinterpret_cast<const uint16_t*>(this->addr64(x, y));
     159             :     }
     160             : 
     161             :     // Writable versions
     162             : 
     163          35 :     void* writable_addr() const { return const_cast<void*>(fPixels); }
     164          73 :     void* writable_addr(int x, int y) const {
     165          73 :         return const_cast<void*>(this->addr(x, y));
     166             :     }
     167          58 :     uint8_t* writable_addr8(int x, int y) const {
     168          58 :         return const_cast<uint8_t*>(this->addr8(x, y));
     169             :     }
     170           0 :     uint16_t* writable_addr16(int x, int y) const {
     171           0 :         return const_cast<uint16_t*>(this->addr16(x, y));
     172             :     }
     173        6748 :     uint32_t* writable_addr32(int x, int y) const {
     174        6748 :         return const_cast<uint32_t*>(this->addr32(x, y));
     175             :     }
     176           0 :     uint64_t* writable_addr64(int x, int y) const {
     177           0 :         return const_cast<uint64_t*>(this->addr64(x, y));
     178             :     }
     179             :     uint16_t* writable_addrF16(int x, int y) const {
     180             :         return reinterpret_cast<uint16_t*>(writable_addr64(x, y));
     181             :     }
     182             : 
     183             :     // copy methods
     184             : 
     185             :     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
     186             :                     int srcX, int srcY) const;
     187           0 :     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes) const {
     188           0 :         return this->readPixels(dstInfo, dstPixels, dstRowBytes, 0, 0);
     189             :     }
     190             :     bool readPixels(const SkPixmap& dst, int srcX, int srcY) const {
     191             :         return this->readPixels(dst.info(), dst.writable_addr(), dst.rowBytes(), srcX, srcY);
     192             :     }
     193           0 :     bool readPixels(const SkPixmap& dst) const {
     194           0 :         return this->readPixels(dst.info(), dst.writable_addr(), dst.rowBytes(), 0, 0);
     195             :     }
     196             : 
     197             :     /**
     198             :      *  Copy the pixels from this pixmap into the dst pixmap, converting as needed into dst's
     199             :      *  colortype/alphatype. If the conversion cannot be performed, false is returned.
     200             :      *
     201             :      *  If dst's dimensions differ from the src dimension, the image will be scaled, applying the
     202             :      *  specified filter-quality.
     203             :      */
     204             :     bool scalePixels(const SkPixmap& dst, SkFilterQuality) const;
     205             : 
     206             :     /**
     207             :      *  Returns true if pixels were written to (e.g. if colorType is kUnknown_SkColorType, this
     208             :      *  will return false). If subset does not intersect the bounds of this pixmap, returns false.
     209             :      */
     210             :     bool erase(SkColor, const SkIRect& subset) const;
     211             : 
     212           0 :     bool erase(SkColor color) const { return this->erase(color, this->bounds()); }
     213             :     bool erase(const SkColor4f&, const SkIRect* subset = nullptr) const;
     214             : 
     215             : private:
     216             :     const void*     fPixels;
     217             :     SkColorTable*   fCTable;
     218             :     size_t          fRowBytes;
     219             :     SkImageInfo     fInfo;
     220             : };
     221             : 
     222             : /////////////////////////////////////////////////////////////////////////////////////////////
     223             : 
     224             : /////////////////////////////////////////////////////////////////////////////////////////////
     225             : 
     226             : class SK_API SkAutoPixmapUnlock : ::SkNoncopyable {
     227             : public:
     228         152 :     SkAutoPixmapUnlock() : fUnlockProc(NULL), fIsLocked(false) {}
     229             :     SkAutoPixmapUnlock(const SkPixmap& pm, void (*unlock)(void*), void* ctx)
     230             :         : fUnlockProc(unlock), fUnlockContext(ctx), fPixmap(pm), fIsLocked(true)
     231             :     {}
     232         152 :     ~SkAutoPixmapUnlock() { this->unlock(); }
     233             : 
     234             :     /**
     235             :      *  Return the currently locked pixmap. Undefined if it has been unlocked.
     236             :      */
     237         152 :     const SkPixmap& pixmap() const {
     238         152 :         SkASSERT(this->isLocked());
     239         152 :         return fPixmap;
     240             :     }
     241             : 
     242         152 :     bool isLocked() const { return fIsLocked; }
     243             : 
     244             :     /**
     245             :      *  Unlocks the pixmap. Can safely be called more than once as it will only call the underlying
     246             :      *  unlock-proc once.
     247             :      */
     248         304 :     void unlock() {
     249         304 :         if (fUnlockProc) {
     250           0 :             SkASSERT(fIsLocked);
     251           0 :             fUnlockProc(fUnlockContext);
     252           0 :             fUnlockProc = NULL;
     253           0 :             fIsLocked = false;
     254             :         }
     255         304 :     }
     256             : 
     257             :     /**
     258             :      *  If there is a currently locked pixmap, unlock it, then copy the specified pixmap
     259             :      *  and (optional) unlock proc/context.
     260             :      */
     261             :     void reset(const SkPixmap& pm, void (*unlock)(void*), void* ctx);
     262             : 
     263             : private:
     264             :     void        (*fUnlockProc)(void*);
     265             :     void*       fUnlockContext;
     266             :     SkPixmap    fPixmap;
     267             :     bool        fIsLocked;
     268             : 
     269             :     friend class SkBitmap;
     270             : };
     271             : 
     272             : #endif

Generated by: LCOV version 1.13