Home | History | Annotate | Download | only in codec
      1 /*
      2  * Copyright 2016 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 SkEncodedInfo_DEFINED
      9 #define SkEncodedInfo_DEFINED
     10 
     11 #include "SkImageInfo.h"
     12 
     13 class SkColorSpace;
     14 
     15 struct SkEncodedInfo {
     16 public:
     17 
     18     enum Alpha {
     19         kOpaque_Alpha,
     20         kUnpremul_Alpha,
     21 
     22         // Each pixel is either fully opaque or fully transparent.
     23         // There is no difference between requesting kPremul or kUnpremul.
     24         kBinary_Alpha,
     25     };
     26 
     27     /*
     28      * We strive to make the number of components per pixel obvious through
     29      * our naming conventions.
     30      * Ex: kRGB has 3 components.  kRGBA has 4 components.
     31      *
     32      * This sometimes results in redundant Alpha and Color information.
     33      * Ex: kRGB images must also be kOpaque.
     34      */
     35     enum Color {
     36         // PNG, WBMP
     37         kGray_Color,
     38 
     39         // PNG
     40         kGrayAlpha_Color,
     41 
     42         // PNG, GIF, BMP
     43         kPalette_Color,
     44 
     45         // PNG, RAW
     46         kRGB_Color,
     47         kRGBA_Color,
     48 
     49         // BMP
     50         kBGR_Color,
     51         kBGRX_Color,
     52         kBGRA_Color,
     53 
     54         // JPEG, WEBP
     55         kYUV_Color,
     56 
     57         // WEBP
     58         kYUVA_Color,
     59 
     60         // JPEG
     61         // Photoshop actually writes inverted CMYK data into JPEGs, where zero
     62         // represents 100% ink coverage.  For this reason, we treat CMYK JPEGs
     63         // as having inverted CMYK.  libjpeg-turbo warns that this may break
     64         // other applications, but the CMYK JPEGs we see on the web expect to
     65         // be treated as inverted CMYK.
     66         kInvertedCMYK_Color,
     67         kYCCK_Color,
     68     };
     69 
     70     static SkEncodedInfo Make(Color color, Alpha alpha, int bitsPerComponent) {
     71         SkASSERT(1 == bitsPerComponent ||
     72                  2 == bitsPerComponent ||
     73                  4 == bitsPerComponent ||
     74                  8 == bitsPerComponent ||
     75                  16 == bitsPerComponent);
     76 
     77         switch (color) {
     78             case kGray_Color:
     79                 SkASSERT(kOpaque_Alpha == alpha);
     80                 break;
     81             case kGrayAlpha_Color:
     82                 SkASSERT(kOpaque_Alpha != alpha);
     83                 break;
     84             case kPalette_Color:
     85                 SkASSERT(16 != bitsPerComponent);
     86                 break;
     87             case kRGB_Color:
     88             case kBGR_Color:
     89             case kBGRX_Color:
     90                 SkASSERT(kOpaque_Alpha == alpha);
     91                 SkASSERT(bitsPerComponent >= 8);
     92                 break;
     93             case kYUV_Color:
     94             case kInvertedCMYK_Color:
     95             case kYCCK_Color:
     96                 SkASSERT(kOpaque_Alpha == alpha);
     97                 SkASSERT(8 == bitsPerComponent);
     98                 break;
     99             case kRGBA_Color:
    100                 SkASSERT(kOpaque_Alpha != alpha);
    101                 SkASSERT(bitsPerComponent >= 8);
    102                 break;
    103             case kBGRA_Color:
    104             case kYUVA_Color:
    105                 SkASSERT(kOpaque_Alpha != alpha);
    106                 SkASSERT(8 == bitsPerComponent);
    107                 break;
    108             default:
    109                 SkASSERT(false);
    110                 break;
    111         }
    112 
    113         return SkEncodedInfo(color, alpha, bitsPerComponent);
    114     }
    115 
    116     /*
    117      * Returns an SkImageInfo with Skia color and alpha types that are the
    118      * closest possible match to the encoded info.
    119      */
    120     SkImageInfo makeImageInfo(int width, int height, sk_sp<SkColorSpace> colorSpace) const {
    121         switch (fColor) {
    122             case kGray_Color:
    123                 SkASSERT(kOpaque_Alpha == fAlpha);
    124                 return SkImageInfo::Make(width, height, kGray_8_SkColorType,
    125                                          kOpaque_SkAlphaType, colorSpace);
    126             case kGrayAlpha_Color:
    127                 SkASSERT(kOpaque_Alpha != fAlpha);
    128                 return SkImageInfo::Make(width, height, kN32_SkColorType,
    129                         kUnpremul_SkAlphaType, colorSpace);
    130             case kPalette_Color: {
    131                 SkAlphaType alphaType = (kOpaque_Alpha == fAlpha) ? kOpaque_SkAlphaType :
    132                         kUnpremul_SkAlphaType;
    133                 return SkImageInfo::Make(width, height, kIndex_8_SkColorType,
    134                                          alphaType, colorSpace);
    135             }
    136             case kRGB_Color:
    137             case kBGR_Color:
    138             case kBGRX_Color:
    139             case kYUV_Color:
    140             case kInvertedCMYK_Color:
    141             case kYCCK_Color:
    142                 SkASSERT(kOpaque_Alpha == fAlpha);
    143                 return SkImageInfo::Make(width, height, kN32_SkColorType,
    144                                          kOpaque_SkAlphaType, colorSpace);
    145             case kRGBA_Color:
    146             case kBGRA_Color:
    147             case kYUVA_Color:
    148                 SkASSERT(kOpaque_Alpha != fAlpha);
    149                 return SkImageInfo::Make(width, height, kN32_SkColorType,
    150                                          kUnpremul_SkAlphaType, std::move(colorSpace));
    151             default:
    152                 SkASSERT(false);
    153                 return SkImageInfo::MakeUnknown();
    154         }
    155     }
    156 
    157     Color color() const { return fColor; }
    158     Alpha alpha() const { return fAlpha; }
    159     uint8_t bitsPerComponent() const { return fBitsPerComponent; }
    160 
    161     uint8_t bitsPerPixel() const {
    162         switch (fColor) {
    163             case kGray_Color:
    164                 return fBitsPerComponent;
    165             case kGrayAlpha_Color:
    166                 return 2 * fBitsPerComponent;
    167             case kPalette_Color:
    168                 return fBitsPerComponent;
    169             case kRGB_Color:
    170             case kBGR_Color:
    171             case kYUV_Color:
    172                 return 3 * fBitsPerComponent;
    173             case kRGBA_Color:
    174             case kBGRA_Color:
    175             case kBGRX_Color:
    176             case kYUVA_Color:
    177             case kInvertedCMYK_Color:
    178             case kYCCK_Color:
    179                 return 4 * fBitsPerComponent;
    180             default:
    181                 SkASSERT(false);
    182                 return 0;
    183         }
    184     }
    185 
    186 private:
    187 
    188     SkEncodedInfo(Color color, Alpha alpha, uint8_t bitsPerComponent)
    189         : fColor(color)
    190         , fAlpha(alpha)
    191         , fBitsPerComponent(bitsPerComponent)
    192     {}
    193 
    194     Color   fColor;
    195     Alpha   fAlpha;
    196     uint8_t fBitsPerComponent;
    197 };
    198 
    199 #endif
    200