• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
16 class SkColorTable;
17 #endif
18 class SkData;
19 struct SkMask;
20 
21 /**
22  *  Pairs SkImageInfo with actual pixels and rowbytes. This class does not try to manage the
23  *  lifetime of the pixel memory (nor the colortable if provided).
24  */
25 class SK_API SkPixmap {
26 public:
SkPixmap()27     SkPixmap()
28         : fPixels(NULL), fRowBytes(0), fInfo(SkImageInfo::MakeUnknown(0, 0))
29     {}
30 
SkPixmap(const SkImageInfo & info,const void * addr,size_t rowBytes)31     SkPixmap(const SkImageInfo& info, const void* addr, size_t rowBytes)
32         : fPixels(addr), fRowBytes(rowBytes), fInfo(info)
33     {}
34 
35     void reset();
36     void reset(const SkImageInfo& info, const void* addr, size_t rowBytes);
reset(const SkImageInfo & info)37     void reset(const SkImageInfo& info) {
38         this->reset(info, NULL, 0);
39     }
40 
41     // overrides the colorspace in the SkImageInfo of the pixmap
42     void setColorSpace(sk_sp<SkColorSpace>);
43 
44     /**
45      *  If supported, set this pixmap to point to the pixels in the specified mask and return true.
46      *  On failure, return false and set this pixmap to empty.
47      */
48     bool SK_WARN_UNUSED_RESULT reset(const SkMask&);
49 
50     /**
51      *  Computes the intersection of area and this pixmap. If that intersection is non-empty,
52      *  set subset to that intersection and return true.
53      *
54      *  On failure, return false and ignore the subset parameter.
55      */
56     bool SK_WARN_UNUSED_RESULT extractSubset(SkPixmap* subset, const SkIRect& area) const;
57 
info()58     const SkImageInfo& info() const { return fInfo; }
rowBytes()59     size_t rowBytes() const { return fRowBytes; }
addr()60     const void* addr() const { return fPixels; }
61 
width()62     int width() const { return fInfo.width(); }
height()63     int height() const { return fInfo.height(); }
colorType()64     SkColorType colorType() const { return fInfo.colorType(); }
alphaType()65     SkAlphaType alphaType() const { return fInfo.alphaType(); }
colorSpace()66     SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
isOpaque()67     bool isOpaque() const { return fInfo.isOpaque(); }
68 
bounds()69     SkIRect bounds() const { return SkIRect::MakeWH(this->width(), this->height()); }
70 
71     /**
72      *  Return the rowbytes expressed as a number of pixels (like width and height).
73      */
rowBytesAsPixels()74     int rowBytesAsPixels() const { return int(fRowBytes >> this->shiftPerPixel()); }
75 
76     /**
77      *  Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel
78      *  colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType.
79      */
shiftPerPixel()80     int shiftPerPixel() const { return fInfo.shiftPerPixel(); }
81 
getSize64()82     uint64_t getSize64() const { return sk_64_mul(fInfo.height(), fRowBytes); }
getSafeSize64()83     uint64_t getSafeSize64() const { return fInfo.getSafeSize64(fRowBytes); }
getSafeSize()84     size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
85 
86     /**
87      *  This will brute-force return true if all of the pixels in the pixmap
88      *  are opaque. If there are no pixels, or encounters an error, returns false.
89      */
90     bool computeIsOpaque() const;
91 
92     /**
93      *  Converts the pixel at the specified coordinate to an unpremultiplied
94      *  SkColor. Note: this ignores any SkColorSpace information, and may return
95      *  lower precision data than is actually in the pixel. Alpha only
96      *  colortypes (e.g. kAlpha_8_SkColorType) return black with the appropriate
97      *  alpha set.  The value is undefined for kUnknown_SkColorType or if x or y
98      *  are out of bounds, or if the pixtap does not have any pixels.
99      */
100     SkColor getColor(int x, int y) const;
101 
addr(int x,int y)102     const void* addr(int x, int y) const {
103         return (const char*)fPixels + fInfo.computeOffset(x, y, fRowBytes);
104     }
addr8()105     const uint8_t* addr8() const {
106         SkASSERT(1 == SkColorTypeBytesPerPixel(fInfo.colorType()));
107         return reinterpret_cast<const uint8_t*>(fPixels);
108     }
addr16()109     const uint16_t* addr16() const {
110         SkASSERT(2 == SkColorTypeBytesPerPixel(fInfo.colorType()));
111         return reinterpret_cast<const uint16_t*>(fPixels);
112     }
addr32()113     const uint32_t* addr32() const {
114         SkASSERT(4 == SkColorTypeBytesPerPixel(fInfo.colorType()));
115         return reinterpret_cast<const uint32_t*>(fPixels);
116     }
addr64()117     const uint64_t* addr64() const {
118         SkASSERT(8 == SkColorTypeBytesPerPixel(fInfo.colorType()));
119         return reinterpret_cast<const uint64_t*>(fPixels);
120     }
addrF16()121     const uint16_t* addrF16() const {
122         SkASSERT(8 == SkColorTypeBytesPerPixel(fInfo.colorType()));
123         SkASSERT(kRGBA_F16_SkColorType == fInfo.colorType());
124         return reinterpret_cast<const uint16_t*>(fPixels);
125     }
126 
127     // Offset by the specified x,y coordinates
128 
addr8(int x,int y)129     const uint8_t* addr8(int x, int y) const {
130         SkASSERT((unsigned)x < (unsigned)fInfo.width());
131         SkASSERT((unsigned)y < (unsigned)fInfo.height());
132         return (const uint8_t*)((const char*)this->addr8() + y * fRowBytes + (x << 0));
133     }
addr16(int x,int y)134     const uint16_t* addr16(int x, int y) const {
135         SkASSERT((unsigned)x < (unsigned)fInfo.width());
136         SkASSERT((unsigned)y < (unsigned)fInfo.height());
137         return (const uint16_t*)((const char*)this->addr16() + y * fRowBytes + (x << 1));
138     }
addr32(int x,int y)139     const uint32_t* addr32(int x, int y) const {
140         SkASSERT((unsigned)x < (unsigned)fInfo.width());
141         SkASSERT((unsigned)y < (unsigned)fInfo.height());
142         return (const uint32_t*)((const char*)this->addr32() + y * fRowBytes + (x << 2));
143     }
addr64(int x,int y)144     const uint64_t* addr64(int x, int y) const {
145         SkASSERT((unsigned)x < (unsigned)fInfo.width());
146         SkASSERT((unsigned)y < (unsigned)fInfo.height());
147         return (const uint64_t*)((const char*)this->addr64() + y * fRowBytes + (x << 3));
148     }
addrF16(int x,int y)149     const uint16_t* addrF16(int x, int y) const {
150         SkASSERT(kRGBA_F16_SkColorType == fInfo.colorType());
151         return reinterpret_cast<const uint16_t*>(this->addr64(x, y));
152     }
153 
154     // Writable versions
155 
writable_addr()156     void* writable_addr() const { return const_cast<void*>(fPixels); }
writable_addr(int x,int y)157     void* writable_addr(int x, int y) const {
158         return const_cast<void*>(this->addr(x, y));
159     }
writable_addr8(int x,int y)160     uint8_t* writable_addr8(int x, int y) const {
161         return const_cast<uint8_t*>(this->addr8(x, y));
162     }
writable_addr16(int x,int y)163     uint16_t* writable_addr16(int x, int y) const {
164         return const_cast<uint16_t*>(this->addr16(x, y));
165     }
writable_addr32(int x,int y)166     uint32_t* writable_addr32(int x, int y) const {
167         return const_cast<uint32_t*>(this->addr32(x, y));
168     }
writable_addr64(int x,int y)169     uint64_t* writable_addr64(int x, int y) const {
170         return const_cast<uint64_t*>(this->addr64(x, y));
171     }
writable_addrF16(int x,int y)172     uint16_t* writable_addrF16(int x, int y) const {
173         return reinterpret_cast<uint16_t*>(writable_addr64(x, y));
174     }
175 
176     // copy methods
177 
178     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
179                     int srcX, int srcY, SkTransferFunctionBehavior behavior) const;
readPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes)180     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes) const {
181         return this->readPixels(dstInfo, dstPixels, dstRowBytes, 0, 0);
182     }
readPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY)183     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, int srcX,
184                     int srcY) const {
185         return this->readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY,
186                                 SkTransferFunctionBehavior::kRespect);
187     }
readPixels(const SkPixmap & dst,int srcX,int srcY)188     bool readPixels(const SkPixmap& dst, int srcX, int srcY) const {
189         return this->readPixels(dst.info(), dst.writable_addr(), dst.rowBytes(), srcX, srcY);
190     }
readPixels(const SkPixmap & dst)191     bool readPixels(const SkPixmap& dst) const {
192         return this->readPixels(dst.info(), dst.writable_addr(), dst.rowBytes(), 0, 0);
193     }
194 
195     /**
196      *  Copy the pixels from this pixmap into the dst pixmap, converting as needed into dst's
197      *  colortype/alphatype. If the conversion cannot be performed, false is returned.
198      *
199      *  If dst's dimensions differ from the src dimension, the image will be scaled, applying the
200      *  specified filter-quality.
201      */
202     bool scalePixels(const SkPixmap& dst, SkFilterQuality) const;
203 
204     /**
205      *  Returns true if pixels were written to (e.g. if colorType is kUnknown_SkColorType, this
206      *  will return false). If subset does not intersect the bounds of this pixmap, returns false.
207      */
208     bool erase(SkColor, const SkIRect& subset) const;
209 
erase(SkColor color)210     bool erase(SkColor color) const { return this->erase(color, this->bounds()); }
211     bool erase(const SkColor4f&, const SkIRect* subset = nullptr) const;
212 
213 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
SkPixmap(const SkImageInfo & info,const void * addr,size_t rowBytes,SkColorTable *)214     SkPixmap(const SkImageInfo& info, const void* addr, size_t rowBytes, SkColorTable*)
215     : fPixels(addr), fRowBytes(rowBytes), fInfo(info)
216     {}
reset(const SkImageInfo & info,const void * addr,size_t rowBytes,SkColorTable *)217     void reset(const SkImageInfo& info, const void* addr, size_t rowBytes,
218                SkColorTable*) {
219         this->reset(info, addr, rowBytes);
220     }
ctable()221     SkColorTable* ctable() const { return nullptr; }
222 #endif
223 
224 private:
225     const void*     fPixels;
226     size_t          fRowBytes;
227     SkImageInfo     fInfo;
228 };
229 
230 #endif
231