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