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
17typedef void (*transform_scanline_proc)(char* dst, const char* src, int width, int bpp);
18
19static inline void transform_scanline_memcpy(char* dst, const char* src, int width, int bpp) {
20 memcpy(dst, src, width * bpp);
21}
22
23static 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
31static 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
38static 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
44static 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
50static 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
56static 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
62static 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
68static 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
74static 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
80static 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
86static 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
92static 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
98static 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
104static 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
110static 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
116static 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
122static 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
128static 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
134static 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
140static 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
146static 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
152static 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
161static 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
170static 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
176static 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
182static 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