| 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 | */ | 
|---|
| 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 { | 
|---|
| 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 | */ | 
|---|
| 112 | SK_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 | */ | 
|---|
| 119 | SK_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 | */ | 
|---|
| 132 | SK_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 | */ | 
|---|
| 148 | enum 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 | */ | 
|---|
| 177 | class SK_API SkColorInfo { | 
|---|
| 178 | public: | 
|---|
| 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 |  | 
|---|
| 267 | private: | 
|---|
| 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 | */ | 
|---|
| 283 | struct SK_API SkImageInfo { | 
|---|
| 284 | public: | 
|---|
| 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 |  | 
|---|
| 708 | private: | 
|---|
| 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 |  | 
|---|