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 "../../third_party/skcms/skcms.h"
12 #include "SkColor.h"
13 #include "SkColorData.h"
14 #include "SkICC.h"
15 #include "SkTypes.h"
16
17 typedef void (*transform_scanline_proc)(char* dst, const char* src, int width, int bpp);
18
transform_scanline_memcpy(char * dst,const char * src,int width,int bpp)19 static inline void transform_scanline_memcpy(char* dst, const char* src, int width, int bpp) {
20 memcpy(dst, src, width * bpp);
21 }
22
transform_scanline_A8_to_GrayAlpha(char * dst,const char * src,int width,int)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
skcms(char * dst,const char * src,int n,skcms_PixelFormat srcFmt,skcms_AlphaFormat srcAlpha,skcms_PixelFormat dstFmt,skcms_AlphaFormat dstAlpha)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
transform_scanline_gray(char * dst,const char * src,int width,int)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
transform_scanline_565(char * dst,const char * src,int width,int)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
transform_scanline_RGBX(char * dst,const char * src,int width,int)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
transform_scanline_BGRX(char * dst,const char * src,int width,int)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
transform_scanline_444(char * dst,const char * src,int width,int)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
transform_scanline_rgbA(char * dst,const char * src,int width,int)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
transform_scanline_bgrA(char * dst,const char * src,int width,int)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
transform_scanline_to_premul_legacy(char * dst,const char * src,int width,int)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
transform_scanline_BGRA(char * dst,const char * src,int width,int)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
transform_scanline_4444(char * dst,const char * src,int width,int)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
transform_scanline_101010x(char * dst,const char * src,int width,int)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
transform_scanline_1010102(char * dst,const char * src,int width,int)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
transform_scanline_1010102_premul(char * dst,const char * src,int width,int)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
transform_scanline_F16(char * dst,const char * src,int width,int)116 static inline void transform_scanline_F16(char* dst, const char* src, int width, int) {
117 skcms(dst, src, width,
118 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
119 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
120 }
121
transform_scanline_F16_premul(char * dst,const char * src,int width,int)122 static inline void transform_scanline_F16_premul(char* dst, const char* src, int width, int) {
123 skcms(dst, src, width,
124 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
125 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
126 }
127
transform_scanline_F16_to_8888(char * dst,const char * src,int width,int)128 static inline void transform_scanline_F16_to_8888(char* dst, const char* src, int width, int) {
129 skcms(dst, src, width,
130 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
131 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
132 }
133
transform_scanline_F16_premul_to_8888(char * dst,const char * src,int width,int)134 static inline void transform_scanline_F16_premul_to_8888(char* dst,
135 const char* src,
136 int width,
137 int) {
138 skcms(dst, src, width,
139 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
140 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
141 }
142
transform_scanline_F16_to_premul_8888(char * dst,const char * src,int width,int)143 static inline void transform_scanline_F16_to_premul_8888(char* dst,
144 const char* src,
145 int width,
146 int) {
147 skcms(dst, src, width,
148 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
149 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded);
150 }
151
transform_scanline_F32(char * dst,const char * src,int width,int)152 static inline void transform_scanline_F32(char* dst, const char* src, int width, int) {
153 skcms(dst, src, width,
154 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_Unpremul,
155 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
156 }
157
transform_scanline_F32_premul(char * dst,const char * src,int width,int)158 static inline void transform_scanline_F32_premul(char* dst, const char* src, int width, int) {
159 skcms(dst, src, width,
160 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_PremulAsEncoded,
161 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
162 }
163
icc_from_color_space(const SkImageInfo & info)164 static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
165 SkColorSpace* cs = info.colorSpace();
166 if (!cs) {
167 return nullptr;
168 }
169
170 skcms_TransferFunction fn;
171 skcms_Matrix3x3 toXYZD50;
172 if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {
173 return SkWriteICCProfile(fn, toXYZD50);
174 }
175 return nullptr;
176 }
177
178 #endif // SkImageEncoderFns_DEFINED
179