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
19class SkReadBuffer;
20class 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*/
37enum 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*/
52static 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*/
70enum 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*/
115SK_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*/
122SK_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*/
135SK_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*/
151enum 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*/
168class SK_API SkColorInfo {
169public:
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 */
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
195 SkColorSpace* colorSpace() const { return fColorSpace.get(); }
196 sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
197 SkColorType colorType() const { return fColorType; }
198 SkAlphaType alphaType() const { return fAlphaType; }
199
200 bool isOpaque() const {
201 return SkAlphaTypeIsOpaque(fAlphaType)
202 || SkColorTypeIsAlwaysOpaque(fColorType);
203 }
204
205 bool gammaCloseToSRGB() const { return fColorSpace && fColorSpace->gammaCloseToSRGB(); }
206
207 /** Does other represent the same color type, alpha type, and color space? */
208 bool operator==(const SkColorInfo& other) const {
209 return fColorType == other.fColorType && fAlphaType == other.fAlphaType &&
210 SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get());
211 }
212
213 /** Does other represent a different color type, alpha type, or color space? */
214 bool operator!=(const SkColorInfo& other) const { return !(*this == other); }
215
216 /** Creates SkColorInfo with same SkColorType, SkColorSpace, with SkAlphaType set
217 to newAlphaType.
218
219 Created SkColorInfo contains newAlphaType even if it is incompatible with
220 SkColorType, in which case SkAlphaType in SkColorInfo is ignored.
221 */
222 SkColorInfo makeAlphaType(SkAlphaType newAlphaType) const {
223 return SkColorInfo(this->colorType(), newAlphaType, this->refColorSpace());
224 }
225
226 /** Creates new SkColorInfo with same SkAlphaType, SkColorSpace, with SkColorType
227 set to newColorType.
228 */
229 SkColorInfo makeColorType(SkColorType newColorType) const {
230 return SkColorInfo(newColorType, this->alphaType(), this->refColorSpace());
231 }
232
233 /** Creates SkColorInfo with same SkAlphaType, SkColorType, with SkColorSpace
234 set to cs. cs may be nullptr.
235 */
236 SkColorInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
237 return SkColorInfo(this->colorType(), this->alphaType(), std::move(cs));
238 }
239
240 /** Returns number of bytes per pixel required by SkColorType.
241 Returns zero if colorType() is kUnknown_SkColorType.
242
243 @return bytes in pixel
244
245 example: https://fiddle.skia.org/c/@ImageInfo_bytesPerPixel
246 */
247 int bytesPerPixel() const;
248
249 /** Returns bit shift converting row bytes to row pixels.
250 Returns zero for kUnknown_SkColorType.
251
252 @return one of: 0, 1, 2, 3, 4; left shift to convert pixels to bytes
253
254 example: https://fiddle.skia.org/c/@ImageInfo_shiftPerPixel
255 */
256 int shiftPerPixel() const;
257
258private:
259 sk_sp<SkColorSpace> fColorSpace;
260 SkColorType fColorType = kUnknown_SkColorType;
261 SkAlphaType fAlphaType = kUnknown_SkAlphaType;
262};
263
264/** \struct SkImageInfo
265 Describes pixel dimensions and encoding. SkBitmap, SkImage, PixMap, and SkSurface
266 can be created from SkImageInfo. SkImageInfo can be retrieved from SkBitmap and
267 SkPixmap, but not from SkImage and SkSurface. For example, SkImage and SkSurface
268 implementations may defer pixel depth, so may not completely specify SkImageInfo.
269
270 SkImageInfo contains dimensions, the pixel integral width and height. It encodes
271 how pixel bits describe alpha, transparency; color components red, blue,
272 and green; and SkColorSpace, the range and linearity of colors.
273*/
274struct SK_API SkImageInfo {
275public:
276
277 /** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
278 a width and height of zero, and no SkColorSpace.
279
280 @return empty SkImageInfo
281 */
282 SkImageInfo() = default;
283
284 /** Creates SkImageInfo from integral dimensions width and height, SkColorType ct,
285 SkAlphaType at, and optionally SkColorSpace cs.
286
287 If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
288 defaults to sRGB, mapping into SkSurface SkColorSpace.
289
290 Parameters are not validated to see if their values are legal, or that the
291 combination is supported.
292
293 @param width pixel column count; must be zero or greater
294 @param height pixel row count; must be zero or greater
295 @param cs range of colors; may be nullptr
296 @return created SkImageInfo
297 */
298 static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
299 sk_sp<SkColorSpace> cs = nullptr) {
300 return SkImageInfo({width, height}, {ct, at, std::move(cs)});
301 }
302 static SkImageInfo Make(SkISize dimensions, SkColorType ct, SkAlphaType at,
303 sk_sp<SkColorSpace> cs = nullptr) {
304 return SkImageInfo(dimensions, {ct, at, std::move(cs)});
305 }
306
307 /** Creates SkImageInfo from integral dimensions and SkColorInfo colorInfo,
308
309 Parameters are not validated to see if their values are legal, or that the
310 combination is supported.
311
312 @param dimensions pixel column and row count; must be zeros or greater
313 @param SkColorInfo the pixel encoding consisting of SkColorType, SkAlphaType, and
314 SkColorSpace (which may be nullptr)
315 @return created SkImageInfo
316 */
317 static SkImageInfo Make(SkISize dimensions, const SkColorInfo& colorInfo) {
318 return SkImageInfo(dimensions, colorInfo);
319 }
320 static SkImageInfo Make(SkISize dimensions, SkColorInfo&& colorInfo) {
321 return SkImageInfo(dimensions, std::move(colorInfo));
322 }
323
324 /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
325 SkAlphaType at, and optionally SkColorSpace cs. kN32_SkColorType will equal either
326 kBGRA_8888_SkColorType or kRGBA_8888_SkColorType, whichever is optimal.
327
328 If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
329 defaults to sRGB, mapping into SkSurface SkColorSpace.
330
331 Parameters are not validated to see if their values are legal, or that the
332 combination is supported.
333
334 @param width pixel column count; must be zero or greater
335 @param height pixel row count; must be zero or greater
336 @param cs range of colors; may be nullptr
337 @return created SkImageInfo
338 */
339 static SkImageInfo MakeN32(int width, int height, SkAlphaType at,
340 sk_sp<SkColorSpace> cs = nullptr) {
341 return Make({width, height}, kN32_SkColorType, at, std::move(cs));
342 }
343
344 /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
345 SkAlphaType at, with sRGB SkColorSpace.
346
347 Parameters are not validated to see if their values are legal, or that the
348 combination is supported.
349
350 @param width pixel column count; must be zero or greater
351 @param height pixel row count; must be zero or greater
352 @return created SkImageInfo
353
354 example: https://fiddle.skia.org/c/@ImageInfo_MakeS32
355 */
356 static SkImageInfo MakeS32(int width, int height, SkAlphaType at);
357
358 /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
359 kPremul_SkAlphaType, with optional SkColorSpace.
360
361 If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
362 defaults to sRGB, mapping into SkSurface SkColorSpace.
363
364 Parameters are not validated to see if their values are legal, or that the
365 combination is supported.
366
367 @param width pixel column count; must be zero or greater
368 @param height pixel row count; must be zero or greater
369 @param cs range of colors; may be nullptr
370 @return created SkImageInfo
371 */
372 static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs = nullptr) {
373 return Make({width, height}, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs));
374 }
375
376 /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
377 kPremul_SkAlphaType, with SkColorSpace set to nullptr.
378
379 If SkImageInfo is part of drawing source: SkColorSpace defaults to sRGB, mapping
380 into SkSurface SkColorSpace.
381
382 Parameters are not validated to see if their values are legal, or that the
383 combination is supported.
384
385 @param dimensions width and height, each must be zero or greater
386 @param cs range of colors; may be nullptr
387 @return created SkImageInfo
388 */
389 static SkImageInfo MakeN32Premul(SkISize dimensions, sk_sp<SkColorSpace> cs = nullptr) {
390 return Make(dimensions, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs));
391 }
392
393 /** Creates SkImageInfo from integral dimensions width and height, kAlpha_8_SkColorType,
394 kPremul_SkAlphaType, with SkColorSpace set to nullptr.
395
396 @param width pixel column count; must be zero or greater
397 @param height pixel row count; must be zero or greater
398 @return created SkImageInfo
399 */
400 static SkImageInfo MakeA8(int width, int height) {
401 return Make({width, height}, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
402 }
403 /** Creates SkImageInfo from integral dimensions, kAlpha_8_SkColorType,
404 kPremul_SkAlphaType, with SkColorSpace set to nullptr.
405
406 @param dimensions pixel row and column count; must be zero or greater
407 @return created SkImageInfo
408 */
409 static SkImageInfo MakeA8(SkISize dimensions) {
410 return Make(dimensions, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
411 }
412
413 /** Creates SkImageInfo from integral dimensions width and height, kUnknown_SkColorType,
414 kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
415
416 Returned SkImageInfo as part of source does not draw, and as part of destination
417 can not be drawn to.
418
419 @param width pixel column count; must be zero or greater
420 @param height pixel row count; must be zero or greater
421 @return created SkImageInfo
422 */
423 static SkImageInfo MakeUnknown(int width, int height) {
424 return Make({width, height}, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr);
425 }
426
427 /** Creates SkImageInfo from integral dimensions width and height set to zero,
428 kUnknown_SkColorType, kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
429
430 Returned SkImageInfo as part of source does not draw, and as part of destination
431 can not be drawn to.
432
433 @return created SkImageInfo
434 */
435 static SkImageInfo MakeUnknown() {
436 return MakeUnknown(0, 0);
437 }
438
439 /** Returns pixel count in each row.
440
441 @return pixel width
442 */
443 int width() const { return fDimensions.width(); }
444
445 /** Returns pixel row count.
446
447 @return pixel height
448 */
449 int height() const { return fDimensions.height(); }
450
451 SkColorType colorType() const { return fColorInfo.colorType(); }
452
453 SkAlphaType alphaType() const { return fColorInfo.alphaType(); }
454
455 /** Returns SkColorSpace, the range of colors. The reference count of
456 SkColorSpace is unchanged. The returned SkColorSpace is immutable.
457
458 @return SkColorSpace, or nullptr
459 */
460 SkColorSpace* colorSpace() const { return fColorInfo.colorSpace(); }
461
462 /** Returns smart pointer to SkColorSpace, the range of colors. The smart pointer
463 tracks the number of objects sharing this SkColorSpace reference so the memory
464 is released when the owners destruct.
465
466 The returned SkColorSpace is immutable.
467
468 @return SkColorSpace wrapped in a smart pointer
469 */
470 sk_sp<SkColorSpace> refColorSpace() const { return fColorInfo.refColorSpace(); }
471
472 /** Returns if SkImageInfo describes an empty area of pixels by checking if either
473 width or height is zero or smaller.
474
475 @return true if either dimension is zero or smaller
476 */
477 bool isEmpty() const { return fDimensions.isEmpty(); }
478
479 /** Returns the dimensionless SkColorInfo that represents the same color type,
480 alpha type, and color space as this SkImageInfo.
481 */
482 const SkColorInfo& colorInfo() const { return fColorInfo; }
483
484 /** Returns true if SkAlphaType is set to hint that all pixels are opaque; their
485 alpha value is implicitly or explicitly 1.0. If true, and all pixels are
486 not opaque, Skia may draw incorrectly.
487
488 Does not check if SkColorType allows alpha, or if any pixel value has
489 transparency.
490
491 @return true if SkAlphaType is kOpaque_SkAlphaType
492 */
493 bool isOpaque() const { return fColorInfo.isOpaque(); }
494
495 /** Returns SkISize { width(), height() }.
496
497 @return integral size of width() and height()
498 */
499 SkISize dimensions() const { return fDimensions; }
500
501 /** Returns SkIRect { 0, 0, width(), height() }.
502
503 @return integral rectangle from origin to width() and height()
504 */
505 SkIRect bounds() const { return SkIRect::MakeSize(fDimensions); }
506
507 /** Returns true if associated SkColorSpace is not nullptr, and SkColorSpace gamma
508 is approximately the same as sRGB.
509 This includes the
510
511 @return true if SkColorSpace gamma is approximately the same as sRGB
512 */
513 bool gammaCloseToSRGB() const { return fColorInfo.gammaCloseToSRGB(); }
514
515 /** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
516 with dimensions set to width and height.
517
518 @param newWidth pixel column count; must be zero or greater
519 @param newHeight pixel row count; must be zero or greater
520 @return created SkImageInfo
521 */
522 SkImageInfo makeWH(int newWidth, int newHeight) const {
523 return Make({newWidth, newHeight}, fColorInfo);
524 }
525
526 /** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
527 with dimensions set to newDimensions.
528
529 @param newSize pixel column and row count; must be zero or greater
530 @return created SkImageInfo
531 */
532 SkImageInfo makeDimensions(SkISize newSize) const {
533 return Make(newSize, fColorInfo);
534 }
535
536 /** Creates SkImageInfo with same SkColorType, SkColorSpace, width, and height,
537 with SkAlphaType set to newAlphaType.
538
539 Created SkImageInfo contains newAlphaType even if it is incompatible with
540 SkColorType, in which case SkAlphaType in SkImageInfo is ignored.
541
542 @return created SkImageInfo
543 */
544 SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
545 return Make(fDimensions, fColorInfo.makeAlphaType(newAlphaType));
546 }
547
548 /** Creates SkImageInfo with same SkAlphaType, SkColorSpace, width, and height,
549 with SkColorType set to newColorType.
550
551 @return created SkImageInfo
552 */
553 SkImageInfo makeColorType(SkColorType newColorType) const {
554 return Make(fDimensions, fColorInfo.makeColorType(newColorType));
555 }
556
557 /** Creates SkImageInfo with same SkAlphaType, SkColorType, width, and height,
558 with SkColorSpace set to cs.
559
560 @param cs range of colors; may be nullptr
561 @return created SkImageInfo
562 */
563 SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
564 return Make(fDimensions, fColorInfo.makeColorSpace(std::move(cs)));
565 }
566
567 /** Returns number of bytes per pixel required by SkColorType.
568 Returns zero if colorType( is kUnknown_SkColorType.
569
570 @return bytes in pixel
571 */
572 int bytesPerPixel() const { return fColorInfo.bytesPerPixel(); }
573
574 /** Returns bit shift converting row bytes to row pixels.
575 Returns zero for kUnknown_SkColorType.
576
577 @return one of: 0, 1, 2, 3; left shift to convert pixels to bytes
578 */
579 int shiftPerPixel() const { return fColorInfo.shiftPerPixel(); }
580
581 /** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
582 specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
583 in 31 bits.
584
585 @return width() times bytesPerPixel() as unsigned 64-bit integer
586 */
587 uint64_t minRowBytes64() const { return sk_64_mul(this->width(), this->bytesPerPixel()); }
588
589 /** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
590 specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
591 in 31 bits.
592
593 @return width() times bytesPerPixel() as signed 32-bit integer
594 */
595 size_t minRowBytes() const {
596 uint64_t minRowBytes = this->minRowBytes64();
597 if (!SkTFitsIn<int32_t>(minRowBytes)) {
598 return 0;
599 }
600 return SkTo<int32_t>(minRowBytes);
601 }
602
603 /** Returns byte offset of pixel from pixel base address.
604
605 Asserts in debug build if x or y is outside of bounds. Does not assert if
606 rowBytes is smaller than minRowBytes(), even though result may be incorrect.
607
608 @param x column index, zero or greater, and less than width()
609 @param y row index, zero or greater, and less than height()
610 @param rowBytes size of pixel row or larger
611 @return offset within pixel array
612
613 example: https://fiddle.skia.org/c/@ImageInfo_computeOffset
614 */
615 size_t computeOffset(int x, int y, size_t rowBytes) const;
616
617 /** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
618 SkAlphaType, and SkColorSpace are equivalent.
619
620 @param other SkImageInfo to compare
621 @return true if SkImageInfo equals other
622 */
623 bool operator==(const SkImageInfo& other) const {
624 return fDimensions == other.fDimensions && fColorInfo == other.fColorInfo;
625 }
626
627 /** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
628 SkAlphaType, and SkColorSpace are not equivalent.
629
630 @param other SkImageInfo to compare
631 @return true if SkImageInfo is not equal to other
632 */
633 bool operator!=(const SkImageInfo& other) const {
634 return !(*this == other);
635 }
636
637 /** Returns storage required by pixel array, given SkImageInfo dimensions, SkColorType,
638 and rowBytes. rowBytes is assumed to be at least as large as minRowBytes().
639
640 Returns zero if height is zero.
641 Returns SIZE_MAX if answer exceeds the range of size_t.
642
643 @param rowBytes size of pixel row or larger
644 @return memory required by pixel buffer
645
646 example: https://fiddle.skia.org/c/@ImageInfo_computeByteSize
647 */
648 size_t computeByteSize(size_t rowBytes) const;
649
650 /** Returns storage required by pixel array, given SkImageInfo dimensions, and
651 SkColorType. Uses minRowBytes() to compute bytes for pixel row.
652
653 Returns zero if height is zero.
654 Returns SIZE_MAX if answer exceeds the range of size_t.
655
656 @return least memory required by pixel buffer
657 */
658 size_t computeMinByteSize() const {
659 return this->computeByteSize(this->minRowBytes());
660 }
661
662 /** Returns true if byteSize equals SIZE_MAX. computeByteSize() and
663 computeMinByteSize() return SIZE_MAX if size_t can not hold buffer size.
664
665 @param byteSize result of computeByteSize() or computeMinByteSize()
666 @return true if computeByteSize() or computeMinByteSize() result exceeds size_t
667 */
668 static bool ByteSizeOverflowed(size_t byteSize) {
669 return SIZE_MAX == byteSize;
670 }
671
672 /** Returns true if rowBytes is valid for this SkImageInfo.
673
674 @param rowBytes size of pixel row including padding
675 @return true if rowBytes is large enough to contain pixel row and is properly
676 aligned
677 */
678 bool validRowBytes(size_t rowBytes) const {
679 if (rowBytes < this->minRowBytes64()) {
680 return false;
681 }
682 int shift = this->shiftPerPixel();
683 size_t alignedRowBytes = rowBytes >> shift << shift;
684 return alignedRowBytes == rowBytes;
685 }
686
687 /** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
688 a width and height of zero, and no SkColorSpace.
689 */
690 void reset() { *this = {}; }
691
692 /** Asserts if internal values are illegal or inconsistent. Only available if
693 SK_DEBUG is defined at compile time.
694 */
695 SkDEBUGCODE(void validate() const;)
696
697private:
698 SkColorInfo fColorInfo;
699 SkISize fDimensions = {0, 0};
700
701 SkImageInfo(SkISize dimensions, const SkColorInfo& colorInfo)
702 : fColorInfo(colorInfo), fDimensions(dimensions) {}
703
704 SkImageInfo(SkISize dimensions, SkColorInfo&& colorInfo)
705 : fColorInfo(std::move(colorInfo)), fDimensions(dimensions) {}
706};
707
708#endif
709