• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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