blob: fece76cf0257daca2329855aff475152b10af133 [file] [log] [blame]
epoger@google.com4ce738b2012-11-16 18:44:18 +00001/*
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 */
Matt Sarett5df93de2017-03-22 21:52:47 +00007
8#ifndef SkImageEncoderFns_DEFINED
9#define SkImageEncoderFns_DEFINED
epoger@google.com4ce738b2012-11-16 18:44:18 +000010
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkColor.h"
12#include "include/core/SkICC.h"
13#include "include/core/SkTypes.h"
14#include "include/private/SkColorData.h"
Brian Osmanea236bf2019-04-29 10:28:22 -040015#include "include/third_party/skcms/skcms.h"
epoger@google.com4ce738b2012-11-16 18:44:18 +000016
Mike Klein0c904fa2018-11-02 12:24:15 -040017typedef void (*transform_scanline_proc)(char* dst, const char* src, int width, int bpp);
epoger@google.com4ce738b2012-11-16 18:44:18 +000018
Mike Klein0c904fa2018-11-02 12:24:15 -040019static inline void transform_scanline_memcpy(char* dst, const char* src, int width, int bpp) {
msarettf17b71f2016-09-12 14:30:03 -070020 memcpy(dst, src, width * bpp);
epoger@google.com4ce738b2012-11-16 18:44:18 +000021}
22
Mike Klein509ccb02018-11-02 12:54:01 -040023static inline void transform_scanline_A8_to_GrayAlpha(char* dst, const char* src, int width, int) {
Matt Sarett62bb2802017-01-23 12:28:02 -050024 for (int i = 0; i < width; i++) {
Mike Klein509ccb02018-11-02 12:54:01 -040025 *dst++ = 0;
26 *dst++ = *src++;
Matt Sarett62bb2802017-01-23 12:28:02 -050027 }
28}
29
Mike Klein509ccb02018-11-02 12:54:01 -040030
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
Mike Klein0c904fa2018-11-02 12:24:15 -040044static inline void transform_scanline_565(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -040045 skcms(dst, src, width,
46 skcms_PixelFormat_BGR_565, skcms_AlphaFormat_Unpremul,
47 skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Unpremul);
Mike Reedd6cb11e2017-11-30 15:33:04 -050048}
49
Mike Klein0c904fa2018-11-02 12:24:15 -040050static inline void transform_scanline_RGBX(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -040051 skcms(dst, src, width,
52 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul,
53 skcms_PixelFormat_RGB_888 , skcms_AlphaFormat_Unpremul);
msarettf17b71f2016-09-12 14:30:03 -070054}
55
Mike Klein0c904fa2018-11-02 12:24:15 -040056static inline void transform_scanline_BGRX(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -040057 skcms(dst, src, width,
58 skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_Unpremul,
59 skcms_PixelFormat_RGB_888 , skcms_AlphaFormat_Unpremul);
epoger@google.com4ce738b2012-11-16 18:44:18 +000060}
61
Mike Klein0c904fa2018-11-02 12:24:15 -040062static inline void transform_scanline_444(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -040063 skcms(dst, src, width,
64 skcms_PixelFormat_ABGR_4444, skcms_AlphaFormat_Unpremul,
65 skcms_PixelFormat_RGB_888 , skcms_AlphaFormat_Unpremul);
epoger@google.com4ce738b2012-11-16 18:44:18 +000066}
67
Mike Klein0c904fa2018-11-02 12:24:15 -040068static inline void transform_scanline_rgbA(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -040069 skcms(dst, src, width,
70 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded,
71 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
Matt Sarett84014f02017-01-10 11:28:54 -050072}
73
Mike Klein0c904fa2018-11-02 12:24:15 -040074static inline void transform_scanline_bgrA(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -040075 skcms(dst, src, width,
76 skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_PremulAsEncoded,
77 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
Matt Sarett84014f02017-01-10 11:28:54 -050078}
79
Mike Klein0c904fa2018-11-02 12:24:15 -040080static inline void transform_scanline_to_premul_legacy(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -040081 skcms(dst, src, width,
82 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul,
83 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded);
Matt Sarett2e61b182017-05-09 12:46:50 -040084}
85
Mike Klein0c904fa2018-11-02 12:24:15 -040086static inline void transform_scanline_BGRA(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -040087 skcms(dst, src, width,
88 skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_Unpremul,
89 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
msarettf17b71f2016-09-12 14:30:03 -070090}
91
Mike Klein0c904fa2018-11-02 12:24:15 -040092static inline void transform_scanline_4444(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -040093 skcms(dst, src, width,
94 skcms_PixelFormat_ABGR_4444, skcms_AlphaFormat_PremulAsEncoded,
95 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
epoger@google.com4ce738b2012-11-16 18:44:18 +000096}
Matt Sarett1da27ef2017-01-19 17:14:07 -050097
Mike Klein0c904fa2018-11-02 12:24:15 -040098static inline void transform_scanline_101010x(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -040099 skcms(dst, src, width,
100 skcms_PixelFormat_RGBA_1010102, skcms_AlphaFormat_Unpremul,
101 skcms_PixelFormat_RGB_161616BE, skcms_AlphaFormat_Unpremul);
Mike Kleinac568a92018-01-25 09:09:32 -0500102}
103
Mike Klein0c904fa2018-11-02 12:24:15 -0400104static inline void transform_scanline_1010102(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400105 skcms(dst, src, width,
106 skcms_PixelFormat_RGBA_1010102, skcms_AlphaFormat_Unpremul,
107 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
Mike Kleinac568a92018-01-25 09:09:32 -0500108}
109
Mike Klein0c904fa2018-11-02 12:24:15 -0400110static inline void transform_scanline_1010102_premul(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400111 skcms(dst, src, width,
112 skcms_PixelFormat_RGBA_1010102, skcms_AlphaFormat_PremulAsEncoded,
113 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
Mike Kleinac568a92018-01-25 09:09:32 -0500114}
115
Mike Kleinf7eb0542020-02-11 12:19:08 -0600116static 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
Mike Klein0c904fa2018-11-02 12:24:15 -0400134static inline void transform_scanline_F16(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400135 skcms(dst, src, width,
136 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
137 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
Matt Sarett1da27ef2017-01-19 17:14:07 -0500138}
139
Mike Klein0c904fa2018-11-02 12:24:15 -0400140static inline void transform_scanline_F16_premul(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400141 skcms(dst, src, width,
142 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
143 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
Matt Sarett1da27ef2017-01-19 17:14:07 -0500144}
Matt Sarett55213562017-01-23 19:37:37 -0500145
Mike Klein0c904fa2018-11-02 12:24:15 -0400146static inline void transform_scanline_F16_to_8888(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400147 skcms(dst, src, width,
148 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
149 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
Matt Sarett55213562017-01-23 19:37:37 -0500150}
151
Mike Klein0c904fa2018-11-02 12:24:15 -0400152static inline void transform_scanline_F16_premul_to_8888(char* dst,
153 const char* src,
154 int width,
155 int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400156 skcms(dst, src, width,
157 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
158 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
Matt Sarett55213562017-01-23 19:37:37 -0500159}
Matt Sarett5df93de2017-03-22 21:52:47 +0000160
Mike Klein0c904fa2018-11-02 12:24:15 -0400161static inline void transform_scanline_F16_to_premul_8888(char* dst,
162 const char* src,
163 int width,
164 int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400165 skcms(dst, src, width,
166 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
167 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded);
Matt Sarett2e61b182017-05-09 12:46:50 -0400168}
169
Mike Klein0c904fa2018-11-02 12:24:15 -0400170static inline void transform_scanline_F32(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400171 skcms(dst, src, width,
172 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_Unpremul,
173 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
Mike Klein37854712018-06-26 11:43:06 -0400174}
175
Mike Klein0c904fa2018-11-02 12:24:15 -0400176static inline void transform_scanline_F32_premul(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400177 skcms(dst, src, width,
178 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_PremulAsEncoded,
179 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
Mike Klein37854712018-06-26 11:43:06 -0400180}
181
Matt Sarett1950e0a2017-06-12 16:17:30 -0400182static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
183 SkColorSpace* cs = info.colorSpace();
184 if (!cs) {
185 return nullptr;
186 }
187
Brian Osman5deadca2019-01-24 12:18:17 -0500188 skcms_TransferFunction fn;
Brian Osman9c6ee012019-01-16 13:13:36 -0500189 skcms_Matrix3x3 toXYZD50;
Matt Sarett1950e0a2017-06-12 16:17:30 -0400190 if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {
Brian Osman5deadca2019-01-24 12:18:17 -0500191 return SkWriteICCProfile(fn, toXYZD50);
Matt Sarett5df93de2017-03-22 21:52:47 +0000192 }
Matt Sarett5df93de2017-03-22 21:52:47 +0000193 return nullptr;
194}
195
196#endif // SkImageEncoderFns_DEFINED