blob: e6f5d4094444fc9e3296cbc5a614060002fe2c21 [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 Klein509ccb02018-11-02 12:54:01 -040011#include "../../third_party/skcms/skcms.h"
epoger@google.com4ce738b2012-11-16 18:44:18 +000012#include "SkColor.h"
Cary Clarka4083c92017-09-15 11:59:23 -040013#include "SkColorData.h"
Matt Sarett5df93de2017-03-22 21:52:47 +000014#include "SkICC.h"
Mike Klein0c904fa2018-11-02 12:24:15 -040015#include "SkTypes.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 Klein0c904fa2018-11-02 12:24:15 -0400116static inline void transform_scanline_F16(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400117 skcms(dst, src, width,
118 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
119 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
Matt Sarett1da27ef2017-01-19 17:14:07 -0500120}
121
Mike Klein0c904fa2018-11-02 12:24:15 -0400122static inline void transform_scanline_F16_premul(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400123 skcms(dst, src, width,
124 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
125 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
Matt Sarett1da27ef2017-01-19 17:14:07 -0500126}
Matt Sarett55213562017-01-23 19:37:37 -0500127
Mike Klein0c904fa2018-11-02 12:24:15 -0400128static inline void transform_scanline_F16_to_8888(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400129 skcms(dst, src, width,
130 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul,
131 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
Matt Sarett55213562017-01-23 19:37:37 -0500132}
133
Mike Klein0c904fa2018-11-02 12:24:15 -0400134static inline void transform_scanline_F16_premul_to_8888(char* dst,
135 const char* src,
136 int width,
137 int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400138 skcms(dst, src, width,
139 skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded,
140 skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul);
Matt Sarett55213562017-01-23 19:37:37 -0500141}
Matt Sarett5df93de2017-03-22 21:52:47 +0000142
Mike Klein0c904fa2018-11-02 12:24:15 -0400143static inline void transform_scanline_F16_to_premul_8888(char* dst,
144 const char* src,
145 int width,
146 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_PremulAsEncoded);
Matt Sarett2e61b182017-05-09 12:46:50 -0400150}
151
Mike Klein0c904fa2018-11-02 12:24:15 -0400152static inline void transform_scanline_F32(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400153 skcms(dst, src, width,
154 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_Unpremul,
155 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
Mike Klein37854712018-06-26 11:43:06 -0400156}
157
Mike Klein0c904fa2018-11-02 12:24:15 -0400158static inline void transform_scanline_F32_premul(char* dst, const char* src, int width, int) {
Mike Klein509ccb02018-11-02 12:54:01 -0400159 skcms(dst, src, width,
160 skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_PremulAsEncoded,
161 skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul);
Mike Klein37854712018-06-26 11:43:06 -0400162}
163
Matt Sarett1950e0a2017-06-12 16:17:30 -0400164static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
165 SkColorSpace* cs = info.colorSpace();
166 if (!cs) {
167 return nullptr;
168 }
169
Matt Sarett5df93de2017-03-22 21:52:47 +0000170 SkColorSpaceTransferFn fn;
Mike Klein4429a4f2018-10-04 09:06:00 -0400171 SkMatrix44 toXYZD50;
Matt Sarett1950e0a2017-06-12 16:17:30 -0400172 if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {
Matt Sarett5df93de2017-03-22 21:52:47 +0000173 return SkICC::WriteToICC(fn, toXYZD50);
174 }
Matt Sarett5df93de2017-03-22 21:52:47 +0000175 return nullptr;
176}
177
178#endif // SkImageEncoderFns_DEFINED