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