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