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