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 | |
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_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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |