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 "include/core/SkColor.h" 12#include "include/core/SkICC.h" 13#include "include/core/SkTypes.h" 14#include "include/private/SkColorData.h" 15#include "include/third_party/skcms/skcms.h" 16 17typedef void (*transform_scanline_proc)(char* dst, const char* src, int width, int bpp); 18 19static inline void transform_scanline_memcpy(char* dst, const char* src, int width, int bpp) { 20 memcpy(dst, src, width * bpp); 21} 22 23static 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 31static 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 38static 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 44static 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 50static 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 56static 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 62static 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 68static 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 74static 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 80static 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 86static 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 92static 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 98static 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 104static 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 110static 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 116static inline void transform_scanline_bgr_101010x(char* dst, const char* src, int width, int) { 117 skcms(dst, src, width, 118 skcms_PixelFormat_BGRA_1010102, skcms_AlphaFormat_Unpremul, 119 skcms_PixelFormat_RGB_161616BE, skcms_AlphaFormat_Unpremul); 120} 121 122static inline void transform_scanline_bgra_1010102(char* dst, const char* src, int width, int) { 123 skcms(dst, src, width, 124 skcms_PixelFormat_BGRA_1010102, skcms_AlphaFormat_Unpremul, 125 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); 126} 127 128static inline void transform_scanline_bgra_1010102_premul(char* dst, const char* src, int width, int) { 129 skcms(dst, src, width, 130 skcms_PixelFormat_BGRA_1010102, skcms_AlphaFormat_PremulAsEncoded, 131 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); 132} 133 134static inline void transform_scanline_F16(char* dst, const char* src, int width, int) { 135 skcms(dst, src, width, 136 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul, 137 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); 138} 139 140static inline void transform_scanline_F16_premul(char* dst, const char* src, int width, int) { 141 skcms(dst, src, width, 142 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded, 143 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); 144} 145 146static inline void transform_scanline_F16_to_8888(char* dst, const char* src, int width, int) { 147 skcms(dst, src, width, 148 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul, 149 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul); 150} 151 152static inline void transform_scanline_F16_premul_to_8888(char* dst, 153 const char* src, 154 int width, 155 int) { 156 skcms(dst, src, width, 157 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded, 158 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul); 159} 160 161static inline void transform_scanline_F16_to_premul_8888(char* dst, 162 const char* src, 163 int width, 164 int) { 165 skcms(dst, src, width, 166 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul, 167 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded); 168} 169 170static inline void transform_scanline_F32(char* dst, const char* src, int width, int) { 171 skcms(dst, src, width, 172 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_Unpremul, 173 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); 174} 175 176static inline void transform_scanline_F32_premul(char* dst, const char* src, int width, int) { 177 skcms(dst, src, width, 178 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_PremulAsEncoded, 179 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); 180} 181 182static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) { 183 SkColorSpace* cs = info.colorSpace(); 184 if (!cs) { 185 return nullptr; 186 } 187 188 skcms_TransferFunction fn; 189 skcms_Matrix3x3 toXYZD50; 190 cs->transferFn(&fn); 191 if (cs->toXYZD50(&toXYZD50)) { 192 skcms_CICP cicp{}; 193 if (cs->GetIccCicp(&cicp)) { 194 return SkWriteICCProfileWithCicp(fn, toXYZD50, cicp); 195 } 196 return SkWriteICCProfile(fn, toXYZD50); 197 } 198 return nullptr; 199} 200 201#endif // SkImageEncoderFns_DEFINED 202