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 16class SkReadBuffer; 17class SkWriteBuffer; 18 19/** 20 * Describes how to interpret the alpha component of a pixel. 21 */ 22enum 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 51static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) { 52 return kOpaque_SkAlphaType == at; 53} 54 55/////////////////////////////////////////////////////////////////////////////// 56 57/** Temporary macro that allows us to add new color types without breaking Chrome compile. */ 58#define SK_EXTENDED_COLOR_TYPES 59 60/** 61 * Describes how to interpret the components of a pixel. 62 * 63 * kN32_SkColorType is an alias for whichever 32bit ARGB format is the "native" 64 * form for skia's blitters. Use this if you don't have a swizzle preference 65 * for 32bit pixels. 66 */ 67enum SkColorType { 68 kUnknown_SkColorType, 69 kAlpha_8_SkColorType, 70 kRGB_565_SkColorType, 71 kARGB_4444_SkColorType, 72 kRGBA_8888_SkColorType, 73 kRGB_888x_SkColorType, 74 kBGRA_8888_SkColorType, 75 kRGBA_1010102_SkColorType, 76 kRGB_101010x_SkColorType, 77 kGray_8_SkColorType, 78 kRGBA_F16_SkColorType, 79 80 kLastEnum_SkColorType = kRGBA_F16_SkColorType, 81 82#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) 83 kN32_SkColorType = kBGRA_8888_SkColorType, 84#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 85 kN32_SkColorType = kRGBA_8888_SkColorType, 86#else 87 #error "SK_*32_SHIFT values must correspond to BGRA or RGBA byte order" 88#endif 89}; 90 91/** 92 * Returns the number of bytes-per-pixel for the specified colortype, or 0 if invalid. 93 */ 94SK_API int SkColorTypeBytesPerPixel(SkColorType ct); 95 96/** 97 * Returns true iff the colortype is always considered opaque (i.e. does not store alpha). 98 */ 99SK_API bool SkColorTypeIsAlwaysOpaque(SkColorType ct); 100 101/** 102 * Tries to validate the colortype, alphatype pair. In all cases if it returns true, it 103 * will set canonical to the "canonical" answer if it is non-null, and ignore the parameter if 104 * it is set to null. 105 * 106 * If the specified colortype has only 1 valid alphatype (e.g. 565 must always be opaque) then 107 * canonical will be set to that valid alphatype. 108 * 109 * If the specified colortype treats more than one alphatype the same (e.g. Alpha_8 colortype 110 * treates Premul and Unpremul the same) and the specified alphatype is one of those, 111 * then canonical will be set to the "canonical" answer (Premul in the case of Alpha_8 colortype). 112 * 113 * If the colortype supports multiple alphatypes, and the specified alphatype is one of them, 114 * then canonical will be set to the specified alphatype. If the specified alphatype is not 115 * one of them (e.g. kUnknown_SkAlphaType is not valid for any colortype except 116 * kUnknown_SkColorType), then the function returns false, and canonical's value is undefined. 117 */ 118SK_API bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType, 119 SkAlphaType* canonical = nullptr); 120 121 122/////////////////////////////////////////////////////////////////////////////// 123 124/** 125 * Describes the color space a YUV pixel. 126 */ 127enum SkYUVColorSpace { 128 /** Standard JPEG color space. */ 129 kJPEG_SkYUVColorSpace, 130 /** SDTV standard Rec. 601 color space. Uses "studio swing" [16, 235] color 131 range. See http://en.wikipedia.org/wiki/Rec._601 for details. */ 132 kRec601_SkYUVColorSpace, 133 /** HDTV standard Rec. 709 color space. Uses "studio swing" [16, 235] color 134 range. See http://en.wikipedia.org/wiki/Rec._709 for details. */ 135 kRec709_SkYUVColorSpace, 136 137 kLastEnum_SkYUVColorSpace = kRec709_SkYUVColorSpace, 138}; 139 140/////////////////////////////////////////////////////////////////////////////// 141 142/** 143 * Describe an image's dimensions and pixel type. 144 * Used for both src images and render-targets (surfaces). 145 */ 146struct SK_API SkImageInfo { 147public: 148 SkImageInfo() 149 : fColorSpace(nullptr) 150 , fWidth(0) 151 , fHeight(0) 152 , fColorType(kUnknown_SkColorType) 153 , fAlphaType(kUnknown_SkAlphaType) 154 {} 155 156 static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at, 157 sk_sp<SkColorSpace> cs = nullptr) { 158 return SkImageInfo(width, height, ct, at, std::move(cs)); 159 } 160 161 /** 162 * Sets colortype to the native ARGB32 type. 163 */ 164 static SkImageInfo MakeN32(int width, int height, SkAlphaType at, 165 sk_sp<SkColorSpace> cs = nullptr) { 166 return Make(width, height, kN32_SkColorType, at, cs); 167 } 168 169 /** 170 * Create an ImageInfo marked as SRGB with N32 swizzle. 171 */ 172 static SkImageInfo MakeS32(int width, int height, SkAlphaType at); 173 174 /** 175 * Sets colortype to the native ARGB32 type, and the alphatype to premul. 176 */ 177 static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs = nullptr) { 178 return Make(width, height, kN32_SkColorType, kPremul_SkAlphaType, cs); 179 } 180 181 static SkImageInfo MakeN32Premul(const SkISize& size) { 182 return MakeN32Premul(size.width(), size.height()); 183 } 184 185 static SkImageInfo MakeA8(int width, int height) { 186 return Make(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr); 187 } 188 189 static SkImageInfo MakeUnknown(int width, int height) { 190 return Make(width, height, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr); 191 } 192 193 static SkImageInfo MakeUnknown() { 194 return MakeUnknown(0, 0); 195 } 196 197 int width() const { return fWidth; } 198 int height() const { return fHeight; } 199 SkColorType colorType() const { return fColorType; } 200 SkAlphaType alphaType() const { return fAlphaType; } 201 SkColorSpace* colorSpace() const { return fColorSpace.get(); } 202 sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; } 203 204 bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; } 205 206 bool isOpaque() const { 207 return SkAlphaTypeIsOpaque(fAlphaType); 208 } 209 210 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); } 211 SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); } 212 213 bool gammaCloseToSRGB() const { 214 return fColorSpace && fColorSpace->gammaCloseToSRGB(); 215 } 216 217 /** 218 * Return a new ImageInfo with the same colortype and alphatype as this info, 219 * but with the specified width and height. 220 */ 221 SkImageInfo makeWH(int newWidth, int newHeight) const { 222 return Make(newWidth, newHeight, fColorType, fAlphaType, fColorSpace); 223 } 224 225 SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const { 226 return Make(fWidth, fHeight, fColorType, newAlphaType, fColorSpace); 227 } 228 229 SkImageInfo makeColorType(SkColorType newColorType) const { 230 return Make(fWidth, fHeight, newColorType, fAlphaType, fColorSpace); 231 } 232 233 SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const { 234 return Make(fWidth, fHeight, fColorType, fAlphaType, std::move(cs)); 235 } 236 237 int bytesPerPixel() const; 238 int shiftPerPixel() const; 239 240 uint64_t minRowBytes64() const { 241 return sk_64_mul(fWidth, this->bytesPerPixel()); 242 } 243 244 size_t minRowBytes() const { 245 uint64_t minRowBytes = this->minRowBytes64(); 246 if (!sk_64_isS32(minRowBytes)) { 247 return 0; 248 } 249 return sk_64_asS32(minRowBytes); 250 } 251 252 size_t computeOffset(int x, int y, size_t rowBytes) const; 253 254 bool operator==(const SkImageInfo& other) const { 255 return fWidth == other.fWidth && fHeight == other.fHeight && 256 fColorType == other.fColorType && fAlphaType == other.fAlphaType && 257 SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get()); 258 } 259 bool operator!=(const SkImageInfo& other) const { 260 return !(*this == other); 261 } 262 263 void unflatten(SkReadBuffer& buffer); 264 void flatten(SkWriteBuffer& buffer) const; 265 266 /** 267 * Returns the size (in bytes) of the image buffer that this info needs, given the specified 268 * rowBytes. The rowBytes must be >= this->minRowBytes(). 269 * 270 * if (height == 0) { 271 * return 0; 272 * } else { 273 * return (height - 1) * rowBytes + width * bytes_per_pixel; 274 * } 275 * 276 * If the calculation overflows this returns SK_MaxSizeT 277 */ 278 size_t computeByteSize(size_t rowBytes) const; 279 280 /** 281 * Returns the minimum size (in bytes) of the image buffer that this info needs. 282 * If the calculation overflows, or if the height is 0, this returns 0. 283 */ 284 size_t computeMinByteSize() const { 285 return this->computeByteSize(this->minRowBytes()); 286 } 287 288 // Returns true if the result of computeByteSize (or computeMinByteSize) overflowed 289 static bool ByteSizeOverflowed(size_t byteSize) { 290 return SK_MaxSizeT == byteSize; 291 } 292 293 bool validRowBytes(size_t rowBytes) const { 294 uint64_t minRB = sk_64_mul(fWidth, this->bytesPerPixel()); 295 return rowBytes >= minRB; 296 } 297 298 void reset() { 299 fColorSpace = nullptr; 300 fWidth = 0; 301 fHeight = 0; 302 fColorType = kUnknown_SkColorType; 303 fAlphaType = kUnknown_SkAlphaType; 304 } 305 306 SkDEBUGCODE(void validate() const;) 307 308private: 309 sk_sp<SkColorSpace> fColorSpace; 310 int fWidth; 311 int fHeight; 312 SkColorType fColorType; 313 SkAlphaType fAlphaType; 314 315 SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs) 316 : fColorSpace(std::move(cs)) 317 , fWidth(width) 318 , fHeight(height) 319 , fColorType(ct) 320 , fAlphaType(at) 321 {} 322}; 323 324#endif 325