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
17 typedef void (*transform_scanline_proc)(char* dst, const char* src, int width, int bpp);
18
transform_scanline_memcpy(char * dst,const char * src,int width,int bpp)19 static inline void transform_scanline_memcpy(char* dst, const char* src, int width, int bpp) {
20 memcpy(dst, src, width * bpp);
21 }
22
transform_scanline_A8_to_GrayAlpha(char * dst,const char * src,int width,int)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
skcms(char * dst,const char * src,int n,skcms_PixelFormat srcFmt,skcms_AlphaFormat srcAlpha,skcms_PixelFormat dstFmt,skcms_AlphaFormat dstAlpha)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
transform_scanline_gray(char * dst,const char * src,int width,int)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
transform_scanline_565(char * dst,const char * src,int width,int)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
transform_scanline_RGBX(char * dst,const char * src,int width,int)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
transform_scanline_BGRX(char * dst,const char * src,int width,int)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
transform_scanline_444(char * dst,const char * src,int width,int)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
transform_scanline_rgbA(char * dst,const char * src,int width,int)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
transform_scanline_bgrA(char * dst,const char * src,int width,int)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
transform_scanline_to_premul_legacy(char * dst,const char * src,int width,int)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
transform_scanline_BGRA(char * dst,const char * src,int width,int)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
transform_scanline_4444(char * dst,const char * src,int width,int)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
transform_scanline_101010x(char * dst,const char * src,int width,int)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
transform_scanline_1010102(char * dst,const char * src,int width,int)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
transform_scanline_1010102_premul(char * dst,const char * src,int width,int)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
transform_scanline_bgr_101010x(char * dst,const char * src,int width,int)116 static 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
transform_scanline_bgra_1010102(char * dst,const char * src,int width,int)122 static 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
transform_scanline_bgra_1010102_premul(char * dst,const char * src,int width,int)128 static 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
transform_scanline_F16(char * dst,const char * src,int width,int)134 static 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
transform_scanline_F16_premul(char * dst,const char * src,int width,int)140 static 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
transform_scanline_F16_to_8888(char * dst,const char * src,int width,int)146 static 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
transform_scanline_F16_premul_to_8888(char * dst,const char * src,int width,int)152 static 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
transform_scanline_F16_to_premul_8888(char * dst,const char * src,int width,int)161 static 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
transform_scanline_F32(char * dst,const char * src,int width,int)170 static 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
transform_scanline_F32_premul(char * dst,const char * src,int width,int)176 static 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
icc_from_color_space(const SkImageInfo & info)182 static 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 if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {
191 return SkWriteICCProfile(fn, toXYZD50);
192 }
193 return nullptr;
194 }
195
196 #endif // SkImageEncoderFns_DEFINED
197