• 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