SkImageInfo.h revision b44c1895afae516cb851cd1a0cea83343c354ee4
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 14class SkWriteBuffer; 15class SkReadBuffer; 16 17/** 18 * Describes how to interpret the alpha compoent of a pixel. 19 */ 20enum 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 54static 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 62static 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 */ 75enum 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 99static 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 116static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) { 117 return width * SkColorTypeBytesPerPixel(ct); 118} 119 120static 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 */ 130bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType, 131 SkAlphaType* canonical = NULL); 132 133/////////////////////////////////////////////////////////////////////////////// 134 135/** 136 * Describe an image's dimensions and pixel type. 137 */ 138struct SkImageInfo { 139 int fWidth; 140 int fHeight; 141 SkColorType fColorType; 142 SkAlphaType fAlphaType; 143 144 static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at) { 145 SkImageInfo info = { 146 width, height, ct, at 147 }; 148 return info; 149 } 150 151 /** 152 * Sets colortype to the native ARGB32 type. 153 */ 154 static SkImageInfo MakeN32(int width, int height, SkAlphaType at) { 155 SkImageInfo info = { 156 width, height, kN32_SkColorType, at 157 }; 158 return info; 159 } 160 161 /** 162 * Sets colortype to the native ARGB32 type, and the alphatype to premul. 163 */ 164 static SkImageInfo MakeN32Premul(int width, int height) { 165 SkImageInfo info = { 166 width, height, kN32_SkColorType, kPremul_SkAlphaType 167 }; 168 return info; 169 } 170 171 /** 172 * Sets colortype to the native ARGB32 type, and the alphatype to premul. 173 */ 174 static SkImageInfo MakeN32Premul(const SkISize& size) { 175 return MakeN32Premul(size.width(), size.height()); 176 } 177 178 static SkImageInfo MakeA8(int width, int height) { 179 SkImageInfo info = { 180 width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType 181 }; 182 return info; 183 } 184 185 static SkImageInfo MakeUnknown(int width, int height) { 186 SkImageInfo info = { 187 width, height, kUnknown_SkColorType, kIgnore_SkAlphaType 188 }; 189 return info; 190 } 191 192 static SkImageInfo MakeUnknown() { 193 SkImageInfo info = { 194 0, 0, kUnknown_SkColorType, kIgnore_SkAlphaType 195 }; 196 return info; 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 int bytesPerPixel() const { 221 return SkColorTypeBytesPerPixel(fColorType); 222 } 223 224 uint64_t minRowBytes64() const { 225 return sk_64_mul(fWidth, this->bytesPerPixel()); 226 } 227 228 size_t minRowBytes() const { 229 return (size_t)this->minRowBytes64(); 230 } 231 232 bool operator==(const SkImageInfo& other) const { 233 return 0 == memcmp(this, &other, sizeof(other)); 234 } 235 bool operator!=(const SkImageInfo& other) const { 236 return 0 != memcmp(this, &other, sizeof(other)); 237 } 238 239 void unflatten(SkReadBuffer&); 240 void flatten(SkWriteBuffer&) const; 241 242 int64_t getSafeSize64(size_t rowBytes) const { 243 if (0 == fHeight) { 244 return 0; 245 } 246 return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel(); 247 } 248 249 size_t getSafeSize(size_t rowBytes) const { 250 return (size_t)this->getSafeSize64(rowBytes); 251 } 252 253 bool validRowBytes(size_t rowBytes) const { 254 uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel()); 255 return rowBytes >= rb; 256 } 257 258 SkDEBUGCODE(void validate() const;) 259}; 260 261#endif 262