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