• 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 
96     kLastEnum_SkColorType     = kSRGBA_8888_SkColorType, //!< last valid value
97 
98 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
99     kN32_SkColorType          = kBGRA_8888_SkColorType,//!< native 32-bit BGRA encoding
100 
101 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
102     kN32_SkColorType          = kRGBA_8888_SkColorType,//!< native 32-bit RGBA encoding
103 
104 #else
105     #error "SK_*32_SHIFT values must correspond to BGRA or RGBA byte order"
106 #endif
107 };
108 
109 /** Returns the number of bytes required to store a pixel, including unused padding.
110     Returns zero if ct is kUnknown_SkColorType or invalid.
111 
112     @return    bytes per pixel
113 */
114 SK_API int SkColorTypeBytesPerPixel(SkColorType ct);
115 
116 /** Returns true if SkColorType always decodes alpha to 1.0, making the pixel
117     fully opaque. If true, SkColorType does not reserve bits to encode alpha.
118 
119     @return    true if alpha is always set to 1.0
120 */
121 SK_API bool SkColorTypeIsAlwaysOpaque(SkColorType ct);
122 
123 /** Returns true if canonical can be set to a valid SkAlphaType for colorType. If
124     there is more than one valid canonical SkAlphaType, set to alphaType, if valid.
125     If true is returned and canonical is not nullptr, store valid SkAlphaType.
126 
127     Returns false only if alphaType is kUnknown_SkAlphaType, color type is not
128     kUnknown_SkColorType, and SkColorType is not always opaque. If false is returned,
129     canonical is ignored.
130 
131     @param canonical  storage for SkAlphaType
132     @return           true if valid SkAlphaType can be associated with colorType
133 */
134 SK_API bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
135                                          SkAlphaType* canonical = nullptr);
136 
137 /** \enum SkImageInfo::SkYUVColorSpace
138     Describes color range of YUV pixels. The color mapping from YUV to RGB varies
139     depending on the source. YUV pixels may be generated by JPEG images, standard
140     video streams, or high definition video streams. Each has its own mapping from
141     YUV to RGB.
142 
143     JPEG YUV values encode the full range of 0 to 255 for all three components.
144     Video YUV values often range from 16 to 235 for Y and from 16 to 240 for U and V (limited).
145     Details of encoding and conversion to RGB are described in YCbCr color space.
146 
147     The identity colorspace exists to provide a utility mapping from Y to R, U to G and V to B.
148     It can be used to visualize the YUV planes or to explicitly post process the YUV channels.
149 */
150 enum SkYUVColorSpace : int {
151     kJPEG_Full_SkYUVColorSpace,                 //!< describes full range
152     kRec601_Limited_SkYUVColorSpace,            //!< describes SDTV range
153     kRec709_Full_SkYUVColorSpace,               //!< describes HDTV range
154     kRec709_Limited_SkYUVColorSpace,
155     kBT2020_8bit_Full_SkYUVColorSpace,          //!< describes UHDTV range, non-constant-luminance
156     kBT2020_8bit_Limited_SkYUVColorSpace,
157     kBT2020_10bit_Full_SkYUVColorSpace,
158     kBT2020_10bit_Limited_SkYUVColorSpace,
159     kBT2020_12bit_Full_SkYUVColorSpace,
160     kBT2020_12bit_Limited_SkYUVColorSpace,
161     kIdentity_SkYUVColorSpace,                  //!< maps Y->R, U->G, V->B
162 
163     kLastEnum_SkYUVColorSpace = kIdentity_SkYUVColorSpace, //!< last valid value
164 
165     // Legacy (deprecated) names:
166     kJPEG_SkYUVColorSpace = kJPEG_Full_SkYUVColorSpace,
167     kRec601_SkYUVColorSpace = kRec601_Limited_SkYUVColorSpace,
168     kRec709_SkYUVColorSpace = kRec709_Limited_SkYUVColorSpace,
169     kBT2020_SkYUVColorSpace = kBT2020_8bit_Limited_SkYUVColorSpace,
170 };
171 
172 /** \struct SkColorInfo
173     Describes pixel and encoding. SkImageInfo can be created from SkColorInfo by
174     providing dimensions.
175 
176     It encodes how pixel bits describe alpha, transparency; color components red, blue,
177     and green; and SkColorSpace, the range and linearity of colors.
178 */
179 class SK_API SkColorInfo {
180 public:
181     /** Creates an SkColorInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
182         and no SkColorSpace.
183 
184         @return  empty SkImageInfo
185     */
186     SkColorInfo() = default;
187 
188     /** Creates SkColorInfo from SkColorType ct, SkAlphaType at, and optionally SkColorSpace cs.
189 
190         If SkColorSpace cs is nullptr and SkColorInfo is part of drawing source: SkColorSpace
191         defaults to sRGB, mapping into SkSurface SkColorSpace.
192 
193         Parameters are not validated to see if their values are legal, or that the
194         combination is supported.
195         @return        created SkColorInfo
196     */
SkColorInfo(SkColorType ct,SkAlphaType at,sk_sp<SkColorSpace> cs)197     SkColorInfo(SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs)
198             : fColorSpace(std::move(cs)), fColorType(ct), fAlphaType(at) {}
199 
200     SkColorInfo(const SkColorInfo&) = default;
201     SkColorInfo(SkColorInfo&&) = default;
202 
203     SkColorInfo& operator=(const SkColorInfo&) = default;
204     SkColorInfo& operator=(SkColorInfo&&) = default;
205 
colorSpace()206     SkColorSpace* colorSpace() const { return fColorSpace.get(); }
refColorSpace()207     sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
colorType()208     SkColorType colorType() const { return fColorType; }
alphaType()209     SkAlphaType alphaType() const { return fAlphaType; }
210 
isOpaque()211     bool isOpaque() const {
212         return SkAlphaTypeIsOpaque(fAlphaType)
213             || SkColorTypeIsAlwaysOpaque(fColorType);
214     }
215 
gammaCloseToSRGB()216     bool gammaCloseToSRGB() const { return fColorSpace && fColorSpace->gammaCloseToSRGB(); }
217 
218     /** Does other represent the same color type, alpha type, and color space? */
219     bool operator==(const SkColorInfo& other) const {
220         return fColorType == other.fColorType && fAlphaType == other.fAlphaType &&
221                SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get());
222     }
223 
224     /** Does other represent a different color type, alpha type, or color space? */
225     bool operator!=(const SkColorInfo& other) const { return !(*this == other); }
226 
227     /** Creates SkColorInfo with same SkColorType, SkColorSpace, with SkAlphaType set
228         to newAlphaType.
229 
230         Created SkColorInfo contains newAlphaType even if it is incompatible with
231         SkColorType, in which case SkAlphaType in SkColorInfo is ignored.
232     */
makeAlphaType(SkAlphaType newAlphaType)233     SkColorInfo makeAlphaType(SkAlphaType newAlphaType) const {
234         return SkColorInfo(this->colorType(), newAlphaType, this->refColorSpace());
235     }
236 
237     /** Creates new SkColorInfo with same SkAlphaType, SkColorSpace, with SkColorType
238         set to newColorType.
239     */
makeColorType(SkColorType newColorType)240     SkColorInfo makeColorType(SkColorType newColorType) const {
241         return SkColorInfo(newColorType, this->alphaType(), this->refColorSpace());
242     }
243 
244     /** Creates SkColorInfo with same SkAlphaType, SkColorType, with SkColorSpace
245         set to cs. cs may be nullptr.
246     */
makeColorSpace(sk_sp<SkColorSpace> cs)247     SkColorInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
248         return SkColorInfo(this->colorType(), this->alphaType(), std::move(cs));
249     }
250 
251     /** Returns number of bytes per pixel required by SkColorType.
252         Returns zero if colorType() is kUnknown_SkColorType.
253 
254         @return  bytes in pixel
255 
256         example: https://fiddle.skia.org/c/@ImageInfo_bytesPerPixel
257     */
258     int bytesPerPixel() const;
259 
260     /** Returns bit shift converting row bytes to row pixels.
261         Returns zero for kUnknown_SkColorType.
262 
263         @return  one of: 0, 1, 2, 3, 4; left shift to convert pixels to bytes
264 
265         example: https://fiddle.skia.org/c/@ImageInfo_shiftPerPixel
266     */
267     int shiftPerPixel() const;
268 
269 private:
270     sk_sp<SkColorSpace> fColorSpace;
271     SkColorType fColorType = kUnknown_SkColorType;
272     SkAlphaType fAlphaType = kUnknown_SkAlphaType;
273 };
274 
275 /** \struct SkImageInfo
276     Describes pixel dimensions and encoding. SkBitmap, SkImage, PixMap, and SkSurface
277     can be created from SkImageInfo. SkImageInfo can be retrieved from SkBitmap and
278     SkPixmap, but not from SkImage and SkSurface. For example, SkImage and SkSurface
279     implementations may defer pixel depth, so may not completely specify SkImageInfo.
280 
281     SkImageInfo contains dimensions, the pixel integral width and height. It encodes
282     how pixel bits describe alpha, transparency; color components red, blue,
283     and green; and SkColorSpace, the range and linearity of colors.
284 */
285 struct SK_API SkImageInfo {
286 public:
287 
288     /** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
289         a width and height of zero, and no SkColorSpace.
290 
291         @return  empty SkImageInfo
292     */
293     SkImageInfo() = default;
294 
295     /** Creates SkImageInfo from integral dimensions width and height, SkColorType ct,
296         SkAlphaType at, and optionally SkColorSpace cs.
297 
298         If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
299         defaults to sRGB, mapping into SkSurface SkColorSpace.
300 
301         Parameters are not validated to see if their values are legal, or that the
302         combination is supported.
303 
304         @param width   pixel column count; must be zero or greater
305         @param height  pixel row count; must be zero or greater
306         @param cs      range of colors; may be nullptr
307         @return        created SkImageInfo
308     */
309     static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
310                             sk_sp<SkColorSpace> cs = nullptr) {
311         return SkImageInfo({width, height}, {ct, at, std::move(cs)});
312     }
313     static SkImageInfo Make(SkISize dimensions, SkColorType ct, SkAlphaType at,
314                             sk_sp<SkColorSpace> cs = nullptr) {
315         return SkImageInfo(dimensions, {ct, at, std::move(cs)});
316     }
317 
318     /** Creates SkImageInfo from integral dimensions and SkColorInfo colorInfo,
319 
320         Parameters are not validated to see if their values are legal, or that the
321         combination is supported.
322 
323         @param dimensions   pixel column and row count; must be zeros or greater
324         @param SkColorInfo  the pixel encoding consisting of SkColorType, SkAlphaType, and
325                             SkColorSpace (which may be nullptr)
326         @return        created SkImageInfo
327     */
MakeSkImageInfo328     static SkImageInfo Make(SkISize dimensions, const SkColorInfo& colorInfo) {
329         return SkImageInfo(dimensions, colorInfo);
330     }
MakeSkImageInfo331     static SkImageInfo Make(SkISize dimensions, SkColorInfo&& colorInfo) {
332         return SkImageInfo(dimensions, std::move(colorInfo));
333     }
334 
335     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
336         SkAlphaType at, and optionally SkColorSpace cs. kN32_SkColorType will equal either
337         kBGRA_8888_SkColorType or kRGBA_8888_SkColorType, whichever is optimal.
338 
339         If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
340         defaults to sRGB, mapping into SkSurface SkColorSpace.
341 
342         Parameters are not validated to see if their values are legal, or that the
343         combination is supported.
344 
345         @param width   pixel column count; must be zero or greater
346         @param height  pixel row count; must be zero or greater
347         @param cs      range of colors; may be nullptr
348         @return        created SkImageInfo
349     */
350     static SkImageInfo MakeN32(int width, int height, SkAlphaType at,
351                                sk_sp<SkColorSpace> cs = nullptr) {
352         return Make({width, height}, kN32_SkColorType, at, std::move(cs));
353     }
354 
355     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
356         SkAlphaType at, with sRGB SkColorSpace.
357 
358         Parameters are not validated to see if their values are legal, or that the
359         combination is supported.
360 
361         @param width   pixel column count; must be zero or greater
362         @param height  pixel row count; must be zero or greater
363         @return        created SkImageInfo
364 
365         example: https://fiddle.skia.org/c/@ImageInfo_MakeS32
366     */
367     static SkImageInfo MakeS32(int width, int height, SkAlphaType at);
368 
369     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
370         kPremul_SkAlphaType, with optional SkColorSpace.
371 
372         If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
373         defaults to sRGB, mapping into SkSurface SkColorSpace.
374 
375         Parameters are not validated to see if their values are legal, or that the
376         combination is supported.
377 
378         @param width   pixel column count; must be zero or greater
379         @param height  pixel row count; must be zero or greater
380         @param cs      range of colors; may be nullptr
381         @return        created SkImageInfo
382     */
383     static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs = nullptr) {
384         return Make({width, height}, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs));
385     }
386 
387     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
388         kPremul_SkAlphaType, with SkColorSpace set to nullptr.
389 
390         If SkImageInfo is part of drawing source: SkColorSpace defaults to sRGB, mapping
391         into SkSurface SkColorSpace.
392 
393         Parameters are not validated to see if their values are legal, or that the
394         combination is supported.
395 
396         @param dimensions  width and height, each must be zero or greater
397         @param cs          range of colors; may be nullptr
398         @return            created SkImageInfo
399     */
400     static SkImageInfo MakeN32Premul(SkISize dimensions, sk_sp<SkColorSpace> cs = nullptr) {
401         return Make(dimensions, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs));
402     }
403 
404     /** Creates SkImageInfo from integral dimensions width and height, kAlpha_8_SkColorType,
405         kPremul_SkAlphaType, with SkColorSpace set to nullptr.
406 
407         @param width   pixel column count; must be zero or greater
408         @param height  pixel row count; must be zero or greater
409         @return        created SkImageInfo
410     */
MakeA8SkImageInfo411     static SkImageInfo MakeA8(int width, int height) {
412         return Make({width, height}, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
413     }
414     /** Creates SkImageInfo from integral dimensions, kAlpha_8_SkColorType,
415         kPremul_SkAlphaType, with SkColorSpace set to nullptr.
416 
417         @param dimensions   pixel row and column count; must be zero or greater
418         @return             created SkImageInfo
419     */
MakeA8SkImageInfo420     static SkImageInfo MakeA8(SkISize dimensions) {
421         return Make(dimensions, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
422     }
423 
424     /** Creates SkImageInfo from integral dimensions width and height, kUnknown_SkColorType,
425         kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
426 
427         Returned SkImageInfo as part of source does not draw, and as part of destination
428         can not be drawn to.
429 
430         @param width   pixel column count; must be zero or greater
431         @param height  pixel row count; must be zero or greater
432         @return        created SkImageInfo
433     */
MakeUnknownSkImageInfo434     static SkImageInfo MakeUnknown(int width, int height) {
435         return Make({width, height}, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr);
436     }
437 
438     /** Creates SkImageInfo from integral dimensions width and height set to zero,
439         kUnknown_SkColorType, kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
440 
441         Returned SkImageInfo as part of source does not draw, and as part of destination
442         can not be drawn to.
443 
444         @return  created SkImageInfo
445     */
MakeUnknownSkImageInfo446     static SkImageInfo MakeUnknown() {
447         return MakeUnknown(0, 0);
448     }
449 
450     /** Returns pixel count in each row.
451 
452         @return  pixel width
453     */
widthSkImageInfo454     int width() const { return fDimensions.width(); }
455 
456     /** Returns pixel row count.
457 
458         @return  pixel height
459     */
heightSkImageInfo460     int height() const { return fDimensions.height(); }
461 
colorTypeSkImageInfo462     SkColorType colorType() const { return fColorInfo.colorType(); }
463 
alphaTypeSkImageInfo464     SkAlphaType alphaType() const { return fColorInfo.alphaType(); }
465 
466     /** Returns SkColorSpace, the range of colors. The reference count of
467         SkColorSpace is unchanged. The returned SkColorSpace is immutable.
468 
469         @return  SkColorSpace, or nullptr
470     */
colorSpaceSkImageInfo471     SkColorSpace* colorSpace() const { return fColorInfo.colorSpace(); }
472 
473     /** Returns smart pointer to SkColorSpace, the range of colors. The smart pointer
474         tracks the number of objects sharing this SkColorSpace reference so the memory
475         is released when the owners destruct.
476 
477         The returned SkColorSpace is immutable.
478 
479         @return  SkColorSpace wrapped in a smart pointer
480     */
refColorSpaceSkImageInfo481     sk_sp<SkColorSpace> refColorSpace() const { return fColorInfo.refColorSpace(); }
482 
483     /** Returns if SkImageInfo describes an empty area of pixels by checking if either
484         width or height is zero or smaller.
485 
486         @return  true if either dimension is zero or smaller
487     */
isEmptySkImageInfo488     bool isEmpty() const { return fDimensions.isEmpty(); }
489 
490     /** Returns the dimensionless SkColorInfo that represents the same color type,
491         alpha type, and color space as this SkImageInfo.
492      */
colorInfoSkImageInfo493     const SkColorInfo& colorInfo() const { return fColorInfo; }
494 
495     /** Returns true if SkAlphaType is set to hint that all pixels are opaque; their
496         alpha value is implicitly or explicitly 1.0. If true, and all pixels are
497         not opaque, Skia may draw incorrectly.
498 
499         Does not check if SkColorType allows alpha, or if any pixel value has
500         transparency.
501 
502         @return  true if SkAlphaType is kOpaque_SkAlphaType
503     */
isOpaqueSkImageInfo504     bool isOpaque() const { return fColorInfo.isOpaque(); }
505 
506     /** Returns SkISize { width(), height() }.
507 
508         @return  integral size of width() and height()
509     */
dimensionsSkImageInfo510     SkISize dimensions() const { return fDimensions; }
511 
512     /** Returns SkIRect { 0, 0, width(), height() }.
513 
514         @return  integral rectangle from origin to width() and height()
515     */
boundsSkImageInfo516     SkIRect bounds() const { return SkIRect::MakeSize(fDimensions); }
517 
518     /** Returns true if associated SkColorSpace is not nullptr, and SkColorSpace gamma
519         is approximately the same as sRGB.
520         This includes the
521 
522         @return  true if SkColorSpace gamma is approximately the same as sRGB
523     */
gammaCloseToSRGBSkImageInfo524     bool gammaCloseToSRGB() const { return fColorInfo.gammaCloseToSRGB(); }
525 
526     /** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
527         with dimensions set to width and height.
528 
529         @param newWidth   pixel column count; must be zero or greater
530         @param newHeight  pixel row count; must be zero or greater
531         @return           created SkImageInfo
532     */
makeWHSkImageInfo533     SkImageInfo makeWH(int newWidth, int newHeight) const {
534         return Make({newWidth, newHeight}, fColorInfo);
535     }
536 
537     /** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
538         with dimensions set to newDimensions.
539 
540         @param newSize   pixel column and row count; must be zero or greater
541         @return          created SkImageInfo
542     */
makeDimensionsSkImageInfo543     SkImageInfo makeDimensions(SkISize newSize) const {
544         return Make(newSize, fColorInfo);
545     }
546 
547     /** Creates SkImageInfo with same SkColorType, SkColorSpace, width, and height,
548         with SkAlphaType set to newAlphaType.
549 
550         Created SkImageInfo contains newAlphaType even if it is incompatible with
551         SkColorType, in which case SkAlphaType in SkImageInfo is ignored.
552 
553         @return              created SkImageInfo
554     */
makeAlphaTypeSkImageInfo555     SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
556         return Make(fDimensions, fColorInfo.makeAlphaType(newAlphaType));
557     }
558 
559     /** Creates SkImageInfo with same SkAlphaType, SkColorSpace, width, and height,
560         with SkColorType set to newColorType.
561 
562         @return              created SkImageInfo
563     */
makeColorTypeSkImageInfo564     SkImageInfo makeColorType(SkColorType newColorType) const {
565         return Make(fDimensions, fColorInfo.makeColorType(newColorType));
566     }
567 
568     /** Creates SkImageInfo with same SkAlphaType, SkColorType, width, and height,
569         with SkColorSpace set to cs.
570 
571         @param cs  range of colors; may be nullptr
572         @return    created SkImageInfo
573     */
makeColorSpaceSkImageInfo574     SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
575         return Make(fDimensions, fColorInfo.makeColorSpace(std::move(cs)));
576     }
577 
578     /** Returns number of bytes per pixel required by SkColorType.
579         Returns zero if colorType( is kUnknown_SkColorType.
580 
581         @return  bytes in pixel
582     */
bytesPerPixelSkImageInfo583     int bytesPerPixel() const { return fColorInfo.bytesPerPixel(); }
584 
585     /** Returns bit shift converting row bytes to row pixels.
586         Returns zero for kUnknown_SkColorType.
587 
588         @return  one of: 0, 1, 2, 3; left shift to convert pixels to bytes
589     */
shiftPerPixelSkImageInfo590     int shiftPerPixel() const { return fColorInfo.shiftPerPixel(); }
591 
592     /** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
593         specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
594         in 31 bits.
595 
596         @return  width() times bytesPerPixel() as unsigned 64-bit integer
597     */
minRowBytes64SkImageInfo598     uint64_t minRowBytes64() const {
599         return (uint64_t)sk_64_mul(this->width(), this->bytesPerPixel());
600     }
601 
602     /** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
603         specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
604         in 31 bits.
605 
606         @return  width() times bytesPerPixel() as size_t
607     */
minRowBytesSkImageInfo608     size_t minRowBytes() const {
609         uint64_t minRowBytes = this->minRowBytes64();
610         if (!SkTFitsIn<int32_t>(minRowBytes)) {
611             return 0;
612         }
613         return (size_t)minRowBytes;
614     }
615 
616     /** Returns byte offset of pixel from pixel base address.
617 
618         Asserts in debug build if x or y is outside of bounds. Does not assert if
619         rowBytes is smaller than minRowBytes(), even though result may be incorrect.
620 
621         @param x         column index, zero or greater, and less than width()
622         @param y         row index, zero or greater, and less than height()
623         @param rowBytes  size of pixel row or larger
624         @return          offset within pixel array
625 
626         example: https://fiddle.skia.org/c/@ImageInfo_computeOffset
627     */
628     size_t computeOffset(int x, int y, size_t rowBytes) const;
629 
630     /** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
631         SkAlphaType, and SkColorSpace are equivalent.
632 
633         @param other  SkImageInfo to compare
634         @return       true if SkImageInfo equals other
635     */
636     bool operator==(const SkImageInfo& other) const {
637         return fDimensions == other.fDimensions && fColorInfo == other.fColorInfo;
638     }
639 
640     /** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
641         SkAlphaType, and SkColorSpace are not equivalent.
642 
643         @param other  SkImageInfo to compare
644         @return       true if SkImageInfo is not equal to other
645     */
646     bool operator!=(const SkImageInfo& other) const {
647         return !(*this == other);
648     }
649 
650     /** Returns storage required by pixel array, given SkImageInfo dimensions, SkColorType,
651         and rowBytes. rowBytes is assumed to be at least as large as minRowBytes().
652 
653         Returns zero if height is zero.
654         Returns SIZE_MAX if answer exceeds the range of size_t.
655 
656         @param rowBytes  size of pixel row or larger
657         @return          memory required by pixel buffer
658 
659         example: https://fiddle.skia.org/c/@ImageInfo_computeByteSize
660     */
661     size_t computeByteSize(size_t rowBytes) const;
662 
663     /** Returns storage required by pixel array, given SkImageInfo dimensions, and
664         SkColorType. Uses minRowBytes() to compute bytes for pixel row.
665 
666         Returns zero if height is zero.
667         Returns SIZE_MAX if answer exceeds the range of size_t.
668 
669         @return  least memory required by pixel buffer
670     */
computeMinByteSizeSkImageInfo671     size_t computeMinByteSize() const {
672         return this->computeByteSize(this->minRowBytes());
673     }
674 
675     /** Returns true if byteSize equals SIZE_MAX. computeByteSize() and
676         computeMinByteSize() return SIZE_MAX if size_t can not hold buffer size.
677 
678         @param byteSize  result of computeByteSize() or computeMinByteSize()
679         @return          true if computeByteSize() or computeMinByteSize() result exceeds size_t
680     */
ByteSizeOverflowedSkImageInfo681     static bool ByteSizeOverflowed(size_t byteSize) {
682         return SIZE_MAX == byteSize;
683     }
684 
685     /** Returns true if rowBytes is valid for this SkImageInfo.
686 
687         @param rowBytes  size of pixel row including padding
688         @return          true if rowBytes is large enough to contain pixel row and is properly
689                          aligned
690     */
validRowBytesSkImageInfo691     bool validRowBytes(size_t rowBytes) const {
692         if (rowBytes < this->minRowBytes64()) {
693             return false;
694         }
695         int shift = this->shiftPerPixel();
696         size_t alignedRowBytes = rowBytes >> shift << shift;
697         return alignedRowBytes == rowBytes;
698     }
699 
700     /** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
701         a width and height of zero, and no SkColorSpace.
702     */
resetSkImageInfo703     void reset() { *this = {}; }
704 
705     /** Asserts if internal values are illegal or inconsistent. Only available if
706         SK_DEBUG is defined at compile time.
707     */
708     SkDEBUGCODE(void validate() const;)
709 
710 private:
711     SkColorInfo fColorInfo;
712     SkISize fDimensions = {0, 0};
713 
SkImageInfoSkImageInfo714     SkImageInfo(SkISize dimensions, const SkColorInfo& colorInfo)
715             : fColorInfo(colorInfo), fDimensions(dimensions) {}
716 
SkImageInfoSkImageInfo717     SkImageInfo(SkISize dimensions, SkColorInfo&& colorInfo)
718             : fColorInfo(std::move(colorInfo)), fDimensions(dimensions) {}
719 };
720 
721 #endif
722