• 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 {
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 /** Temporary macro that allows us to add new color types without breaking Chrome compile. */
59 #define SK_EXTENDED_COLOR_TYPES
60 
61 /** \enum SkImageInfo::SkColorType
62     Describes how pixel bits encode color. A pixel may be an alpha mask, a
63     grayscale, RGB, or ARGB.
64 
65     kN32_SkColorType selects the native 32-bit ARGB format. On little endian
66     processors, pixels containing 8-bit ARGB components pack into 32-bit
67     kBGRA_8888_SkColorType. On big endian processors, pixels pack into 32-bit
68     kRGBA_8888_SkColorType.
69 */
70 enum SkColorType {
71     kUnknown_SkColorType,      //!< uninitialized
72     kAlpha_8_SkColorType,      //!< pixel with alpha in 8-bit byte
73     kRGB_565_SkColorType,      //!< pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
74     kARGB_4444_SkColorType,    //!< pixel with 4 bits for alpha, red, green, blue; in 16-bit word
75     kRGBA_8888_SkColorType,    //!< pixel with 8 bits for red, green, blue, alpha; in 32-bit word
76     kRGB_888x_SkColorType,     //!< pixel with 8 bits each for red, green, blue; in 32-bit word
77     kBGRA_8888_SkColorType,    //!< pixel with 8 bits for blue, green, red, alpha; in 32-bit word
78     kRGBA_1010102_SkColorType, //!< 10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
79     kBGRA_1010102_SkColorType, //!< 10 bits for blue, green, red; 2 bits for alpha; in 32-bit word
80     kRGB_101010x_SkColorType,  //!< pixel with 10 bits each for red, green, blue; in 32-bit word
81     kBGR_101010x_SkColorType,  //!< pixel with 10 bits each for blue, green, red; in 32-bit word
82     kGray_8_SkColorType,       //!< pixel with grayscale level in 8-bit byte
83     kRGBA_F16Norm_SkColorType, //!< pixel with half floats in [0,1] for red, green, blue, alpha; in 64-bit word
84     kRGBA_F16_SkColorType,     //!< pixel with half floats for red, green, blue, alpha; in 64-bit word
85     kRGBA_F32_SkColorType,     //!< pixel using C float for red, green, blue, alpha; in 128-bit word
86 
87     // The following 6 colortypes are just for reading from - not for rendering to
88     kR8G8_unorm_SkColorType,   //<! pixel with a uint8_t for red and green
89 
90     kA16_float_SkColorType,    //<! pixel with a half float for alpha
91     kR16G16_float_SkColorType, //<! pixel with a half float for red and green
92 
93     kA16_unorm_SkColorType,    //<! pixel with a little endian uint16_t for alpha
94     kR16G16_unorm_SkColorType, //<! pixel with a little endian uint16_t for red and green
95     kR16G16B16A16_unorm_SkColorType,//<! pixel with a little endian uint16_t for red, green, blue, and alpha
96 
97     kLastEnum_SkColorType     = kR16G16B16A16_unorm_SkColorType, //!< last valid value
98 
99 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
100     kN32_SkColorType          = kBGRA_8888_SkColorType,//!< native ARGB 32-bit encoding
101 
102 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
103     kN32_SkColorType          = kRGBA_8888_SkColorType,//!< native ARGB 32-bit 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 and RGB.
143 
144     JPEG YUV values encode the full range of 0 to 255 for all three components.
145     Video YUV values range from 16 to 235 for all three components. Details of
146     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 {
152     kJPEG_SkYUVColorSpace,                      //!< describes full range
153     kRec601_SkYUVColorSpace,                    //!< describes SDTV range
154     kRec709_SkYUVColorSpace,                    //!< describes HDTV range
155     kBT2020_SkYUVColorSpace,                    //!< describes UHDTV range, non-constant-luminance
156     kIdentity_SkYUVColorSpace,                  //!< maps Y->R, U->G, V->B
157 
158     kLastEnum_SkYUVColorSpace = kIdentity_SkYUVColorSpace, //!< last valid value
159 };
160 
161 /** \struct SkColorInfo
162     Describes pixel and encoding. SkImageInfo can be created from SkColorInfo by
163     providing dimensions.
164 
165     It encodes how pixel bits describe alpha, transparency; color components red, blue,
166     and green; and SkColorSpace, the range and linearity of colors.
167 */
168 class SK_API SkColorInfo {
169 public:
170     /** Creates an SkColorInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
171         and no SkColorSpace.
172 
173         @return  empty SkImageInfo
174     */
175     SkColorInfo() = default;
176 
177     /** Creates SkColorInfo from SkColorType ct, SkAlphaType at, and optionally SkColorSpace cs.
178 
179         If SkColorSpace cs is nullptr and SkColorInfo is part of drawing source: SkColorSpace
180         defaults to sRGB, mapping into SkSurface SkColorSpace.
181 
182         Parameters are not validated to see if their values are legal, or that the
183         combination is supported.
184         @return        created SkColorInfo
185     */
SkColorInfo(SkColorType ct,SkAlphaType at,sk_sp<SkColorSpace> cs)186     SkColorInfo(SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs)
187             : fColorSpace(std::move(cs)), fColorType(ct), fAlphaType(at) {}
188 
189     SkColorInfo(const SkColorInfo&) = default;
190     SkColorInfo(SkColorInfo&&) = default;
191 
192     SkColorInfo& operator=(const SkColorInfo&) = default;
193     SkColorInfo& operator=(SkColorInfo&&) = default;
194 
colorSpace()195     SkColorSpace* colorSpace() const { return fColorSpace.get(); }
refColorSpace()196     sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
colorType()197     SkColorType colorType() const { return fColorType; }
alphaType()198     SkAlphaType alphaType() const { return fAlphaType; }
199 
isOpaque()200     bool isOpaque() const { return SkAlphaTypeIsOpaque(fAlphaType); }
201 
gammaCloseToSRGB()202     bool gammaCloseToSRGB() const { return fColorSpace && fColorSpace->gammaCloseToSRGB(); }
203 
204     /** Does other represent the same color type, alpha type, and color space? */
205     bool operator==(const SkColorInfo& other) const {
206         return fColorType == other.fColorType && fAlphaType == other.fAlphaType &&
207                SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get());
208     }
209 
210     /** Does other represent a different color type, alpha type, or color space? */
211     bool operator!=(const SkColorInfo& other) const { return !(*this == other); }
212 
213     /** Creates SkColorInfo with same SkColorType, SkColorSpace, with SkAlphaType set
214         to newAlphaType.
215 
216         Created SkColorInfo contains newAlphaType even if it is incompatible with
217         SkColorType, in which case SkAlphaType in SkColorInfo is ignored.
218     */
makeAlphaType(SkAlphaType newAlphaType)219     SkColorInfo makeAlphaType(SkAlphaType newAlphaType) const {
220         return SkColorInfo(this->colorType(), newAlphaType, this->refColorSpace());
221     }
222 
223     /** Creates new SkColorInfo with same SkAlphaType, SkColorSpace, with SkColorType
224         set to newColorType.
225     */
makeColorType(SkColorType newColorType)226     SkColorInfo makeColorType(SkColorType newColorType) const {
227         return SkColorInfo(newColorType, this->alphaType(), this->refColorSpace());
228     }
229 
230     /** Creates SkColorInfo with same SkAlphaType, SkColorType, with SkColorSpace
231         set to cs. cs may be nullptr.
232     */
makeColorSpace(sk_sp<SkColorSpace> cs)233     SkColorInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
234         return SkColorInfo(this->colorType(), this->alphaType(), std::move(cs));
235     }
236 
237     /** Returns number of bytes per pixel required by SkColorType.
238         Returns zero if colorType() is kUnknown_SkColorType.
239 
240         @return  bytes in pixel
241 
242         example: https://fiddle.skia.org/c/@ImageInfo_bytesPerPixel
243     */
244     int bytesPerPixel() const;
245 
246     /** Returns bit shift converting row bytes to row pixels.
247         Returns zero for kUnknown_SkColorType.
248 
249         @return  one of: 0, 1, 2, 3, 4; left shift to convert pixels to bytes
250 
251         example: https://fiddle.skia.org/c/@ImageInfo_shiftPerPixel
252     */
253     int shiftPerPixel() const;
254 
255 private:
256     sk_sp<SkColorSpace> fColorSpace;
257     SkColorType fColorType = kUnknown_SkColorType;
258     SkAlphaType fAlphaType = kUnknown_SkAlphaType;
259 };
260 
261 /** \struct SkImageInfo
262     Describes pixel dimensions and encoding. SkBitmap, SkImage, PixMap, and SkSurface
263     can be created from SkImageInfo. SkImageInfo can be retrieved from SkBitmap and
264     SkPixmap, but not from SkImage and SkSurface. For example, SkImage and SkSurface
265     implementations may defer pixel depth, so may not completely specify SkImageInfo.
266 
267     SkImageInfo contains dimensions, the pixel integral width and height. It encodes
268     how pixel bits describe alpha, transparency; color components red, blue,
269     and green; and SkColorSpace, the range and linearity of colors.
270 */
271 struct SK_API SkImageInfo {
272 public:
273 
274     /** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
275         a width and height of zero, and no SkColorSpace.
276 
277         @return  empty SkImageInfo
278     */
279     SkImageInfo() = default;
280 
281     /** Creates SkImageInfo from integral dimensions width and height, SkColorType ct,
282         SkAlphaType at, and optionally SkColorSpace cs.
283 
284         If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
285         defaults to sRGB, mapping into SkSurface SkColorSpace.
286 
287         Parameters are not validated to see if their values are legal, or that the
288         combination is supported.
289 
290         @param width   pixel column count; must be zero or greater
291         @param height  pixel row count; must be zero or greater
292         @param cs      range of colors; may be nullptr
293         @return        created SkImageInfo
294     */
295     static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
296                             sk_sp<SkColorSpace> cs = nullptr) {
297         return SkImageInfo({width, height}, {ct, at, std::move(cs)});
298     }
299     static SkImageInfo Make(SkISize dimensions, SkColorType ct, SkAlphaType at,
300                             sk_sp<SkColorSpace> cs = nullptr) {
301         return SkImageInfo(dimensions, {ct, at, std::move(cs)});
302     }
303 
304     /** Creates SkImageInfo from integral dimensions and SkColorInfo colorInfo,
305 
306         Parameters are not validated to see if their values are legal, or that the
307         combination is supported.
308 
309         @param dimensions   pixel column and row count; must be zeros or greater
310         @param SkColorInfo  the pixel encoding consisting of SkColorType, SkAlphaType, and
311                             SkColorSpace (which may be nullptr)
312         @return        created SkImageInfo
313     */
MakeSkImageInfo314     static SkImageInfo Make(SkISize dimensions, const SkColorInfo& colorInfo) {
315         return SkImageInfo(dimensions, colorInfo);
316     }
MakeSkImageInfo317     static SkImageInfo Make(SkISize dimensions, SkColorInfo&& colorInfo) {
318         return SkImageInfo(dimensions, std::move(colorInfo));
319     }
320 
321     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
322         SkAlphaType at, and optionally SkColorSpace cs. kN32_SkColorType will equal either
323         kBGRA_8888_SkColorType or kRGBA_8888_SkColorType, whichever is optimal.
324 
325         If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
326         defaults to sRGB, mapping into SkSurface SkColorSpace.
327 
328         Parameters are not validated to see if their values are legal, or that the
329         combination is supported.
330 
331         @param width   pixel column count; must be zero or greater
332         @param height  pixel row count; must be zero or greater
333         @param cs      range of colors; may be nullptr
334         @return        created SkImageInfo
335     */
336     static SkImageInfo MakeN32(int width, int height, SkAlphaType at,
337                                sk_sp<SkColorSpace> cs = nullptr) {
338         return Make({width, height}, kN32_SkColorType, at, std::move(cs));
339     }
340 
341     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
342         SkAlphaType at, with sRGB SkColorSpace.
343 
344         Parameters are not validated to see if their values are legal, or that the
345         combination is supported.
346 
347         @param width   pixel column count; must be zero or greater
348         @param height  pixel row count; must be zero or greater
349         @return        created SkImageInfo
350 
351         example: https://fiddle.skia.org/c/@ImageInfo_MakeS32
352     */
353     static SkImageInfo MakeS32(int width, int height, SkAlphaType at);
354 
355     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
356         kPremul_SkAlphaType, with optional SkColorSpace.
357 
358         If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
359         defaults to sRGB, mapping into SkSurface SkColorSpace.
360 
361         Parameters are not validated to see if their values are legal, or that the
362         combination is supported.
363 
364         @param width   pixel column count; must be zero or greater
365         @param height  pixel row count; must be zero or greater
366         @param cs      range of colors; may be nullptr
367         @return        created SkImageInfo
368     */
369     static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs = nullptr) {
370         return Make({width, height}, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs));
371     }
372 
373     /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
374         kPremul_SkAlphaType, with SkColorSpace set to nullptr.
375 
376         If SkImageInfo is part of drawing source: SkColorSpace defaults to sRGB, mapping
377         into SkSurface SkColorSpace.
378 
379         Parameters are not validated to see if their values are legal, or that the
380         combination is supported.
381 
382         @param dimensions  width and height, each must be zero or greater
383         @param cs          range of colors; may be nullptr
384         @return            created SkImageInfo
385     */
386     static SkImageInfo MakeN32Premul(SkISize dimensions, sk_sp<SkColorSpace> cs = nullptr) {
387         return Make(dimensions, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs));
388     }
389 
390     /** Creates SkImageInfo from integral dimensions width and height, kAlpha_8_SkColorType,
391         kPremul_SkAlphaType, with SkColorSpace set to nullptr.
392 
393         @param width   pixel column count; must be zero or greater
394         @param height  pixel row count; must be zero or greater
395         @return        created SkImageInfo
396     */
MakeA8SkImageInfo397     static SkImageInfo MakeA8(int width, int height) {
398         return Make({width, height}, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
399     }
400     /** Creates SkImageInfo from integral dimensions, kAlpha_8_SkColorType,
401         kPremul_SkAlphaType, with SkColorSpace set to nullptr.
402 
403         @param dimensions   pixel row and column count; must be zero or greater
404         @return             created SkImageInfo
405     */
MakeA8SkImageInfo406     static SkImageInfo MakeA8(SkISize dimensions) {
407         return Make(dimensions, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
408     }
409 
410     /** Creates SkImageInfo from integral dimensions width and height, kUnknown_SkColorType,
411         kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
412 
413         Returned SkImageInfo as part of source does not draw, and as part of destination
414         can not be drawn to.
415 
416         @param width   pixel column count; must be zero or greater
417         @param height  pixel row count; must be zero or greater
418         @return        created SkImageInfo
419     */
MakeUnknownSkImageInfo420     static SkImageInfo MakeUnknown(int width, int height) {
421         return Make({width, height}, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr);
422     }
423 
424     /** Creates SkImageInfo from integral dimensions width and height set to zero,
425         kUnknown_SkColorType, 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         @return  created SkImageInfo
431     */
MakeUnknownSkImageInfo432     static SkImageInfo MakeUnknown() {
433         return MakeUnknown(0, 0);
434     }
435 
436     /** Returns pixel count in each row.
437 
438         @return  pixel width
439     */
widthSkImageInfo440     int width() const { return fDimensions.width(); }
441 
442     /** Returns pixel row count.
443 
444         @return  pixel height
445     */
heightSkImageInfo446     int height() const { return fDimensions.height(); }
447 
colorTypeSkImageInfo448     SkColorType colorType() const { return fColorInfo.colorType(); }
449 
alphaTypeSkImageInfo450     SkAlphaType alphaType() const { return fColorInfo.alphaType(); }
451 
452     /** Returns SkColorSpace, the range of colors. The reference count of
453         SkColorSpace is unchanged. The returned SkColorSpace is immutable.
454 
455         @return  SkColorSpace, or nullptr
456     */
colorSpaceSkImageInfo457     SkColorSpace* colorSpace() const { return fColorInfo.colorSpace(); }
458 
459     /** Returns smart pointer to SkColorSpace, the range of colors. The smart pointer
460         tracks the number of objects sharing this SkColorSpace reference so the memory
461         is released when the owners destruct.
462 
463         The returned SkColorSpace is immutable.
464 
465         @return  SkColorSpace wrapped in a smart pointer
466     */
refColorSpaceSkImageInfo467     sk_sp<SkColorSpace> refColorSpace() const { return fColorInfo.refColorSpace(); }
468 
469     /** Returns if SkImageInfo describes an empty area of pixels by checking if either
470         width or height is zero or smaller.
471 
472         @return  true if either dimension is zero or smaller
473     */
isEmptySkImageInfo474     bool isEmpty() const { return fDimensions.isEmpty(); }
475 
476     /** Returns the dimensionless SkColorInfo that represents the same color type,
477         alpha type, and color space as this SkImageInfo.
478      */
colorInfoSkImageInfo479     const SkColorInfo& colorInfo() const { return fColorInfo; }
480 
481     /** Returns true if SkAlphaType is set to hint that all pixels are opaque; their
482         alpha value is implicitly or explicitly 1.0. If true, and all pixels are
483         not opaque, Skia may draw incorrectly.
484 
485         Does not check if SkColorType allows alpha, or if any pixel value has
486         transparency.
487 
488         @return  true if SkAlphaType is kOpaque_SkAlphaType
489     */
isOpaqueSkImageInfo490     bool isOpaque() const { return fColorInfo.isOpaque(); }
491 
492     /** Returns SkISize { width(), height() }.
493 
494         @return  integral size of width() and height()
495     */
dimensionsSkImageInfo496     SkISize dimensions() const { return fDimensions; }
497 
498     /** Returns SkIRect { 0, 0, width(), height() }.
499 
500         @return  integral rectangle from origin to width() and height()
501     */
boundsSkImageInfo502     SkIRect bounds() const { return SkIRect::MakeSize(fDimensions); }
503 
504     /** Returns true if associated SkColorSpace is not nullptr, and SkColorSpace gamma
505         is approximately the same as sRGB.
506         This includes the
507 
508         @return  true if SkColorSpace gamma is approximately the same as sRGB
509     */
gammaCloseToSRGBSkImageInfo510     bool gammaCloseToSRGB() const { return fColorInfo.gammaCloseToSRGB(); }
511 
512     /** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
513         with dimensions set to width and height.
514 
515         @param newWidth   pixel column count; must be zero or greater
516         @param newHeight  pixel row count; must be zero or greater
517         @return           created SkImageInfo
518     */
makeWHSkImageInfo519     SkImageInfo makeWH(int newWidth, int newHeight) const {
520         return Make({newWidth, newHeight}, fColorInfo);
521     }
522 
523     /** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
524         with dimensions set to newDimensions.
525 
526         @param newSize   pixel column and row count; must be zero or greater
527         @return          created SkImageInfo
528     */
makeDimensionsSkImageInfo529     SkImageInfo makeDimensions(SkISize newSize) const {
530         return Make(newSize, fColorInfo);
531     }
532 
533     /** Creates SkImageInfo with same SkColorType, SkColorSpace, width, and height,
534         with SkAlphaType set to newAlphaType.
535 
536         Created SkImageInfo contains newAlphaType even if it is incompatible with
537         SkColorType, in which case SkAlphaType in SkImageInfo is ignored.
538 
539         @return              created SkImageInfo
540     */
makeAlphaTypeSkImageInfo541     SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
542         return Make(fDimensions, fColorInfo.makeAlphaType(newAlphaType));
543     }
544 
545     /** Creates SkImageInfo with same SkAlphaType, SkColorSpace, width, and height,
546         with SkColorType set to newColorType.
547 
548         @return              created SkImageInfo
549     */
makeColorTypeSkImageInfo550     SkImageInfo makeColorType(SkColorType newColorType) const {
551         return Make(fDimensions, fColorInfo.makeColorType(newColorType));
552     }
553 
554     /** Creates SkImageInfo with same SkAlphaType, SkColorType, width, and height,
555         with SkColorSpace set to cs.
556 
557         @param cs  range of colors; may be nullptr
558         @return    created SkImageInfo
559     */
makeColorSpaceSkImageInfo560     SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
561         return Make(fDimensions, fColorInfo.makeColorSpace(std::move(cs)));
562     }
563 
564     /** Returns number of bytes per pixel required by SkColorType.
565         Returns zero if colorType( is kUnknown_SkColorType.
566 
567         @return  bytes in pixel
568     */
bytesPerPixelSkImageInfo569     int bytesPerPixel() const { return fColorInfo.bytesPerPixel(); }
570 
571     /** Returns bit shift converting row bytes to row pixels.
572         Returns zero for kUnknown_SkColorType.
573 
574         @return  one of: 0, 1, 2, 3; left shift to convert pixels to bytes
575     */
shiftPerPixelSkImageInfo576     int shiftPerPixel() const { return fColorInfo.shiftPerPixel(); }
577 
578     /** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
579         specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
580         in 31 bits.
581 
582         @return  width() times bytesPerPixel() as unsigned 64-bit integer
583     */
minRowBytes64SkImageInfo584     uint64_t minRowBytes64() const { return sk_64_mul(this->width(), this->bytesPerPixel()); }
585 
586     /** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
587         specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
588         in 31 bits.
589 
590         @return  width() times bytesPerPixel() as signed 32-bit integer
591     */
minRowBytesSkImageInfo592     size_t minRowBytes() const {
593         uint64_t minRowBytes = this->minRowBytes64();
594         if (!SkTFitsIn<int32_t>(minRowBytes)) {
595             return 0;
596         }
597         return SkTo<int32_t>(minRowBytes);
598     }
599 
600     /** Returns byte offset of pixel from pixel base address.
601 
602         Asserts in debug build if x or y is outside of bounds. Does not assert if
603         rowBytes is smaller than minRowBytes(), even though result may be incorrect.
604 
605         @param x         column index, zero or greater, and less than width()
606         @param y         row index, zero or greater, and less than height()
607         @param rowBytes  size of pixel row or larger
608         @return          offset within pixel array
609 
610         example: https://fiddle.skia.org/c/@ImageInfo_computeOffset
611     */
612     size_t computeOffset(int x, int y, size_t rowBytes) const;
613 
614     /** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
615         SkAlphaType, and SkColorSpace are equivalent.
616 
617         @param other  SkImageInfo to compare
618         @return       true if SkImageInfo equals other
619     */
620     bool operator==(const SkImageInfo& other) const {
621         return fDimensions == other.fDimensions && fColorInfo == other.fColorInfo;
622     }
623 
624     /** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
625         SkAlphaType, and SkColorSpace are not equivalent.
626 
627         @param other  SkImageInfo to compare
628         @return       true if SkImageInfo is not equal to other
629     */
630     bool operator!=(const SkImageInfo& other) const {
631         return !(*this == other);
632     }
633 
634     /** Returns storage required by pixel array, given SkImageInfo dimensions, SkColorType,
635         and rowBytes. rowBytes is assumed to be at least as large as minRowBytes().
636 
637         Returns zero if height is zero.
638         Returns SIZE_MAX if answer exceeds the range of size_t.
639 
640         @param rowBytes  size of pixel row or larger
641         @return          memory required by pixel buffer
642 
643         example: https://fiddle.skia.org/c/@ImageInfo_computeByteSize
644     */
645     size_t computeByteSize(size_t rowBytes) const;
646 
647     /** Returns storage required by pixel array, given SkImageInfo dimensions, and
648         SkColorType. Uses minRowBytes() to compute bytes for pixel row.
649 
650         Returns zero if height is zero.
651         Returns SIZE_MAX if answer exceeds the range of size_t.
652 
653         @return  least memory required by pixel buffer
654     */
computeMinByteSizeSkImageInfo655     size_t computeMinByteSize() const {
656         return this->computeByteSize(this->minRowBytes());
657     }
658 
659     /** Returns true if byteSize equals SIZE_MAX. computeByteSize() and
660         computeMinByteSize() return SIZE_MAX if size_t can not hold buffer size.
661 
662         @param byteSize  result of computeByteSize() or computeMinByteSize()
663         @return          true if computeByteSize() or computeMinByteSize() result exceeds size_t
664     */
ByteSizeOverflowedSkImageInfo665     static bool ByteSizeOverflowed(size_t byteSize) {
666         return SIZE_MAX == byteSize;
667     }
668 
669     /** Returns true if rowBytes is valid for this SkImageInfo.
670 
671         @param rowBytes  size of pixel row including padding
672         @return          true if rowBytes is large enough to contain pixel row and is properly
673                          aligned
674     */
validRowBytesSkImageInfo675     bool validRowBytes(size_t rowBytes) const {
676         if (rowBytes < this->minRowBytes64()) {
677             return false;
678         }
679         int shift = this->shiftPerPixel();
680         size_t alignedRowBytes = rowBytes >> shift << shift;
681         return alignedRowBytes == rowBytes;
682     }
683 
684     /** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
685         a width and height of zero, and no SkColorSpace.
686     */
resetSkImageInfo687     void reset() { *this = {}; }
688 
689     /** Asserts if internal values are illegal or inconsistent. Only available if
690         SK_DEBUG is defined at compile time.
691     */
692     SkDEBUGCODE(void validate() const;)
693 
694 private:
695     SkColorInfo fColorInfo;
696     SkISize fDimensions = {0, 0};
697 
SkImageInfoSkImageInfo698     SkImageInfo(SkISize dimensions, const SkColorInfo& colorInfo)
699             : fColorInfo(colorInfo), fDimensions(dimensions) {}
700 
SkImageInfoSkImageInfo701     SkImageInfo(SkISize dimensions, SkColorInfo&& colorInfo)
702             : fColorInfo(std::move(colorInfo)), fDimensions(dimensions) {}
703 };
704 
705 #endif
706