SkImageInfo.h revision 61e96cd44624c9faceb625519c1b29775b161f45
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 */ 71enum SkColorType { 72 kUnknown_SkColorType, 73 kAlpha_8_SkColorType, 74 kRGB_565_SkColorType, 75 kARGB_4444_SkColorType, 76 kRGBA_8888_SkColorType, 77 kBGRA_8888_SkColorType, 78 kIndex_8_SkColorType, 79 80 kLastEnum_SkColorType = kIndex_8_SkColorType, 81 82#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) 83 kPMColor_SkColorType = kBGRA_8888_SkColorType 84#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 85 kPMColor_SkColorType = kRGBA_8888_SkColorType 86#else 87#error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order" 88#endif 89}; 90 91static int SkColorTypeBytesPerPixel(SkColorType ct) { 92 static const uint8_t gSize[] = { 93 0, // Unknown 94 1, // Alpha_8 95 2, // RGB_565 96 2, // ARGB_4444 97 4, // RGBA_8888 98 4, // BGRA_8888 99 1, // kIndex_8 100 }; 101 SK_COMPILE_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 108static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) { 109 return width * SkColorTypeBytesPerPixel(ct); 110} 111 112static inline bool SkColorTypeIsValid(unsigned value) { 113 return value <= kLastEnum_SkColorType; 114} 115 116/////////////////////////////////////////////////////////////////////////////// 117 118/** 119 * Describe an image's dimensions and pixel type. 120 */ 121struct SkImageInfo { 122 int fWidth; 123 int fHeight; 124 SkColorType fColorType; 125 SkAlphaType fAlphaType; 126 127 static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at) { 128 SkASSERT(width >= 0); 129 SkASSERT(height >= 0); 130 SkImageInfo info = { 131 width, height, ct, at 132 }; 133 return info; 134 } 135 136 /** 137 * Sets colortype to the native ARGB32 type. 138 */ 139 static SkImageInfo MakeN32(int width, int height, SkAlphaType at) { 140 SkASSERT(width >= 0); 141 SkASSERT(height >= 0); 142 SkImageInfo info = { 143 width, height, kPMColor_SkColorType, at 144 }; 145 return info; 146 } 147 148 /** 149 * Sets colortype to the native ARGB32 type, and the alphatype to premul. 150 */ 151 static SkImageInfo MakeN32Premul(int width, int height) { 152 SkASSERT(width >= 0); 153 SkASSERT(height >= 0); 154 SkImageInfo info = { 155 width, height, kPMColor_SkColorType, kPremul_SkAlphaType 156 }; 157 return info; 158 } 159 160 /** 161 * Sets colortype to the native ARGB32 type, and the alphatype to premul. 162 */ 163 static SkImageInfo MakeN32Premul(const SkISize& size) { 164 return MakeN32Premul(size.width(), size.height()); 165 } 166 167 static SkImageInfo MakeA8(int width, int height) { 168 SkASSERT(width >= 0); 169 SkASSERT(height >= 0); 170 SkImageInfo info = { 171 width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType 172 }; 173 return info; 174 } 175 176 int width() const { return fWidth; } 177 int height() const { return fHeight; } 178 SkColorType colorType() const { return fColorType; } 179 SkAlphaType alphaType() const { return fAlphaType; } 180 181 bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; } 182 183 bool isOpaque() const { 184 return SkAlphaTypeIsOpaque(fAlphaType); 185 } 186 187 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); } 188 189 int bytesPerPixel() const { 190 return SkColorTypeBytesPerPixel(fColorType); 191 } 192 193 uint64_t minRowBytes64() const { 194 return sk_64_mul(fWidth, this->bytesPerPixel()); 195 } 196 197 size_t minRowBytes() const { 198 return (size_t)this->minRowBytes64(); 199 } 200 201 bool operator==(const SkImageInfo& other) const { 202 return 0 == memcmp(this, &other, sizeof(other)); 203 } 204 bool operator!=(const SkImageInfo& other) const { 205 return 0 != memcmp(this, &other, sizeof(other)); 206 } 207 208 void unflatten(SkReadBuffer&); 209 void flatten(SkWriteBuffer&) const; 210 211 int64_t getSafeSize64(size_t rowBytes) const { 212 if (0 == fHeight) { 213 return 0; 214 } 215 return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel(); 216 } 217 218 size_t getSafeSize(size_t rowBytes) const { 219 return (size_t)this->getSafeSize64(rowBytes); 220 } 221 222 bool validRowBytes(size_t rowBytes) const { 223 uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel()); 224 return rowBytes >= rb; 225 } 226 227 SkDEBUGCODE(void validate() const;) 228}; 229 230#endif 231