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/SkICC.h"
14 #include "include/core/SkImageInfo.h"
15 #include "include/core/SkRefCnt.h"
16 #include "include/core/SkTypes.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_bgra_1010102_premul(char * dst,const char * src,int width,int)132 static inline void transform_scanline_bgra_1010102_premul(char* dst, const char* src, int width, int) {
133 skcms(dst, src, width,
134 skcms_PixelFormat_BGRA_1010102, skcms_AlphaFormat_PremulAsEncoded,
135 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
136 }
137
transform_scanline_F16(char * dst,const char * src,int width,int)138 static inline void transform_scanline_F16(char* dst, const char* src, int width, int) {
139 skcms(dst, src, width,
140 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
141 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
142 }
143
transform_scanline_F16_premul(char * dst,const char * src,int width,int)144 static inline void transform_scanline_F16_premul(char* dst, const char* src, int width, int) {
145 skcms(dst, src, width,
146 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
147 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
148 }
149
transform_scanline_F16_to_8888(char * dst,const char * src,int width,int)150 static inline void transform_scanline_F16_to_8888(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_8888, skcms_AlphaFormat_Unpremul);
154 }
155
transform_scanline_F16_premul_to_8888(char * dst,const char * src,int width,int)156 static inline void transform_scanline_F16_premul_to_8888(char* dst,
157 const char* src,
158 int width,
159 int) {
160 skcms(dst, src, width,
161 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
162 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
163 }
164
transform_scanline_F16_to_premul_8888(char * dst,const char * src,int width,int)165 static inline void transform_scanline_F16_to_premul_8888(char* dst,
166 const char* src,
167 int width,
168 int) {
169 skcms(dst, src, width,
170 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
171 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded);
172 }
173
transform_scanline_F32(char * dst,const char * src,int width,int)174 static inline void transform_scanline_F32(char* dst, const char* src, int width, int) {
175 skcms(dst, src, width,
176 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_Unpremul,
177 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
178 }
179
transform_scanline_F32_premul(char * dst,const char * src,int width,int)180 static inline void transform_scanline_F32_premul(char* dst, const char* src, int width, int) {
181 skcms(dst, src, width,
182 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_PremulAsEncoded,
183 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
184 }
185
icc_from_color_space(const SkColorSpace * cs,const skcms_ICCProfile * profile,const char * profile_description)186 static inline sk_sp<SkData> icc_from_color_space(const SkColorSpace* cs,
187 const skcms_ICCProfile* profile,
188 const char* profile_description) {
189 // TODO(ccameron): Remove this check.
190 if (!cs) {
191 return nullptr;
192 }
193
194 if (profile) {
195 return SkWriteICCProfile(profile, profile_description);
196 }
197
198 skcms_Matrix3x3 toXYZD50;
199 if (cs->toXYZD50(&toXYZD50)) {
200 skcms_TransferFunction fn;
201 cs->transferFn(&fn);
202 return SkWriteICCProfile(fn, toXYZD50);
203 }
204 return nullptr;
205 }
206
icc_from_color_space(const SkImageInfo & info,const skcms_ICCProfile * profile,const char * profile_description)207 static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info,
208 const skcms_ICCProfile* profile,
209 const char* profile_description) {
210 return icc_from_color_space(info.colorSpace(), profile, profile_description);
211 }
212
213 #endif // SkImageEncoderFns_DEFINED
214