epoger@google.com | 4ce738b | 2012-11-16 18:44:18 +0000 | [diff] [blame] | 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 | */ |
Matt Sarett | 5df93de | 2017-03-22 21:52:47 +0000 | [diff] [blame] | 7 | |
| 8 | #ifndef SkImageEncoderFns_DEFINED |
| 9 | #define SkImageEncoderFns_DEFINED |
epoger@google.com | 4ce738b | 2012-11-16 18:44:18 +0000 | [diff] [blame] | 10 | |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 11 | #include "../../third_party/skcms/skcms.h" |
epoger@google.com | 4ce738b | 2012-11-16 18:44:18 +0000 | [diff] [blame] | 12 | #include "SkColor.h" |
Cary Clark | a4083c9 | 2017-09-15 11:59:23 -0400 | [diff] [blame] | 13 | #include "SkColorData.h" |
Matt Sarett | 5df93de | 2017-03-22 21:52:47 +0000 | [diff] [blame] | 14 | #include "SkICC.h" |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 15 | #include "SkTypes.h" |
epoger@google.com | 4ce738b | 2012-11-16 18:44:18 +0000 | [diff] [blame] | 16 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 17 | typedef void (*transform_scanline_proc)(char* dst, const char* src, int width, int bpp); |
epoger@google.com | 4ce738b | 2012-11-16 18:44:18 +0000 | [diff] [blame] | 18 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 19 | static inline void transform_scanline_memcpy(char* dst, const char* src, int width, int bpp) { |
msarett | f17b71f | 2016-09-12 14:30:03 -0700 | [diff] [blame] | 20 | memcpy(dst, src, width * bpp); |
epoger@google.com | 4ce738b | 2012-11-16 18:44:18 +0000 | [diff] [blame] | 21 | } |
| 22 | |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 23 | static inline void transform_scanline_A8_to_GrayAlpha(char* dst, const char* src, int width, int) { |
Matt Sarett | 62bb280 | 2017-01-23 12:28:02 -0500 | [diff] [blame] | 24 | for (int i = 0; i < width; i++) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 25 | *dst++ = 0; |
| 26 | *dst++ = *src++; |
Matt Sarett | 62bb280 | 2017-01-23 12:28:02 -0500 | [diff] [blame] | 27 | } |
| 28 | } |
| 29 | |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 30 | |
| 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 | |
| 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 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 44 | static inline void transform_scanline_565(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 45 | skcms(dst, src, width, |
| 46 | skcms_PixelFormat_BGR_565, skcms_AlphaFormat_Unpremul, |
| 47 | skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Unpremul); |
Mike Reed | d6cb11e | 2017-11-30 15:33:04 -0500 | [diff] [blame] | 48 | } |
| 49 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 50 | static inline void transform_scanline_RGBX(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 51 | skcms(dst, src, width, |
| 52 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul, |
| 53 | skcms_PixelFormat_RGB_888 , skcms_AlphaFormat_Unpremul); |
msarett | f17b71f | 2016-09-12 14:30:03 -0700 | [diff] [blame] | 54 | } |
| 55 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 56 | static inline void transform_scanline_BGRX(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 57 | skcms(dst, src, width, |
| 58 | skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_Unpremul, |
| 59 | skcms_PixelFormat_RGB_888 , skcms_AlphaFormat_Unpremul); |
epoger@google.com | 4ce738b | 2012-11-16 18:44:18 +0000 | [diff] [blame] | 60 | } |
| 61 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 62 | static inline void transform_scanline_444(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 63 | skcms(dst, src, width, |
| 64 | skcms_PixelFormat_ABGR_4444, skcms_AlphaFormat_Unpremul, |
| 65 | skcms_PixelFormat_RGB_888 , skcms_AlphaFormat_Unpremul); |
epoger@google.com | 4ce738b | 2012-11-16 18:44:18 +0000 | [diff] [blame] | 66 | } |
| 67 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 68 | static inline void transform_scanline_rgbA(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 69 | skcms(dst, src, width, |
| 70 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded, |
| 71 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul); |
Matt Sarett | 84014f0 | 2017-01-10 11:28:54 -0500 | [diff] [blame] | 72 | } |
| 73 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 74 | static inline void transform_scanline_bgrA(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 75 | skcms(dst, src, width, |
| 76 | skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_PremulAsEncoded, |
| 77 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul); |
Matt Sarett | 84014f0 | 2017-01-10 11:28:54 -0500 | [diff] [blame] | 78 | } |
| 79 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 80 | static inline void transform_scanline_to_premul_legacy(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 81 | skcms(dst, src, width, |
| 82 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul, |
| 83 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded); |
Matt Sarett | 2e61b18 | 2017-05-09 12:46:50 -0400 | [diff] [blame] | 84 | } |
| 85 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 86 | static inline void transform_scanline_BGRA(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 87 | skcms(dst, src, width, |
| 88 | skcms_PixelFormat_BGRA_8888, skcms_AlphaFormat_Unpremul, |
| 89 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul); |
msarett | f17b71f | 2016-09-12 14:30:03 -0700 | [diff] [blame] | 90 | } |
| 91 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 92 | static inline void transform_scanline_4444(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 93 | skcms(dst, src, width, |
| 94 | skcms_PixelFormat_ABGR_4444, skcms_AlphaFormat_PremulAsEncoded, |
| 95 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul); |
epoger@google.com | 4ce738b | 2012-11-16 18:44:18 +0000 | [diff] [blame] | 96 | } |
Matt Sarett | 1da27ef | 2017-01-19 17:14:07 -0500 | [diff] [blame] | 97 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 98 | static inline void transform_scanline_101010x(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 99 | skcms(dst, src, width, |
| 100 | skcms_PixelFormat_RGBA_1010102, skcms_AlphaFormat_Unpremul, |
| 101 | skcms_PixelFormat_RGB_161616BE, skcms_AlphaFormat_Unpremul); |
Mike Klein | ac568a9 | 2018-01-25 09:09:32 -0500 | [diff] [blame] | 102 | } |
| 103 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 104 | static inline void transform_scanline_1010102(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 105 | skcms(dst, src, width, |
| 106 | skcms_PixelFormat_RGBA_1010102, skcms_AlphaFormat_Unpremul, |
| 107 | skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); |
Mike Klein | ac568a9 | 2018-01-25 09:09:32 -0500 | [diff] [blame] | 108 | } |
| 109 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 110 | static inline void transform_scanline_1010102_premul(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 111 | skcms(dst, src, width, |
| 112 | skcms_PixelFormat_RGBA_1010102, skcms_AlphaFormat_PremulAsEncoded, |
| 113 | skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); |
Mike Klein | ac568a9 | 2018-01-25 09:09:32 -0500 | [diff] [blame] | 114 | } |
| 115 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 116 | static inline void transform_scanline_F16(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 117 | skcms(dst, src, width, |
| 118 | skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul, |
| 119 | skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); |
Matt Sarett | 1da27ef | 2017-01-19 17:14:07 -0500 | [diff] [blame] | 120 | } |
| 121 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 122 | static inline void transform_scanline_F16_premul(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 123 | skcms(dst, src, width, |
| 124 | skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded, |
| 125 | skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); |
Matt Sarett | 1da27ef | 2017-01-19 17:14:07 -0500 | [diff] [blame] | 126 | } |
Matt Sarett | 5521356 | 2017-01-23 19:37:37 -0500 | [diff] [blame] | 127 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 128 | static inline void transform_scanline_F16_to_8888(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 129 | skcms(dst, src, width, |
| 130 | skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul, |
| 131 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul); |
Matt Sarett | 5521356 | 2017-01-23 19:37:37 -0500 | [diff] [blame] | 132 | } |
| 133 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 134 | static inline void transform_scanline_F16_premul_to_8888(char* dst, |
| 135 | const char* src, |
| 136 | int width, |
| 137 | int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 138 | skcms(dst, src, width, |
| 139 | skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_PremulAsEncoded, |
| 140 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul); |
Matt Sarett | 5521356 | 2017-01-23 19:37:37 -0500 | [diff] [blame] | 141 | } |
Matt Sarett | 5df93de | 2017-03-22 21:52:47 +0000 | [diff] [blame] | 142 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 143 | static inline void transform_scanline_F16_to_premul_8888(char* dst, |
| 144 | const char* src, |
| 145 | int width, |
| 146 | int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 147 | skcms(dst, src, width, |
| 148 | skcms_PixelFormat_RGBA_hhhh, skcms_AlphaFormat_Unpremul, |
| 149 | skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded); |
Matt Sarett | 2e61b18 | 2017-05-09 12:46:50 -0400 | [diff] [blame] | 150 | } |
| 151 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 152 | static inline void transform_scanline_F32(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 153 | skcms(dst, src, width, |
| 154 | skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_Unpremul, |
| 155 | skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); |
Mike Klein | 3785471 | 2018-06-26 11:43:06 -0400 | [diff] [blame] | 156 | } |
| 157 | |
Mike Klein | 0c904fa | 2018-11-02 12:24:15 -0400 | [diff] [blame] | 158 | static inline void transform_scanline_F32_premul(char* dst, const char* src, int width, int) { |
Mike Klein | 509ccb0 | 2018-11-02 12:54:01 -0400 | [diff] [blame] | 159 | skcms(dst, src, width, |
| 160 | skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_PremulAsEncoded, |
| 161 | skcms_PixelFormat_RGBA_16161616BE, skcms_AlphaFormat_Unpremul); |
Mike Klein | 3785471 | 2018-06-26 11:43:06 -0400 | [diff] [blame] | 162 | } |
| 163 | |
Matt Sarett | 1950e0a | 2017-06-12 16:17:30 -0400 | [diff] [blame] | 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 | |
Brian Osman | 5deadca | 2019-01-24 12:18:17 -0500 | [diff] [blame] | 170 | skcms_TransferFunction fn; |
Brian Osman | 9c6ee01 | 2019-01-16 13:13:36 -0500 | [diff] [blame] | 171 | skcms_Matrix3x3 toXYZD50; |
Matt Sarett | 1950e0a | 2017-06-12 16:17:30 -0400 | [diff] [blame] | 172 | if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) { |
Brian Osman | 5deadca | 2019-01-24 12:18:17 -0500 | [diff] [blame] | 173 | return SkWriteICCProfile(fn, toXYZD50); |
Matt Sarett | 5df93de | 2017-03-22 21:52:47 +0000 | [diff] [blame] | 174 | } |
Matt Sarett | 5df93de | 2017-03-22 21:52:47 +0000 | [diff] [blame] | 175 | return nullptr; |
| 176 | } |
| 177 | |
| 178 | #endif // SkImageEncoderFns_DEFINED |