Home | History | Annotate | Download | only in core
      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