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