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