Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2017 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 SkImageInfoPriv_DEFINED
      9 #define SkImageInfoPriv_DEFINED
     10 
     11 #include "SkImageInfo.h"
     12 
     13 /**
     14  *  Returns true if |info| contains a valid combination of width, height, colorType, alphaType,
     15  *  colorSpace.  Returns false otherwise.
     16  */
     17 static inline bool SkImageInfoIsValid(const SkImageInfo& info) {
     18     if (info.width() <= 0 || info.height() <= 0) {
     19         return false;
     20     }
     21 
     22     const int kMaxDimension = SK_MaxS32 >> 2;
     23     if (info.width() > kMaxDimension || info.height() > kMaxDimension) {
     24         return false;
     25     }
     26 
     27     if (kUnknown_SkColorType == info.colorType() || kUnknown_SkAlphaType == info.alphaType()) {
     28         return false;
     29     }
     30 
     31     if (kOpaque_SkAlphaType != info.alphaType() &&
     32        (kRGB_565_SkColorType == info.colorType() || kGray_8_SkColorType == info.colorType())) {
     33         return false;
     34     }
     35 
     36     if (kRGBA_F16_SkColorType == info.colorType() &&
     37        (!info.colorSpace() || !info.colorSpace()->gammaIsLinear())) {
     38         return false;
     39     }
     40 
     41     if (info.colorSpace() &&
     42        (!info.colorSpace()->gammaCloseToSRGB() && !info.colorSpace()->gammaIsLinear())) {
     43         return false;
     44     }
     45 
     46     return true;
     47 }
     48 
     49 /**
     50  *  Returns true if Skia has defined a pixel conversion from the |src| to the |dst|.
     51  *  Returns false otherwise.  Some discussion of false cases:
     52  *      We will not convert to kIndex8 unless it exactly matches the src, since color tables
     53  *      are immutable.
     54  *      We do not convert to kGray8 when the |src| is not kGray8 in the same color space.
     55  *      We may add this feature - it just requires some work to convert to luminance while
     56  *      handling color spaces correctly.  Currently no one is asking for this.
     57  *      We will not convert from kAlpha8 when the |dst| is not kAlpha8.  This would require
     58  *      inventing color information.
     59  *      We will not convert to kOpaque when the |src| is not kOpaque.  This could be
     60  *      implemented to set all the alpha values to 1, but there is still some ambiguity -
     61  *      should we use kPremul or kUnpremul color values with the opaque alphas?  Or should
     62  *      we just use whatever the |src| alpha is?  In the future, we could choose to clearly
     63  *      define this, but currently no one is asking for this feature.
     64  *      We will not convert to a particular color space if |src| is nullptr.  The color space
     65  *      conversion is not well-defined.
     66  */
     67 static inline bool SkImageInfoValidConversion(const SkImageInfo& dst, const SkImageInfo& src) {
     68     if (!SkImageInfoIsValid(dst) || !SkImageInfoIsValid(src)) {
     69         return false;
     70     }
     71 
     72     if (kIndex_8_SkColorType == dst.colorType()) {
     73         if (kIndex_8_SkColorType != src.colorType()) {
     74             return false;
     75         }
     76 
     77         if ((kPremul_SkAlphaType == dst.alphaType() && kUnpremul_SkAlphaType == src.alphaType()) ||
     78             (kUnpremul_SkAlphaType == dst.alphaType() && kPremul_SkAlphaType == src.alphaType()))
     79         {
     80             return false;
     81         }
     82 
     83         if (dst.colorSpace() && !SkColorSpace::Equals(dst.colorSpace(), src.colorSpace())) {
     84             return false;
     85         }
     86     }
     87 
     88     if (kGray_8_SkColorType == dst.colorType()) {
     89         if (kGray_8_SkColorType != src.colorType()) {
     90             return false;
     91         }
     92 
     93         if (dst.colorSpace() && !SkColorSpace::Equals(dst.colorSpace(), src.colorSpace())) {
     94             return false;
     95         }
     96     }
     97 
     98     if (kAlpha_8_SkColorType != dst.colorType() && kAlpha_8_SkColorType == src.colorType()) {
     99         return false;
    100     }
    101 
    102     if (kOpaque_SkAlphaType == dst.alphaType() && kOpaque_SkAlphaType != src.alphaType()) {
    103         return false;
    104     }
    105 
    106     if (dst.colorSpace() && !src.colorSpace()) {
    107         return false;
    108     }
    109 
    110     return true;
    111 }
    112 #endif  // SkImageInfoPriv_DEFINED
    113