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/SkColorSpace.h"
12 #include "include/core/SkData.h"
13 #include "include/core/SkImageInfo.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkTypes.h"
16 #include "include/encode/SkICC.h"
17 #include "modules/skcms/skcms.h"
18
19 #include <cstring>
20
21 typedef void (*transform_scanline_proc)(char* dst, const char* src, int width, int bpp);
22
transform_scanline_memcpy(char * dst,const char * src,int width,int bpp)23 static inline void transform_scanline_memcpy(char* dst, const char* src, int width, int bpp) {
24 memcpy(dst, src, width * bpp);
25 }
26
transform_scanline_A8_to_GrayAlpha(char * dst,const char * src,int width,int)27 static inline void transform_scanline_A8_to_GrayAlpha(char* dst, const char* src, int width, int) {
28 for (int i = 0; i < width; i++) {
29 *dst++ = 0;
30 *dst++ = *src++;
31 }
32 }
33
34
skcms(char * dst,const char * src,int n,skcms_PixelFormat srcFmt,skcms_AlphaFormat srcAlpha,skcms_PixelFormat dstFmt,skcms_AlphaFormat dstAlpha)35 static void skcms(char* dst, const char* src, int n,
36 skcms_PixelFormat srcFmt, skcms_AlphaFormat srcAlpha,
37 skcms_PixelFormat dstFmt, skcms_AlphaFormat dstAlpha) {
38 SkAssertResult(skcms_Transform(src, srcFmt, srcAlpha, nullptr,
39 dst, dstFmt, dstAlpha, nullptr, n));
40 }
41
transform_scanline_gray(char * dst,const char * src,int width,int)42 static inline void transform_scanline_gray(char* dst, const char* src, int width, int) {
43 skcms(dst, src, width,
44 skcms_PixelFormat_G_8, skcms_AlphaFormat_Unpremul,
45 skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Unpremul);
46 }
47
transform_scanline_565(char * dst,const char * src,int width,int)48 static inline void transform_scanline_565(char* dst, const char* src, int width, int) {
49 skcms(dst, src, width,
50 skcms_PixelFormat_BGR_565, skcms_AlphaFormat_Unpremul,
51 skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Unpremul);
52 }
53
transform_scanline_RGBX(char * dst,const char * src,int width,int)54 static inline void transform_scanline_RGBX(char* dst, const char* src, int width, int) {
55 skcms(dst, src, width,
56 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul,
57 skcms_PixelFormat_RGB_888 , skcms_AlphaFormat_Unpremul);
58 }
59
transform_scanline_BGRX(char * dst,const char * src,int width,int)60 static inline void transform_scanline_BGRX(char* dst, const char* src, int width, int) {
61 skcms(dst, src, width,
62 skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_Unpremul,
63 skcms_PixelFormat_RGB_888 , skcms_AlphaFormat_Unpremul);
64 }
65
transform_scanline_444(char * dst,const char * src,int width,int)66 static inline void transform_scanline_444(char* dst, const char* src, int width, int) {
67 skcms(dst, src, width,
68 skcms_PixelFormat_ABGR_4444, skcms_AlphaFormat_Unpremul,
69 skcms_PixelFormat_RGB_888 , skcms_AlphaFormat_Unpremul);
70 }
71
transform_scanline_rgbA(char * dst,const char * src,int width,int)72 static inline void transform_scanline_rgbA(char* dst, const char* src, int width, int) {
73 skcms(dst, src, width,
74 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded,
75 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
76 }
77
transform_scanline_bgrA(char * dst,const char * src,int width,int)78 static inline void transform_scanline_bgrA(char* dst, const char* src, int width, int) {
79 skcms(dst, src, width,
80 skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_PremulAsEncoded,
81 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
82 }
83
transform_scanline_to_premul_legacy(char * dst,const char * src,int width,int)84 static inline void transform_scanline_to_premul_legacy(char* dst, const char* src, int width, int) {
85 skcms(dst, src, width,
86 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul,
87 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded);
88 }
89
transform_scanline_BGRA(char * dst,const char * src,int width,int)90 static inline void transform_scanline_BGRA(char* dst, const char* src, int width, int) {
91 skcms(dst, src, width,
92 skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_Unpremul,
93 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
94 }
95
transform_scanline_4444(char * dst,const char * src,int width,int)96 static inline void transform_scanline_4444(char* dst, const char* src, int width, int) {
97 skcms(dst, src, width,
98 skcms_PixelFormat_ABGR_4444, skcms_AlphaFormat_PremulAsEncoded,
99 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
100 }
101
transform_scanline_101010x(char * dst,const char * src,int width,int)102 static inline void transform_scanline_101010x(char* dst, const char* src, int width, int) {
103 skcms(dst, src, width,
104 skcms_PixelFormat_RGBA_1010102, skcms_AlphaFormat_Unpremul,
105 skcms_PixelFormat_RGB_161616BE, skcms_AlphaFormat_Unpremul);
106 }
107
transform_scanline_1010102(char * dst,const char * src,int width,int)108 static inline void transform_scanline_1010102(char* dst, const char* src, int width, int) {
109 skcms(dst, src, width,
110 skcms_PixelFormat_RGBA_1010102, skcms_AlphaFormat_Unpremul,
111 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
112 }
113
transform_scanline_1010102_premul(char * dst,const char * src,int width,int)114 static inline void transform_scanline_1010102_premul(char* dst, const char* src, int width, int) {
115 skcms(dst, src, width,
116 skcms_PixelFormat_RGBA_1010102, skcms_AlphaFormat_PremulAsEncoded,
117 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
118 }
119
transform_scanline_bgr_101010x(char * dst,const char * src,int width,int)120 static inline void transform_scanline_bgr_101010x(char* dst, const char* src, int width, int) {
121 skcms(dst, src, width,
122 skcms_PixelFormat_BGRA_1010102, skcms_AlphaFormat_Unpremul,
123 skcms_PixelFormat_RGB_161616BE, skcms_AlphaFormat_Unpremul);
124 }
125
transform_scanline_bgra_1010102(char * dst,const char * src,int width,int)126 static inline void transform_scanline_bgra_1010102(char* dst, const char* src, int width, int) {
127 skcms(dst, src, width,
128 skcms_PixelFormat_BGRA_1010102, skcms_AlphaFormat_Unpremul,
129 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
130 }
131
transform_scanline_bgr_101010x_xr(char * dst,const char * src,int width,int)132 static inline void transform_scanline_bgr_101010x_xr(char* dst, const char* src, int width, int) {
133 skcms(dst, src, width,
134 skcms_PixelFormat_BGR_101010x_XR, skcms_AlphaFormat_Unpremul,
135 skcms_PixelFormat_RGB_161616BE, skcms_AlphaFormat_Unpremul);
136 }
137
transform_scanline_bgra_10101010_xr(char * dst,const char * src,int width,int)138 static inline void transform_scanline_bgra_10101010_xr(char* dst, const char* src, int width, int) {
139 skcms(dst, src, width,
140 skcms_PixelFormat_BGRA_10101010_XR, skcms_AlphaFormat_Unpremul,
141 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
142 }
143
transform_scanline_bgra_1010102_premul(char * dst,const char * src,int width,int)144 static inline void transform_scanline_bgra_1010102_premul(char* dst, const char* src, int width, int) {
145 skcms(dst, src, width,
146 skcms_PixelFormat_BGRA_1010102, skcms_AlphaFormat_PremulAsEncoded,
147 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
148 }
149
transform_scanline_F16(char * dst,const char * src,int width,int)150 static inline void transform_scanline_F16(char* dst, const char* src, int width, int) {
151 skcms(dst, src, width,
152 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
153 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
154 }
155
transform_scanline_F16_premul(char * dst,const char * src,int width,int)156 static inline void transform_scanline_F16_premul(char* dst, const char* src, int width, int) {
157 skcms(dst, src, width,
158 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
159 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
160 }
161
transform_scanline_F16_to_8888(char * dst,const char * src,int width,int)162 static inline void transform_scanline_F16_to_8888(char* dst, const char* src, int width, int) {
163 skcms(dst, src, width,
164 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
165 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
166 }
167
transform_scanline_F16_premul_to_8888(char * dst,const char * src,int width,int)168 static inline void transform_scanline_F16_premul_to_8888(char* dst,
169 const char* src,
170 int width,
171 int) {
172 skcms(dst, src, width,
173 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
174 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
175 }
176
transform_scanline_F16_to_premul_8888(char * dst,const char * src,int width,int)177 static inline void transform_scanline_F16_to_premul_8888(char* dst,
178 const char* src,
179 int width,
180 int) {
181 skcms(dst, src, width,
182 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
183 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded);
184 }
185
transform_scanline_F32(char * dst,const char * src,int width,int)186 static inline void transform_scanline_F32(char* dst, const char* src, int width, int) {
187 skcms(dst, src, width,
188 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_Unpremul,
189 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
190 }
191
transform_scanline_F32_premul(char * dst,const char * src,int width,int)192 static inline void transform_scanline_F32_premul(char* dst, const char* src, int width, int) {
193 skcms(dst, src, width,
194 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_PremulAsEncoded,
195 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
196 }
197
icc_from_color_space(const SkColorSpace * cs,const skcms_ICCProfile * profile,const char * profile_description)198 static inline sk_sp<SkData> icc_from_color_space(const SkColorSpace* cs,
199 const skcms_ICCProfile* profile,
200 const char* profile_description) {
201 // TODO(ccameron): Remove this check.
202 if (!cs) {
203 return nullptr;
204 }
205
206 if (profile) {
207 return SkWriteICCProfile(profile, profile_description);
208 }
209
210 skcms_Matrix3x3 toXYZD50;
211 if (cs->toXYZD50(&toXYZD50)) {
212 skcms_TransferFunction fn;
213 cs->transferFn(&fn);
214 return SkWriteICCProfile(fn, toXYZD50);
215 }
216 return nullptr;
217 }
218
icc_from_color_space(const SkImageInfo & info,const skcms_ICCProfile * profile,const char * profile_description)219 static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info,
220 const skcms_ICCProfile* profile,
221 const char* profile_description) {
222 return icc_from_color_space(info.colorSpace(), profile, profile_description);
223 }
224
225 #endif // SkImageEncoderFns_DEFINED
226