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