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 kN32_SkColorType = kBGRA_8888_SkColorType, 84#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 85 kN32_SkColorType = kRGBA_8888_SkColorType, 86#else 87#error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order" 88#endif 89 90#ifdef SK_SUPPORT_LEGACY_N32_NAME 91 kPMColor_SkColorType = kN32_SkColorType 92#endif 93}; 94 95static int SkColorTypeBytesPerPixel(SkColorType ct) { 96 static const uint8_t gSize[] = { 97 0, // Unknown 98 1, // Alpha_8 99 2, // RGB_565 100 2, // ARGB_4444 101 4, // RGBA_8888 102 4, // BGRA_8888 103 1, // kIndex_8 104 }; 105 SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1), 106 size_mismatch_with_SkColorType_enum); 107 108 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gSize)); 109 return gSize[ct]; 110} 111 112static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) { 113 return width * SkColorTypeBytesPerPixel(ct); 114} 115 116static inline bool SkColorTypeIsValid(unsigned value) { 117 return value <= kLastEnum_SkColorType; 118} 119 120/////////////////////////////////////////////////////////////////////////////// 121 122/** 123 * Describe an image's dimensions and pixel type. 124 */ 125struct SkImageInfo { 126 int fWidth; 127 int fHeight; 128 SkColorType fColorType; 129 SkAlphaType fAlphaType; 130 131 static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at) { 132 SkImageInfo info = { 133 width, height, ct, at 134 }; 135 return info; 136 } 137 138 /** 139 * Sets colortype to the native ARGB32 type. 140 */ 141 static SkImageInfo MakeN32(int width, int height, SkAlphaType at) { 142 SkImageInfo info = { 143 width, height, kN32_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 SkImageInfo info = { 153 width, height, kN32_SkColorType, kPremul_SkAlphaType 154 }; 155 return info; 156 } 157 158 /** 159 * Sets colortype to the native ARGB32 type, and the alphatype to premul. 160 */ 161 static SkImageInfo MakeN32Premul(const SkISize& size) { 162 return MakeN32Premul(size.width(), size.height()); 163 } 164 165 static SkImageInfo MakeA8(int width, int height) { 166 SkImageInfo info = { 167 width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType 168 }; 169 return info; 170 } 171 172 static SkImageInfo MakeUnknown(int width, int height) { 173 SkImageInfo info = { 174 width, height, kUnknown_SkColorType, kIgnore_SkAlphaType 175 }; 176 return info; 177 } 178 179 static SkImageInfo MakeUnknown() { 180 SkImageInfo info = { 181 0, 0, kUnknown_SkColorType, kIgnore_SkAlphaType 182 }; 183 return info; 184 } 185 186 int width() const { return fWidth; } 187 int height() const { return fHeight; } 188 SkColorType colorType() const { return fColorType; } 189 SkAlphaType alphaType() const { return fAlphaType; } 190 191 bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; } 192 193 bool isOpaque() const { 194 return SkAlphaTypeIsOpaque(fAlphaType); 195 } 196 197 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); } 198 199 /** 200 * Return a new ImageInfo with the same colortype and alphatype as this info, 201 * but with the specified width and height. 202 */ 203 SkImageInfo makeWH(int newWidth, int newHeight) const { 204 return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType); 205 } 206 207 int bytesPerPixel() const { 208 return SkColorTypeBytesPerPixel(fColorType); 209 } 210 211 uint64_t minRowBytes64() const { 212 return sk_64_mul(fWidth, this->bytesPerPixel()); 213 } 214 215 size_t minRowBytes() const { 216 return (size_t)this->minRowBytes64(); 217 } 218 219 bool operator==(const SkImageInfo& other) const { 220 return 0 == memcmp(this, &other, sizeof(other)); 221 } 222 bool operator!=(const SkImageInfo& other) const { 223 return 0 != memcmp(this, &other, sizeof(other)); 224 } 225 226 void unflatten(SkReadBuffer&); 227 void flatten(SkWriteBuffer&) const; 228 229 int64_t getSafeSize64(size_t rowBytes) const { 230 if (0 == fHeight) { 231 return 0; 232 } 233 return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel(); 234 } 235 236 size_t getSafeSize(size_t rowBytes) const { 237 return (size_t)this->getSafeSize64(rowBytes); 238 } 239 240 bool validRowBytes(size_t rowBytes) const { 241 uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel()); 242 return rowBytes >= rb; 243 } 244 245 SkDEBUGCODE(void validate() const;) 246}; 247 248#endif 249