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