Home | History | Annotate | Download | only in images
      1 /*
      2  * Copyright 2012 The Android Open Source Project
      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 SkImageEncoderFns_DEFINED
      9 #define SkImageEncoderFns_DEFINED
     10 
     11 #include "../../third_party/skcms/skcms.h"
     12 #include "SkColor.h"
     13 #include "SkColorData.h"
     14 #include "SkICC.h"
     15 #include "SkTypes.h"
     16 
     17 typedef void (*transform_scanline_proc)(char* dst, const char* src, int width, int bpp);
     18 
     19 static inline void transform_scanline_memcpy(char* dst, const char* src, int width, int bpp) {
     20     memcpy(dst, src, width * bpp);
     21 }
     22 
     23 static inline void transform_scanline_A8_to_GrayAlpha(char* dst, const char* src, int width, int) {
     24     for (int i = 0; i < width; i++) {
     25         *dst++ = 0;
     26         *dst++ = *src++;
     27     }
     28 }
     29 
     30 
     31 static void skcms(char* dst, const char* src, int n,
     32                   skcms_PixelFormat srcFmt, skcms_AlphaFormat srcAlpha,
     33                   skcms_PixelFormat dstFmt, skcms_AlphaFormat dstAlpha) {
     34     SkAssertResult(skcms_Transform(src, srcFmt, srcAlpha, nullptr,
     35                                    dst, dstFmt, dstAlpha, nullptr, n));
     36 }
     37 
     38 static inline void transform_scanline_gray(char* dst, const char* src, int width, int) {
     39     skcms(dst, src, width,
     40           skcms_PixelFormat_G_8,     skcms_AlphaFormat_Unpremul,
     41           skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Unpremul);
     42 }
     43 
     44 static inline void transform_scanline_565(char* dst, const char* src, int width, int) {
     45     skcms(dst, src, width,
     46           skcms_PixelFormat_BGR_565, skcms_AlphaFormat_Unpremul,
     47           skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Unpremul);
     48 }
     49 
     50 static inline void transform_scanline_RGBX(char* dst, const char* src, int width, int) {
     51     skcms(dst, src, width,
     52           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul,
     53           skcms_PixelFormat_RGB_888  , skcms_AlphaFormat_Unpremul);
     54 }
     55 
     56 static inline void transform_scanline_BGRX(char* dst, const char* src, int width, int) {
     57     skcms(dst, src, width,
     58           skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_Unpremul,
     59           skcms_PixelFormat_RGB_888  , skcms_AlphaFormat_Unpremul);
     60 }
     61 
     62 static inline void transform_scanline_444(char* dst, const char* src, int width, int) {
     63     skcms(dst, src, width,
     64           skcms_PixelFormat_ABGR_4444, skcms_AlphaFormat_Unpremul,
     65           skcms_PixelFormat_RGB_888  , skcms_AlphaFormat_Unpremul);
     66 }
     67 
     68 static inline void transform_scanline_rgbA(char* dst, const char* src, int width, int) {
     69     skcms(dst, src, width,
     70           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded,
     71           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
     72 }
     73 
     74 static inline void transform_scanline_bgrA(char* dst, const char* src, int width, int) {
     75     skcms(dst, src, width,
     76           skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_PremulAsEncoded,
     77           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
     78 }
     79 
     80 static inline void transform_scanline_to_premul_legacy(char* dst, const char* src, int width, int) {
     81     skcms(dst, src, width,
     82           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul,
     83           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded);
     84 }
     85 
     86 static inline void transform_scanline_BGRA(char* dst, const char* src, int width, int) {
     87     skcms(dst, src, width,
     88           skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_Unpremul,
     89           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
     90 }
     91 
     92 static inline void transform_scanline_4444(char* dst, const char* src, int width, int) {
     93     skcms(dst, src, width,
     94           skcms_PixelFormat_ABGR_4444, skcms_AlphaFormat_PremulAsEncoded,
     95           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
     96 }
     97 
     98 static inline void transform_scanline_101010x(char* dst, const char* src, int width, int) {
     99     skcms(dst, src, width,
    100           skcms_PixelFormat_RGBA_1010102, skcms_AlphaFormat_Unpremul,
    101           skcms_PixelFormat_RGB_161616BE, skcms_AlphaFormat_Unpremul);
    102 }
    103 
    104 static inline void transform_scanline_1010102(char* dst, const char* src, int width, int) {
    105     skcms(dst, src, width,
    106           skcms_PixelFormat_RGBA_1010102,    skcms_AlphaFormat_Unpremul,
    107           skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
    108 }
    109 
    110 static inline void transform_scanline_1010102_premul(char* dst, const char* src, int width, int) {
    111     skcms(dst, src, width,
    112           skcms_PixelFormat_RGBA_1010102,    skcms_AlphaFormat_PremulAsEncoded,
    113           skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
    114 }
    115 
    116 static inline void transform_scanline_F16(char* dst, const char* src, int width, int) {
    117     skcms(dst, src, width,
    118           skcms_PixelFormat_RGBA_hhhh,       skcms_AlphaFormat_Unpremul,
    119           skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
    120 }
    121 
    122 static inline void transform_scanline_F16_premul(char* dst, const char* src, int width, int) {
    123     skcms(dst, src, width,
    124           skcms_PixelFormat_RGBA_hhhh,       skcms_AlphaFormat_PremulAsEncoded,
    125           skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
    126 }
    127 
    128 static inline void transform_scanline_F16_to_8888(char* dst, const char* src, int width, int) {
    129     skcms(dst, src, width,
    130           skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
    131           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
    132 }
    133 
    134 static inline void transform_scanline_F16_premul_to_8888(char* dst,
    135                                                          const char* src,
    136                                                          int width,
    137                                                          int) {
    138     skcms(dst, src, width,
    139           skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
    140           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
    141 }
    142 
    143 static inline void transform_scanline_F16_to_premul_8888(char* dst,
    144                                                          const char* src,
    145                                                          int width,
    146                                                          int) {
    147     skcms(dst, src, width,
    148           skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
    149           skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded);
    150 }
    151 
    152 static inline void transform_scanline_F32(char* dst, const char* src, int width, int) {
    153     skcms(dst, src, width,
    154           skcms_PixelFormat_RGBA_ffff,       skcms_AlphaFormat_Unpremul,
    155           skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
    156 }
    157 
    158 static inline void transform_scanline_F32_premul(char* dst, const char* src, int width, int) {
    159     skcms(dst, src, width,
    160           skcms_PixelFormat_RGBA_ffff,       skcms_AlphaFormat_PremulAsEncoded,
    161           skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
    162 }
    163 
    164 static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
    165     SkColorSpace* cs = info.colorSpace();
    166     if (!cs) {
    167         return nullptr;
    168     }
    169 
    170     skcms_TransferFunction fn;
    171     skcms_Matrix3x3 toXYZD50;
    172     if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {
    173         return SkWriteICCProfile(fn, toXYZD50);
    174     }
    175     return nullptr;
    176 }
    177 
    178 #endif  // SkImageEncoderFns_DEFINED
    179