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 "SkColorSpace.h" 12 #include "SkMath.h" 13 #include "SkRect.h" 14 #include "SkSize.h" 15 16 class SkReadBuffer; 17 class SkWriteBuffer; 18 19 /** 20 * Describes how to interpret the alpha component of a pixel. 21 */ 22 enum SkAlphaType { 23 kUnknown_SkAlphaType, 24 25 /** 26 * All pixels are stored as opaque. This differs slightly from kIgnore in 27 * that kOpaque has correct "opaque" values stored in the pixels, while 28 * kIgnore may not, but in both cases the caller should treat the pixels 29 * as opaque. 30 */ 31 kOpaque_SkAlphaType, 32 33 /** 34 * All pixels have their alpha premultiplied in their color components. 35 * This is the natural format for the rendering target pixels. 36 */ 37 kPremul_SkAlphaType, 38 39 /** 40 * All pixels have their color components stored without any regard to the 41 * alpha. e.g. this is the default configuration for PNG images. 42 * 43 * This alpha-type is ONLY supported for input images. Rendering cannot 44 * generate this on output. 45 */ 46 kUnpremul_SkAlphaType, 47 48 kLastEnum_SkAlphaType = kUnpremul_SkAlphaType 49 }; 50 51 static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) { 52 return kOpaque_SkAlphaType == at; 53 } 54 55 static inline bool SkAlphaTypeIsValid(unsigned value) { 56 return value <= kLastEnum_SkAlphaType; 57 } 58 59 /////////////////////////////////////////////////////////////////////////////// 60 61 /** 62 * Describes how to interpret the components of a pixel. 63 * 64 * kN32_SkColorType is an alias for whichever 32bit ARGB format is the "native" 65 * form for skia's blitters. Use this if you don't have a swizzle preference 66 * for 32bit pixels. 67 */ 68 enum SkColorType { 69 kUnknown_SkColorType, 70 kAlpha_8_SkColorType, 71 kRGB_565_SkColorType, 72 kARGB_4444_SkColorType, 73 kRGBA_8888_SkColorType, 74 kBGRA_8888_SkColorType, 75 kIndex_8_SkColorType, 76 kGray_8_SkColorType, 77 kRGBA_F16_SkColorType, 78 79 kLastEnum_SkColorType = kRGBA_F16_SkColorType, 80 81 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) 82 kN32_SkColorType = kBGRA_8888_SkColorType, 83 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 84 kN32_SkColorType = kRGBA_8888_SkColorType, 85 #else 86 #error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order" 87 #endif 88 }; 89 90 static int SkColorTypeBytesPerPixel(SkColorType ct) { 91 static const uint8_t gSize[] = { 92 0, // Unknown 93 1, // Alpha_8 94 2, // RGB_565 95 2, // ARGB_4444 96 4, // RGBA_8888 97 4, // BGRA_8888 98 1, // kIndex_8 99 1, // kGray_8 100 8, // kRGBA_F16 101 }; 102 static_assert(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1), 103 "size_mismatch_with_SkColorType_enum"); 104 105 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gSize)); 106 return gSize[ct]; 107 } 108 109 static int SkColorTypeShiftPerPixel(SkColorType ct) { 110 static const uint8_t gShift[] = { 111 0, // Unknown 112 0, // Alpha_8 113 1, // RGB_565 114 1, // ARGB_4444 115 2, // RGBA_8888 116 2, // BGRA_8888 117 0, // kIndex_8 118 0, // kGray_8 119 3, // kRGBA_F16 120 }; 121 static_assert(SK_ARRAY_COUNT(gShift) == (size_t)(kLastEnum_SkColorType + 1), 122 "size_mismatch_with_SkColorType_enum"); 123 124 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gShift)); 125 return gShift[ct]; 126 } 127 128 static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) { 129 return width * SkColorTypeBytesPerPixel(ct); 130 } 131 132 static inline bool SkColorTypeIsValid(unsigned value) { 133 return value <= kLastEnum_SkColorType; 134 } 135 136 static inline size_t SkColorTypeComputeOffset(SkColorType ct, int x, int y, size_t rowBytes) { 137 if (kUnknown_SkColorType == ct) { 138 return 0; 139 } 140 return y * rowBytes + (x << SkColorTypeShiftPerPixel(ct)); 141 } 142 143 /////////////////////////////////////////////////////////////////////////////// 144 145 /** 146 * Return true if alphaType is supported by colorType. If there is a canonical 147 * alphaType for this colorType, return it in canonical. 148 */ 149 bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType, 150 SkAlphaType* canonical = NULL); 151 152 /////////////////////////////////////////////////////////////////////////////// 153 154 /** 155 * Describes the color space a YUV pixel. 156 */ 157 enum SkYUVColorSpace { 158 /** Standard JPEG color space. */ 159 kJPEG_SkYUVColorSpace, 160 /** SDTV standard Rec. 601 color space. Uses "studio swing" [16, 235] color 161 range. See http://en.wikipedia.org/wiki/Rec._601 for details. */ 162 kRec601_SkYUVColorSpace, 163 /** HDTV standard Rec. 709 color space. Uses "studio swing" [16, 235] color 164 range. See http://en.wikipedia.org/wiki/Rec._709 for details. */ 165 kRec709_SkYUVColorSpace, 166 167 kLastEnum_SkYUVColorSpace = kRec709_SkYUVColorSpace 168 }; 169 170 /////////////////////////////////////////////////////////////////////////////// 171 172 enum class SkDestinationSurfaceColorMode { 173 kLegacy, 174 kGammaAndColorSpaceAware, 175 }; 176 177 /** 178 * Describe an image's dimensions and pixel type. 179 * Used for both src images and render-targets (surfaces). 180 */ 181 struct SK_API SkImageInfo { 182 public: 183 SkImageInfo() 184 : fColorSpace(nullptr) 185 , fWidth(0) 186 , fHeight(0) 187 , fColorType(kUnknown_SkColorType) 188 , fAlphaType(kUnknown_SkAlphaType) 189 {} 190 191 static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at, 192 sk_sp<SkColorSpace> cs = nullptr) { 193 return SkImageInfo(width, height, ct, at, std::move(cs)); 194 } 195 196 /** 197 * Sets colortype to the native ARGB32 type. 198 */ 199 static SkImageInfo MakeN32(int width, int height, SkAlphaType at, 200 sk_sp<SkColorSpace> cs = nullptr) { 201 return Make(width, height, kN32_SkColorType, at, cs); 202 } 203 204 /** 205 * Create an ImageInfo marked as SRGB with N32 swizzle. 206 */ 207 static SkImageInfo MakeS32(int width, int height, SkAlphaType at); 208 209 /** 210 * Sets colortype to the native ARGB32 type, and the alphatype to premul. 211 */ 212 static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs = nullptr) { 213 return Make(width, height, kN32_SkColorType, kPremul_SkAlphaType, cs); 214 } 215 216 static SkImageInfo MakeN32Premul(const SkISize& size) { 217 return MakeN32Premul(size.width(), size.height()); 218 } 219 220 static SkImageInfo MakeA8(int width, int height) { 221 return Make(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr); 222 } 223 224 static SkImageInfo MakeUnknown(int width, int height) { 225 return Make(width, height, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr); 226 } 227 228 static SkImageInfo MakeUnknown() { 229 return MakeUnknown(0, 0); 230 } 231 232 int width() const { return fWidth; } 233 int height() const { return fHeight; } 234 SkColorType colorType() const { return fColorType; } 235 SkAlphaType alphaType() const { return fAlphaType; } 236 SkColorSpace* colorSpace() const { return fColorSpace.get(); } 237 sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; } 238 239 bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; } 240 241 bool isOpaque() const { 242 return SkAlphaTypeIsOpaque(fAlphaType); 243 } 244 245 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); } 246 SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); } 247 248 bool gammaCloseToSRGB() const { 249 return fColorSpace && fColorSpace->gammaCloseToSRGB(); 250 } 251 252 /** 253 * Return a new ImageInfo with the same colortype and alphatype as this info, 254 * but with the specified width and height. 255 */ 256 SkImageInfo makeWH(int newWidth, int newHeight) const { 257 return Make(newWidth, newHeight, fColorType, fAlphaType, fColorSpace); 258 } 259 260 SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const { 261 return Make(fWidth, fHeight, fColorType, newAlphaType, fColorSpace); 262 } 263 264 SkImageInfo makeColorType(SkColorType newColorType) const { 265 return Make(fWidth, fHeight, newColorType, fAlphaType, fColorSpace); 266 } 267 268 SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const { 269 return Make(fWidth, fHeight, fColorType, fAlphaType, std::move(cs)); 270 } 271 272 int bytesPerPixel() const { return SkColorTypeBytesPerPixel(fColorType); } 273 274 int shiftPerPixel() const { return SkColorTypeShiftPerPixel(fColorType); } 275 276 uint64_t minRowBytes64() const { 277 return sk_64_mul(fWidth, this->bytesPerPixel()); 278 } 279 280 size_t minRowBytes() const { 281 uint64_t minRowBytes = this->minRowBytes64(); 282 if (!sk_64_isS32(minRowBytes)) { 283 return 0; 284 } 285 return sk_64_asS32(minRowBytes); 286 } 287 288 size_t computeOffset(int x, int y, size_t rowBytes) const { 289 SkASSERT((unsigned)x < (unsigned)fWidth); 290 SkASSERT((unsigned)y < (unsigned)fHeight); 291 return SkColorTypeComputeOffset(fColorType, x, y, rowBytes); 292 } 293 294 bool operator==(const SkImageInfo& other) const { 295 return fWidth == other.fWidth && fHeight == other.fHeight && 296 fColorType == other.fColorType && fAlphaType == other.fAlphaType && 297 SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get()); 298 } 299 bool operator!=(const SkImageInfo& other) const { 300 return !(*this == other); 301 } 302 303 void unflatten(SkReadBuffer&); 304 void flatten(SkWriteBuffer&) const; 305 306 int64_t getSafeSize64(size_t rowBytes) const { 307 if (0 == fHeight) { 308 return 0; 309 } 310 return sk_64_mul(fHeight - 1, rowBytes) + sk_64_mul(fWidth, this->bytesPerPixel()); 311 } 312 313 size_t getSafeSize(size_t rowBytes) const { 314 int64_t size = this->getSafeSize64(rowBytes); 315 if (!sk_64_isS32(size)) { 316 return 0; 317 } 318 return sk_64_asS32(size); 319 } 320 321 bool validRowBytes(size_t rowBytes) const { 322 uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel()); 323 return rowBytes >= rb; 324 } 325 326 void reset() { 327 fColorSpace = nullptr; 328 fWidth = 0; 329 fHeight = 0; 330 fColorType = kUnknown_SkColorType; 331 fAlphaType = kUnknown_SkAlphaType; 332 } 333 334 SkDEBUGCODE(void validate() const;) 335 336 private: 337 sk_sp<SkColorSpace> fColorSpace; 338 int fWidth; 339 int fHeight; 340 SkColorType fColorType; 341 SkAlphaType fAlphaType; 342 343 SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs) 344 : fColorSpace(std::move(cs)) 345 , fWidth(width) 346 , fHeight(height) 347 , fColorType(ct) 348 , fAlphaType(at) 349 {} 350 }; 351 352 #endif 353