• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 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 SkImageInfo_DEFINED
9 #define SkImageInfo_DEFINED
10 
11 #include "include/core/SkColorSpace.h"
12 #include "include/core/SkMath.h"
13 #include "include/core/SkRect.h"
14 #include "include/core/SkSize.h"
15 
16 #include "include/private/SkTFitsIn.h"
17 #include "include/private/SkTo.h"
18 
19 class SkReadBuffer;
20 class SkWriteBuffer;
21 
22 /** \enum SkImageInfo::SkAlphaType
23     Describes how to interpret the alpha component of a pixel. A pixel may
24     be opaque, or alpha, describing multiple levels of transparency.
25 
26     In simple blending, alpha weights the draw color and the destination
27     color to create a new color. If alpha describes a weight from zero to one:
28 
29     new color = draw color * alpha + destination color * (1 - alpha)
30 
31     In practice alpha is encoded in two or more bits, where 1.0 equals all bits set.
32 
33     RGB may have alpha included in each component value; the stored
34     value is the original RGB multiplied by alpha. Premultiplied color
35     components improve performance.
36 */
37 enum SkAlphaType : int {
38     kUnknown_SkAlphaType,                          //!< uninitialized
39     kOpaque_SkAlphaType,                           //!< pixel is opaque
40     kPremul_SkAlphaType,                           //!< pixel components are premultiplied by alpha
41     kUnpremul_SkAlphaType,                         //!< pixel components are independent of alpha
42     kLastEnum_SkAlphaType = kUnpremul_SkAlphaType, //!< last valid value
43 };
44 
45 /** Returns true if SkAlphaType equals kOpaque_SkAlphaType.
46 
47     kOpaque_SkAlphaType is a hint that the SkColorType is opaque, or that all
48     alpha values are set to their 1.0 equivalent. If SkAlphaType is
49     kOpaque_SkAlphaType, and SkColorType is not opaque, then the result of
50     drawing any pixel with a alpha value less than 1.0 is undefined.
51 */
SkAlphaTypeIsOpaque(SkAlphaType at)52 static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
53     return kOpaque_SkAlphaType == at;
54 }
55 
56 ///////////////////////////////////////////////////////////////////////////////
57 
58 /** \enum SkImageInfo::SkColorType
59     Describes how pixel bits encode color. A pixel may be an alpha mask, a grayscale, RGB, or ARGB.
60 
61     kN32_SkColorType selects the native 32-bit ARGB format for the current configuration. This can
62     lead to inconsistent results across platforms, so use with caution.
63 */
64 enum SkColorType : int {
65     kUnknown_SkColorType,      //!< uninitialized
66     kAlpha_8_SkColorType,      //!< pixel with alpha in 8-bit byte
67     kRGB_565_SkColorType,      //!< pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
68     kARGB_4444_SkColorType,    //!< pixel with 4 bits for alpha, red, green, blue; in 16-bit word
69     kRGBA_8888_SkColorType,    //!< pixel with 8 bits for red, green, blue, alpha; in 32-bit word
70     kRGB_888x_SkColorType,     //!< pixel with 8 bits each for red, green, blue; in 32-bit word
71     kBGRA_8888_SkColorType,    //!< pixel with 8 bits for blue, green, red, alpha; in 32-bit word
72     kRGBA_1010102_SkColorType, //!< 10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
73     kBGRA_1010102_SkColorType, //!< 10 bits for blue, green, red; 2 bits for alpha; in 32-bit word
74     kRGB_101010x_SkColorType,  //!< pixel with 10 bits each for red, green, blue; in 32-bit word
75     kBGR_101010x_SkColorType,  //!< pixel with 10 bits each for blue, green, red; in 32-bit word
76     kGray_8_SkColorType,       //!< pixel with grayscale level in 8-bit byte
77     kRGBA_F16Norm_SkColorType, //!< pixel with half floats in [0,1] for red, green, blue, alpha;
78                                //   in 64-bit word
79     kRGBA_F16_SkColorType,     //!< pixel with half floats for red, green, blue, alpha;
80                                //   in 64-bit word
81     kRGBA_F32_SkColorType,     //!< pixel using C float for red, green, blue, alpha; in 128-bit word
82 
83     // The following 6 colortypes are just for reading from - not for rendering to
84     kR8G8_unorm_SkColorType,         //!< pixel with a uint8_t for red and green
85 
86     kA16_float_SkColorType,          //!< pixel with a half float for alpha
87     kR16G16_float_SkColorType,       //!< pixel with a half float for red and green
88 
89     kA16_unorm_SkColorType,          //!< pixel with a little endian uint16_t for alpha
90     kR16G16_unorm_SkColorType,       //!< pixel with a little endian uint16_t for red and green
91     kR16G16B16A16_unorm_SkColorType, //!< pixel with a little endian uint16_t for red, green, blue
92                                      //   and alpha
93 
94     kSRGBA_8888_SkColorType,
95     kR8_unorm_SkColorType,
96 
97     kLastEnum_SkColorType     = kR8_unorm_SkColorType, //!< last valid value
98 
99 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
100     kN32_SkColorType          = kBGRA_8888_SkColorType,//!< native 32-bit BGRA encoding
101 
102 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
103     kN32_SkColorType          = kRGBA_8888_SkColorType,//!< native 32-bit RGBA encoding
104 
105 #else
106     #error "SK_*32_SHIFT values must correspond to BGRA or RGBA byte order"
107 #endif
108 };
109 
110 /** Returns the number of bytes required to store a pixel, including unused padding.
111     Returns zero if ct is kUnknown_SkColorType or invalid.
112 
113     @return    bytes per pixel
114 */
115 SK_API int SkColorTypeBytesPerPixel(SkColorType ct);
116 
117 /** Returns true if SkColorType always decodes alpha to 1.0, making the pixel
118     fully opaque. If true, SkColorType does not reserve bits to encode alpha.
119 
120     @return    true if alpha is always set to 1.0
121 */
122 SK_API bool SkColorTypeIsAlwaysOpaque(SkColorType ct);
123 
124 /** Returns true if canonical can be set to a valid SkAlphaType for colorType. If
125     there is more than one valid canonical SkAlphaType, set to alphaType, if valid.
126     If true is returned and canonical is not nullptr, store valid SkAlphaType.
127 
128     Returns false only if alphaType is kUnknown_SkAlphaType, color type is not
129     kUnknown_SkColorType, and SkColorType is not always opaque. If false is returned,
130     canonical is ignored.
131 
132     @param canonical  storage for SkAlphaType
133     @return           true if valid SkAlphaType can be associated with colorType
134 */
135 SK_API bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
136                                          SkAlphaType* canonical = nullptr);
137 
138 /** \enum SkImageInfo::SkYUVColorSpace
139     Describes color range of YUV pixels. The color mapping from YUV to RGB varies
140     depending on the source. YUV pixels may be generated by JPEG images, standard
141     video streams, or high definition video streams. Each has its own mapping from
142     YUV to RGB.
143 
144     JPEG YUV values encode the full range of 0 to 255 for all three components.
145     Video YUV values often range from 16 to 235 for Y and from 16 to 240 for U and V (limited).
146     Details of encoding and conversion to RGB are described in YCbCr color space.
147 
148     The identity colorspace exists to provide a utility mapping from Y to R, U to G and V to B.
149     It can be used to visualize the YUV planes or to explicitly post process the YUV channels.
150 */
151 enum SkYUVColorSpace : int {
152     kJPEG_Full_SkYUVColorSpace,                 //!< describes full range
153     kRec601_Limited_SkYUVColorSpace,            //!< describes SDTV range
154     kRec709_Full_SkYUVColorSpace,               //!< describes HDTV range
155     kRec709_Limited_SkYUVColorSpace,
156     kBT2020_8bit_Full_SkYUVColorSpace,          //!< describes UHDTV range, non-constant-luminance
157     kBT2020_8bit_Limited_SkYUVColorSpace,
158     kBT2020_10bit_Full_SkYUVColorSpace,
159     kBT2020_10bit_Limited_SkYUVColorSpace,
160     kBT2020_12bit_Full_SkYUVColorSpace,
161     kBT2020_12bit_Limited_SkYUVColorSpace,
162     kIdentity_SkYUVColorSpace,                  //!< maps Y->R, U->G, V->B
163 
164     kLastEnum_SkYUVColorSpace = kIdentity_SkYUVColorSpace, //!< last valid value
165 
166     // Legacy (deprecated) names:
167     kJPEG_SkYUVColorSpace = kJPEG_Full_SkYUVColorSpace,
168     kRec601_SkYUVColorSpace = kRec601_Limited_SkYUVColorSpace,
169     kRec709_SkYUVColorSpace = kRec709_Limited_SkYUVColorSpace,
170     kBT2020_SkYUVColorSpace = kBT2020_8bit_Limited_SkYUVColorSpace,
171 };
172 
173 /** \struct SkColorInfo
174     Describes pixel and encoding. SkImageInfo can be created from SkColorInfo by
175     providing dimensions.
176 
177     It encodes how pixel bits describe alpha, transparency; color components red, blue,
178     and green; and SkColorSpace, the range and linearity of colors.
179 */
180 class SK_API SkColorInfo {
181 public:
182     /** Creates an SkColorInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
183         and no SkColorSpace.
184 
185         @return  empty SkImageInfo
186     */
187     SkColorInfo() = default;
188 
189     /** Creates SkColorInfo from SkColorType ct, SkAlphaType at, and optionally SkColorSpace cs.
190 
191         If SkColorSpace cs is nullptr and SkColorInfo is part of drawing source: SkColorSpace
192         defaults to sRGB, mapping into SkSurface SkColorSpace.
193 
194         Parameters are not validated to see if their values are legal, or that the
195         combination is supported.
196         @return        created SkColorInfo
197     */
SkColorInfo(SkColorType ct,SkAlphaType at,sk_sp<SkColorSpace> cs)198     SkColorInfo(SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs)
199             : fColorSpace(std::move(cs)), fColorType(ct), fAlphaType(at) {}
200 
201     SkColorInfo(const SkColorInfo&) = default;
202     SkColorInfo(SkColorInfo&&) = default;
203 
204     SkColorInfo& operator=(const SkColorInfo&) = default;
205     SkColorInfo& operator=(SkColorInfo&&) = default;
206 
colorSpace()207     SkColorSpace* colorSpace() const { return fColorSpace.get(); }
refColorSpace()208     sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
colorType()209     SkColorType colorType() const { return fColorType; }
alphaType()210     SkAlphaType alphaType() const { return fAlphaType; }
211 
isOpaque()212     bool isOpaque() const {
213         return SkAlphaTypeIsOpaque(fAlphaType)
214             || SkColorTypeIsAlwaysOpaque(fColorType);
215     }
216 
gammaCloseToSRGB()217     bool gammaCloseToSRGB() const { return fColorSpace && fColorSpace->gammaCloseToSRGB(); }
218 
219     /** Does other represent the same color type, alpha type, and color space? */
220     bool operator==(const SkColorInfo& other) const {
221         return fColorType == other.fColorType && fAlphaType == other.fAlphaType &&
222                SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get());
223     }
224 
225     /** Does other represent a different color type, alpha type, or color space? */
226     bool operator!=(const SkColorInfo& other) const { return !(*this == other); }
227 
228     /** Creates SkColorInfo with same SkColorType, SkColorSpace, with SkAlphaType set
229         to newAlphaType.
230 
231         Created SkColorInfo contains newAlphaType even if it is incompatible with
232         SkColorType, in which case SkAlphaType in SkColorInfo is ignored.
233     */
makeAlphaType(SkAlphaType newAlphaType)234     SkColorInfo makeAlphaType(SkAlphaType newAlphaType) const {
235         return SkColorInfo(this->colorType(), newAlphaType, this->refColorSpace());
236     }
237 
238     /** Creates new SkColorInfo with same SkAlphaType, SkColorSpace, with SkColorType
239         set to newColorType.
240     */
makeColorType(SkColorType newColorType)241     SkColorInfo makeColorType(SkColorType newColorType) const {
242         return SkColorInfo(newColorType, this->alphaType(), this->refColorSpace());
243     }
244 
245     /** Creates SkColorInfo with same SkAlphaType, SkColorType, with SkColorSpace
246         set to cs. cs may be nullptr.
247     */
makeColorSpace(sk_sp<SkColorSpace> cs)248     SkColorInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
249         return SkColorInfo(this->colorType(), this->alphaType(), std::move(cs));
250     }
251 
252     /** Returns number of bytes per pixel required by SkColorType.
253         Returns zero if colorType() is kUnknown_SkColorType.
254 
255         @return  bytes in pixel
256 
257         example: https://fiddle.skia.org/c/@ImageInfo_bytesPerPixel
258     */
259     int bytesPerPixel() const;
260 
261     /** Returns bit shift converting row bytes to row pixels.
262         Returns zero for kUnknown_SkColorType.
263 
264         @return  one of: 0, 1, 2, 3, 4; left shift to convert pixels to bytes
265 
266         example: https://fiddle.skia.org/c/@ImageInfo_shiftPerPixel
267     */
268     int shiftPerPixel() const;
269 
270 private:
271     sk_sp<SkColorSpace> fColorSpace;
272     SkColorType fColorType = kUnknown_SkColorType;
273     SkAlphaType fAlphaType = kUnknown_SkAlphaType;
274 };
275 
276 /** \struct SkImageInfo
277     Describes pixel dimensions and encoding. SkBitmap, SkImage, PixMap, and SkSurface
278     can be created from SkImageInfo. SkImageInfo can be retrieved from SkBitmap and
279     SkPixmap, but not from SkImage and SkSurface. For example, SkImage and SkSurface
280     implementations may defer pixel depth, so may not completely specify SkImageInfo.
281 
282     SkImageInfo contains dimensions, the pixel integral width and height. It encodes
283     how pixel bits describe alpha, transparency; color components red, blue,
284     and green; and SkColorSpace, the range and linearity of colors.
285 */
286 struct SK_API SkImageInfo {
287 public:
288 
289     /** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
290         a width and height of zero, and no SkColorSpace.
291 
292         @return  empty SkImageInfo
293     */
294     SkImageInfo() = default;
295 
296     /** Creates SkImageInfo from integral dimensions width and height, SkColorType ct,
297         SkAlphaType at, and optionally SkColorSpace cs.
298 
299         If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
300         defaults to sRGB, mapping into SkSurface SkColorSpace.
301 
302         Parameters are not validated to see if their values are legal, or that the
303         combination is supported.
304 
305         @param width   pixel column count; must be zero or greater
306         @param height  pixel row count; must be zero or greater
307         @param cs      range of colors; may be nullptr
308         @return        created SkImageInfo
309     */
310     static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
311                             sk_sp<SkColorSpace> cs = nullptr) {
312         return SkImageInfo({width, height}, {ct, at, std::move(cs)});
313     }
314     static SkImageInfo Make(SkISize dimensions, SkColorType ct, SkAlphaType at,
315                             sk_sp<SkColorSpace> cs = nullptr) {
316         return SkImageInfo(dimensions, {ct, at, std::move(cs)});
317     }
318 
319     /** Creates SkImageInfo from integral dimensions and SkColorInfo colorInfo,
320 
321         Parameters are not validated to see if their values are legal, or that the
322         combination is supported.
323 
324         @param dimensions   pixel column and row count; must be zeros or greater
325         @param SkColorInfo  the pixel encoding consisting of SkColorType, SkAlphaType, and
326                             SkColorSpace (which may be nullptr)
327         @return        created SkImageInfo
328     */
MakeSkImageInfo329     static SkImageInfo Make(SkISize dimensions, const SkColorInfo& colorInfo) {
330         return SkImageInfo(dimensions, colorInfo);
331     }
MakeSkImageInfo332     static SkImageInfo Make(SkISize dimensions, SkColorInfo&& colorInfo) {
333         return SkImageInfo(dimensions, std::move(colorInfo));
334     }
335 
336     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
337         SkAlphaType at, and optionally SkColorSpace cs. kN32_SkColorType will equal either
338         kBGRA_8888_SkColorType or kRGBA_8888_SkColorType, whichever is optimal.
339 
340         If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
341         defaults to sRGB, mapping into SkSurface SkColorSpace.
342 
343         Parameters are not validated to see if their values are legal, or that the
344         combination is supported.
345 
346         @param width   pixel column count; must be zero or greater
347         @param height  pixel row count; must be zero or greater
348         @param cs      range of colors; may be nullptr
349         @return        created SkImageInfo
350     */
351     static SkImageInfo MakeN32(int width, int height, SkAlphaType at,
352                                sk_sp<SkColorSpace> cs = nullptr) {
353         return Make({width, height}, kN32_SkColorType, at, std::move(cs));
354     }
355 
356     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
357         SkAlphaType at, with sRGB SkColorSpace.
358 
359         Parameters are not validated to see if their values are legal, or that the
360         combination is supported.
361 
362         @param width   pixel column count; must be zero or greater
363         @param height  pixel row count; must be zero or greater
364         @return        created SkImageInfo
365 
366         example: https://fiddle.skia.org/c/@ImageInfo_MakeS32
367     */
368     static SkImageInfo MakeS32(int width, int height, SkAlphaType at);
369 
370     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
371         kPremul_SkAlphaType, with optional SkColorSpace.
372 
373         If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
374         defaults to sRGB, mapping into SkSurface SkColorSpace.
375 
376         Parameters are not validated to see if their values are legal, or that the
377         combination is supported.
378 
379         @param width   pixel column count; must be zero or greater
380         @param height  pixel row count; must be zero or greater
381         @param cs      range of colors; may be nullptr
382         @return        created SkImageInfo
383     */
384     static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs = nullptr) {
385         return Make({width, height}, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs));
386     }
387 
388     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
389         kPremul_SkAlphaType, with SkColorSpace set to nullptr.
390 
391         If SkImageInfo is part of drawing source: SkColorSpace defaults to sRGB, mapping
392         into SkSurface SkColorSpace.
393 
394         Parameters are not validated to see if their values are legal, or that the
395         combination is supported.
396 
397         @param dimensions  width and height, each must be zero or greater
398         @param cs          range of colors; may be nullptr
399         @return            created SkImageInfo
400     */
401     static SkImageInfo MakeN32Premul(SkISize dimensions, sk_sp<SkColorSpace> cs = nullptr) {
402         return Make(dimensions, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs));
403     }
404 
405     /** Creates SkImageInfo from integral dimensions width and height, kAlpha_8_SkColorType,
406         kPremul_SkAlphaType, with SkColorSpace set to nullptr.
407 
408         @param width   pixel column count; must be zero or greater
409         @param height  pixel row count; must be zero or greater
410         @return        created SkImageInfo
411     */
MakeA8SkImageInfo412     static SkImageInfo MakeA8(int width, int height) {
413         return Make({width, height}, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
414     }
415     /** Creates SkImageInfo from integral dimensions, kAlpha_8_SkColorType,
416         kPremul_SkAlphaType, with SkColorSpace set to nullptr.
417 
418         @param dimensions   pixel row and column count; must be zero or greater
419         @return             created SkImageInfo
420     */
MakeA8SkImageInfo421     static SkImageInfo MakeA8(SkISize dimensions) {
422         return Make(dimensions, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
423     }
424 
425     /** Creates SkImageInfo from integral dimensions width and height, kUnknown_SkColorType,
426         kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
427 
428         Returned SkImageInfo as part of source does not draw, and as part of destination
429         can not be drawn to.
430 
431         @param width   pixel column count; must be zero or greater
432         @param height  pixel row count; must be zero or greater
433         @return        created SkImageInfo
434     */
MakeUnknownSkImageInfo435     static SkImageInfo MakeUnknown(int width, int height) {
436         return Make({width, height}, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr);
437     }
438 
439     /** Creates SkImageInfo from integral dimensions width and height set to zero,
440         kUnknown_SkColorType, kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
441 
442         Returned SkImageInfo as part of source does not draw, and as part of destination
443         can not be drawn to.
444 
445         @return  created SkImageInfo
446     */
MakeUnknownSkImageInfo447     static SkImageInfo MakeUnknown() {
448         return MakeUnknown(0, 0);
449     }
450 
451     /** Returns pixel count in each row.
452 
453         @return  pixel width
454     */
widthSkImageInfo455     int width() const { return fDimensions.width(); }
456 
457     /** Returns pixel row count.
458 
459         @return  pixel height
460     */
heightSkImageInfo461     int height() const { return fDimensions.height(); }
462 
colorTypeSkImageInfo463     SkColorType colorType() const { return fColorInfo.colorType(); }
464 
alphaTypeSkImageInfo465     SkAlphaType alphaType() const { return fColorInfo.alphaType(); }
466 
467     /** Returns SkColorSpace, the range of colors. The reference count of
468         SkColorSpace is unchanged. The returned SkColorSpace is immutable.
469 
470         @return  SkColorSpace, or nullptr
471     */
colorSpaceSkImageInfo472     SkColorSpace* colorSpace() const { return fColorInfo.colorSpace(); }
473 
474     /** Returns smart pointer to SkColorSpace, the range of colors. The smart pointer
475         tracks the number of objects sharing this SkColorSpace reference so the memory
476         is released when the owners destruct.
477 
478         The returned SkColorSpace is immutable.
479 
480         @return  SkColorSpace wrapped in a smart pointer
481     */
refColorSpaceSkImageInfo482     sk_sp<SkColorSpace> refColorSpace() const { return fColorInfo.refColorSpace(); }
483 
484     /** Returns if SkImageInfo describes an empty area of pixels by checking if either
485         width or height is zero or smaller.
486 
487         @return  true if either dimension is zero or smaller
488     */
isEmptySkImageInfo489     bool isEmpty() const { return fDimensions.isEmpty(); }
490 
491     /** Returns the dimensionless SkColorInfo that represents the same color type,
492         alpha type, and color space as this SkImageInfo.
493      */
colorInfoSkImageInfo494     const SkColorInfo& colorInfo() const { return fColorInfo; }
495 
496     /** Returns true if SkAlphaType is set to hint that all pixels are opaque; their
497         alpha value is implicitly or explicitly 1.0. If true, and all pixels are
498         not opaque, Skia may draw incorrectly.
499 
500         Does not check if SkColorType allows alpha, or if any pixel value has
501         transparency.
502 
503         @return  true if SkAlphaType is kOpaque_SkAlphaType
504     */
isOpaqueSkImageInfo505     bool isOpaque() const { return fColorInfo.isOpaque(); }
506 
507     /** Returns SkISize { width(), height() }.
508 
509         @return  integral size of width() and height()
510     */
dimensionsSkImageInfo511     SkISize dimensions() const { return fDimensions; }
512 
513     /** Returns SkIRect { 0, 0, width(), height() }.
514 
515         @return  integral rectangle from origin to width() and height()
516     */
boundsSkImageInfo517     SkIRect bounds() const { return SkIRect::MakeSize(fDimensions); }
518 
519     /** Returns true if associated SkColorSpace is not nullptr, and SkColorSpace gamma
520         is approximately the same as sRGB.
521         This includes the
522 
523         @return  true if SkColorSpace gamma is approximately the same as sRGB
524     */
gammaCloseToSRGBSkImageInfo525     bool gammaCloseToSRGB() const { return fColorInfo.gammaCloseToSRGB(); }
526 
527     /** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
528         with dimensions set to width and height.
529 
530         @param newWidth   pixel column count; must be zero or greater
531         @param newHeight  pixel row count; must be zero or greater
532         @return           created SkImageInfo
533     */
makeWHSkImageInfo534     SkImageInfo makeWH(int newWidth, int newHeight) const {
535         return Make({newWidth, newHeight}, fColorInfo);
536     }
537 
538     /** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
539         with dimensions set to newDimensions.
540 
541         @param newSize   pixel column and row count; must be zero or greater
542         @return          created SkImageInfo
543     */
makeDimensionsSkImageInfo544     SkImageInfo makeDimensions(SkISize newSize) const {
545         return Make(newSize, fColorInfo);
546     }
547 
548     /** Creates SkImageInfo with same SkColorType, SkColorSpace, width, and height,
549         with SkAlphaType set to newAlphaType.
550 
551         Created SkImageInfo contains newAlphaType even if it is incompatible with
552         SkColorType, in which case SkAlphaType in SkImageInfo is ignored.
553 
554         @return              created SkImageInfo
555     */
makeAlphaTypeSkImageInfo556     SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
557         return Make(fDimensions, fColorInfo.makeAlphaType(newAlphaType));
558     }
559 
560     /** Creates SkImageInfo with same SkAlphaType, SkColorSpace, width, and height,
561         with SkColorType set to newColorType.
562 
563         @return              created SkImageInfo
564     */
makeColorTypeSkImageInfo565     SkImageInfo makeColorType(SkColorType newColorType) const {
566         return Make(fDimensions, fColorInfo.makeColorType(newColorType));
567     }
568 
569     /** Creates SkImageInfo with same SkAlphaType, SkColorType, width, and height,
570         with SkColorSpace set to cs.
571 
572         @param cs  range of colors; may be nullptr
573         @return    created SkImageInfo
574     */
makeColorSpaceSkImageInfo575     SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
576         return Make(fDimensions, fColorInfo.makeColorSpace(std::move(cs)));
577     }
578 
579     /** Returns number of bytes per pixel required by SkColorType.
580         Returns zero if colorType( is kUnknown_SkColorType.
581 
582         @return  bytes in pixel
583     */
bytesPerPixelSkImageInfo584     int bytesPerPixel() const { return fColorInfo.bytesPerPixel(); }
585 
586     /** Returns bit shift converting row bytes to row pixels.
587         Returns zero for kUnknown_SkColorType.
588 
589         @return  one of: 0, 1, 2, 3; left shift to convert pixels to bytes
590     */
shiftPerPixelSkImageInfo591     int shiftPerPixel() const { return fColorInfo.shiftPerPixel(); }
592 
593     /** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
594         specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
595         in 31 bits.
596 
597         @return  width() times bytesPerPixel() as unsigned 64-bit integer
598     */
minRowBytes64SkImageInfo599     uint64_t minRowBytes64() const {
600         return (uint64_t)sk_64_mul(this->width(), this->bytesPerPixel());
601     }
602 
603     /** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
604         specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
605         in 31 bits.
606 
607         @return  width() times bytesPerPixel() as size_t
608     */
minRowBytesSkImageInfo609     size_t minRowBytes() const {
610         uint64_t minRowBytes = this->minRowBytes64();
611         if (!SkTFitsIn<int32_t>(minRowBytes)) {
612             return 0;
613         }
614         return (size_t)minRowBytes;
615     }
616 
617     /** Returns byte offset of pixel from pixel base address.
618 
619         Asserts in debug build if x or y is outside of bounds. Does not assert if
620         rowBytes is smaller than minRowBytes(), even though result may be incorrect.
621 
622         @param x         column index, zero or greater, and less than width()
623         @param y         row index, zero or greater, and less than height()
624         @param rowBytes  size of pixel row or larger
625         @return          offset within pixel array
626 
627         example: https://fiddle.skia.org/c/@ImageInfo_computeOffset
628     */
629     size_t computeOffset(int x, int y, size_t rowBytes) const;
630 
631     /** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
632         SkAlphaType, and SkColorSpace are equivalent.
633 
634         @param other  SkImageInfo to compare
635         @return       true if SkImageInfo equals other
636     */
637     bool operator==(const SkImageInfo& other) const {
638         return fDimensions == other.fDimensions && fColorInfo == other.fColorInfo;
639     }
640 
641     /** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
642         SkAlphaType, and SkColorSpace are not equivalent.
643 
644         @param other  SkImageInfo to compare
645         @return       true if SkImageInfo is not equal to other
646     */
647     bool operator!=(const SkImageInfo& other) const {
648         return !(*this == other);
649     }
650 
651     /** Returns storage required by pixel array, given SkImageInfo dimensions, SkColorType,
652         and rowBytes. rowBytes is assumed to be at least as large as minRowBytes().
653 
654         Returns zero if height is zero.
655         Returns SIZE_MAX if answer exceeds the range of size_t.
656 
657         @param rowBytes  size of pixel row or larger
658         @return          memory required by pixel buffer
659 
660         example: https://fiddle.skia.org/c/@ImageInfo_computeByteSize
661     */
662     size_t computeByteSize(size_t rowBytes) const;
663 
664     /** Returns storage required by pixel array, given SkImageInfo dimensions, and
665         SkColorType. Uses minRowBytes() to compute bytes for pixel row.
666 
667         Returns zero if height is zero.
668         Returns SIZE_MAX if answer exceeds the range of size_t.
669 
670         @return  least memory required by pixel buffer
671     */
computeMinByteSizeSkImageInfo672     size_t computeMinByteSize() const {
673         return this->computeByteSize(this->minRowBytes());
674     }
675 
676     /** Returns true if byteSize equals SIZE_MAX. computeByteSize() and
677         computeMinByteSize() return SIZE_MAX if size_t can not hold buffer size.
678 
679         @param byteSize  result of computeByteSize() or computeMinByteSize()
680         @return          true if computeByteSize() or computeMinByteSize() result exceeds size_t
681     */
ByteSizeOverflowedSkImageInfo682     static bool ByteSizeOverflowed(size_t byteSize) {
683         return SIZE_MAX == byteSize;
684     }
685 
686     /** Returns true if rowBytes is valid for this SkImageInfo.
687 
688         @param rowBytes  size of pixel row including padding
689         @return          true if rowBytes is large enough to contain pixel row and is properly
690                          aligned
691     */
validRowBytesSkImageInfo692     bool validRowBytes(size_t rowBytes) const {
693         if (rowBytes < this->minRowBytes64()) {
694             return false;
695         }
696         int shift = this->shiftPerPixel();
697         size_t alignedRowBytes = rowBytes >> shift << shift;
698         return alignedRowBytes == rowBytes;
699     }
700 
701     /** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
702         a width and height of zero, and no SkColorSpace.
703     */
resetSkImageInfo704     void reset() { *this = {}; }
705 
706     /** Asserts if internal values are illegal or inconsistent. Only available if
707         SK_DEBUG is defined at compile time.
708     */
709     SkDEBUGCODE(void validate() const;)
710 
711 private:
712     SkColorInfo fColorInfo;
713     SkISize fDimensions = {0, 0};
714 
SkImageInfoSkImageInfo715     SkImageInfo(SkISize dimensions, const SkColorInfo& colorInfo)
716             : fColorInfo(colorInfo), fDimensions(dimensions) {}
717 
SkImageInfoSkImageInfo718     SkImageInfo(SkISize dimensions, SkColorInfo&& colorInfo)
719             : fColorInfo(std::move(colorInfo)), fDimensions(dimensions) {}
720 };
721 
722 #endif
723