blob: df5957b8400cc27152ef9749f067648992f1c347 [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
11/**
12 * Functions to transform scanlines between packed-pixel formats.
13 */
14
15#include "SkBitmap.h"
16#include "SkColor.h"
Cary Clarka4083c92017-09-15 11:59:23 -040017#include "SkColorData.h"
Matt Sarett5df93de2017-03-22 21:52:47 +000018#include "SkICC.h"
Matt Sarett2e61b182017-05-09 12:46:50 -040019#include "SkOpts.h"
epoger@google.com4ce738b2012-11-16 18:44:18 +000020#include "SkPreConfig.h"
Matt Sarett84014f02017-01-10 11:28:54 -050021#include "SkRasterPipeline.h"
epoger@google.com4ce738b2012-11-16 18:44:18 +000022#include "SkUnPreMultiply.h"
Matt Sarettc7b29082017-02-09 16:22:39 -050023#include "SkUnPreMultiplyPriv.h"
epoger@google.com4ce738b2012-11-16 18:44:18 +000024
25/**
26 * Function template for transforming scanlines.
27 * Transform 'width' pixels from 'src' buffer into 'dst' buffer,
28 * repacking color channel data as appropriate for the given transformation.
msarettf17b71f2016-09-12 14:30:03 -070029 * 'bpp' is bytes per pixel in the 'src' buffer.
epoger@google.com4ce738b2012-11-16 18:44:18 +000030 */
msarettf17b71f2016-09-12 14:30:03 -070031typedef void (*transform_scanline_proc)(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
Matt Sarett62bb2802017-01-23 12:28:02 -050032 int width, int bpp, const SkPMColor* colors);
epoger@google.com4ce738b2012-11-16 18:44:18 +000033
34/**
35 * Identity transformation: just copy bytes from src to dst.
36 */
Matt Sarett62bb2802017-01-23 12:28:02 -050037static inline void transform_scanline_memcpy(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
38 int width, int bpp, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -070039 memcpy(dst, src, width * bpp);
epoger@google.com4ce738b2012-11-16 18:44:18 +000040}
41
Matt Sarett62bb2802017-01-23 12:28:02 -050042static inline void transform_scanline_index8_opaque(char* SK_RESTRICT dst,
43 const char* SK_RESTRICT src, int width, int,
44 const SkPMColor* colors) {
45 for (int i = 0; i < width; i++) {
46 const uint32_t c = colors[(uint8_t)*src++];
47 dst[0] = SkGetPackedR32(c);
48 dst[1] = SkGetPackedG32(c);
49 dst[2] = SkGetPackedB32(c);
50 dst += 3;
51 }
52}
53
54static inline void transform_scanline_index8_unpremul(char* SK_RESTRICT dst,
55 const char* SK_RESTRICT src, int width, int,
56 const SkPMColor* colors) {
57 uint32_t* SK_RESTRICT dst32 = (uint32_t*) dst;
58 for (int i = 0; i < width; i++) {
59 // This function swizzles R and B on platforms where SkPMColor is BGRA. This is
60 // exactly what we want.
61 dst32[i] = SkSwizzle_RGBA_to_PMColor(colors[(uint8_t)*src++]);
62 }
63}
64
65static inline void transform_scanline_gray(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
66 int width, int, const SkPMColor* colors) {
67 for (int i = 0; i < width; i++) {
68 const uint8_t g = (uint8_t) *src++;
69 dst[0] = g;
70 dst[1] = g;
71 dst[2] = g;
72 dst += 3;
73 }
74}
75
epoger@google.com4ce738b2012-11-16 18:44:18 +000076/**
77 * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB.
78 * Alpha channel data is not present in kRGB_565_Config format, so there is no
79 * alpha channel data to preserve.
80 */
Matt Sarett62bb2802017-01-23 12:28:02 -050081static inline void transform_scanline_565(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
82 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -070083 const uint16_t* srcP = (const uint16_t*)src;
epoger@google.com4ce738b2012-11-16 18:44:18 +000084 for (int i = 0; i < width; i++) {
85 unsigned c = *srcP++;
86 *dst++ = SkPacked16ToR32(c);
87 *dst++ = SkPacked16ToG32(c);
88 *dst++ = SkPacked16ToB32(c);
89 }
90}
91
92/**
Mike Reedd6cb11e2017-11-30 15:33:04 -050093 * Transform from kAlpha_8_Config to 2-bytes-per-pixel GrayAlpha.
94 */
95static inline void transform_scanline_A8_to_GrayAlpha(char* SK_RESTRICT dst,
96 const char* SK_RESTRICT src,
97 int width, int, const SkPMColor*) {
98 for (int i = 0; i < width; i++) {
99 *dst++ = 0; // gray (ignored)
100 *dst++ = *src++; // alpha
101 }
102}
103
104/**
msarettf17b71f2016-09-12 14:30:03 -0700105 * Transform from kRGBA_8888_SkColorType to 3-bytes-per-pixel RGB.
106 * Alpha channel data is abandoned.
epoger@google.com4ce738b2012-11-16 18:44:18 +0000107 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500108static inline void transform_scanline_RGBX(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
109 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -0700110 const uint32_t* srcP = (const SkPMColor*)src;
epoger@google.com4ce738b2012-11-16 18:44:18 +0000111 for (int i = 0; i < width; i++) {
msarettf17b71f2016-09-12 14:30:03 -0700112 uint32_t c = *srcP++;
113 *dst++ = (c >> 0) & 0xFF;
114 *dst++ = (c >> 8) & 0xFF;
115 *dst++ = (c >> 16) & 0xFF;
116 }
117}
118
119/**
120 * Transform from kBGRA_8888_SkColorType to 3-bytes-per-pixel RGB.
121 * Alpha channel data is abandoned.
122 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500123static inline void transform_scanline_BGRX(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
124 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -0700125 const uint32_t* srcP = (const SkPMColor*)src;
126 for (int i = 0; i < width; i++) {
127 uint32_t c = *srcP++;
128 *dst++ = (c >> 16) & 0xFF;
129 *dst++ = (c >> 8) & 0xFF;
130 *dst++ = (c >> 0) & 0xFF;
epoger@google.com4ce738b2012-11-16 18:44:18 +0000131 }
132}
133
134/**
135 * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB.
136 * Alpha channel data, if any, is abandoned.
137 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500138static inline void transform_scanline_444(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
139 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -0700140 const SkPMColor16* srcP = (const SkPMColor16*)src;
epoger@google.com4ce738b2012-11-16 18:44:18 +0000141 for (int i = 0; i < width; i++) {
142 SkPMColor16 c = *srcP++;
143 *dst++ = SkPacked4444ToR32(c);
144 *dst++ = SkPacked4444ToG32(c);
145 *dst++ = SkPacked4444ToB32(c);
146 }
147}
148
epoger@google.com4ce738b2012-11-16 18:44:18 +0000149/**
Matt Sarett84014f02017-01-10 11:28:54 -0500150 * Transform from legacy kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
151 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500152static inline void transform_scanline_rgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
153 int width, int, const SkPMColor*) {
Matt Sarettc7b29082017-02-09 16:22:39 -0500154 SkUnpremultiplyRow<false>((uint32_t*) dst, (const uint32_t*) src, width);
Matt Sarett84014f02017-01-10 11:28:54 -0500155}
156
157/**
158 * Transform from legacy kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
159 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500160static inline void transform_scanline_bgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
161 int width, int, const SkPMColor*) {
Matt Sarettc7b29082017-02-09 16:22:39 -0500162 SkUnpremultiplyRow<true>((uint32_t*) dst, (const uint32_t*) src, width);
Matt Sarett84014f02017-01-10 11:28:54 -0500163}
164
Matt Sarett84014f02017-01-10 11:28:54 -0500165/**
Matt Sarett2e61b182017-05-09 12:46:50 -0400166 * Premultiply RGBA to rgbA.
167 */
168static inline void transform_scanline_to_premul_legacy(char* SK_RESTRICT dst,
169 const char* SK_RESTRICT src,
170 int width, int, const SkPMColor*) {
171 SkOpts::RGBA_to_rgbA((uint32_t*)dst, (const uint32_t*)src, width);
172}
173
174/**
msarettf17b71f2016-09-12 14:30:03 -0700175 * Transform from kUnpremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
176 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500177static inline void transform_scanline_BGRA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
178 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -0700179 const uint32_t* srcP = (const SkPMColor*)src;
180 for (int i = 0; i < width; i++) {
181 uint32_t c = *srcP++;
182 *dst++ = (c >> 16) & 0xFF;
183 *dst++ = (c >> 8) & 0xFF;
184 *dst++ = (c >> 0) & 0xFF;
185 *dst++ = (c >> 24) & 0xFF;
186 }
187}
188
189/**
epoger@google.com4ce738b2012-11-16 18:44:18 +0000190 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA,
191 * with scaling of RGB based on alpha channel.
192 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500193static inline void transform_scanline_4444(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
194 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -0700195 const SkPMColor16* srcP = (const SkPMColor16*)src;
196 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
epoger@google.com4ce738b2012-11-16 18:44:18 +0000197
198 for (int i = 0; i < width; i++) {
199 SkPMColor16 c = *srcP++;
200 unsigned a = SkPacked4444ToA32(c);
201 unsigned r = SkPacked4444ToR32(c);
202 unsigned g = SkPacked4444ToG32(c);
203 unsigned b = SkPacked4444ToB32(c);
204
205 if (0 != a && 255 != a) {
206 SkUnPreMultiply::Scale scale = table[a];
207 r = SkUnPreMultiply::ApplyScale(scale, r);
208 g = SkUnPreMultiply::ApplyScale(scale, g);
209 b = SkUnPreMultiply::ApplyScale(scale, b);
210 }
211 *dst++ = r;
212 *dst++ = g;
213 *dst++ = b;
214 *dst++ = a;
215 }
216}
Matt Sarett1da27ef2017-01-19 17:14:07 -0500217
Mike Kleinac568a92018-01-25 09:09:32 -0500218// 888x is opaque RGB in four bytes, with 8 junk bits. We convert that to 3 byte RGB.
219static inline void transform_scanline_888x(char* dst, const char* src,
220 int width, int, const SkPMColor*) {
221 while (width --> 0) {
222 dst[0] = src[0];
223 dst[1] = src[1];
224 dst[2] = src[2];
225 dst += 3;
226 src += 4;
227 }
228}
229
230// 101010x is opaque RGB in four bytes, with 2 bits junk. We convert to 6 byte RGB (big endian).
231static inline void transform_scanline_101010x(char* dst, const char* src,
232 int width, int, const SkPMColor*) {
233 auto d = ( uint16_t*)dst;
234 auto s = (const uint32_t*)src;
235 while (width --> 0) {
236 uint32_t r = (*s >> 0) & 1023,
237 g = (*s >> 10) & 1023,
238 b = (*s >> 20) & 1023;
239
240 // Scale 10-bit unorms to 16-bit by replicating the most significant bits.
241 r = (r << 6) | (r >> 4);
242 g = (g << 6) | (g >> 4);
243 b = (b << 6) | (b >> 4);
244
245 // Store big-endian.
246 d[0] = (r >> 8) | (r << 8);
247 d[1] = (g >> 8) | (g << 8);
248 d[2] = (b >> 8) | (b << 8);
249
250 d += 3; // 3 channels
251 s += 1; // 1 whole pixel
252 }
253}
254
255static inline void transform_scanline_1010102(char* dst, const char* src,
256 int width, int, const SkPMColor*) {
Mike Kleinb11ab572018-10-24 06:42:14 -0400257 SkRasterPipeline_MemoryCtx src_ctx = { (void*)src, 0 },
258 dst_ctx = { (void*)dst, 0 };
Mike Kleinac568a92018-01-25 09:09:32 -0500259 SkRasterPipeline_<256> p;
260 p.append(SkRasterPipeline::load_1010102, &src_ctx);
261 p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
262 p.run(0,0, width,1);
263}
264
265static inline void transform_scanline_1010102_premul(char* dst, const char* src,
266 int width, int, const SkPMColor*) {
Mike Kleinb11ab572018-10-24 06:42:14 -0400267 SkRasterPipeline_MemoryCtx src_ctx = { (void*)src, 0 },
268 dst_ctx = { (void*)dst, 0 };
Mike Kleinac568a92018-01-25 09:09:32 -0500269 SkRasterPipeline_<256> p;
270 p.append(SkRasterPipeline::load_1010102, &src_ctx);
271 p.append(SkRasterPipeline::unpremul);
272 p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
273 p.run(0,0, width,1);
274}
275
Matt Sarett1da27ef2017-01-19 17:14:07 -0500276/**
Matt Sarett55213562017-01-23 19:37:37 -0500277 * Transform from kRGBA_F16 to 8-bytes-per-pixel RGBA.
Matt Sarett1da27ef2017-01-19 17:14:07 -0500278 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500279static inline void transform_scanline_F16(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
280 int width, int, const SkPMColor*) {
Mike Kleinb11ab572018-10-24 06:42:14 -0400281 SkRasterPipeline_MemoryCtx src_ctx = { (void*)src, 0 },
282 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400283 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400284 p.append(SkRasterPipeline::load_f16, &src_ctx);
Mike Kleince988012017-07-21 13:11:37 -0400285 p.append(SkRasterPipeline::clamp_0); // F16 values may be out of [0,1] range, so clamp.
286 p.append(SkRasterPipeline::clamp_1);
Mike Klein45c16fa2017-07-18 18:15:13 -0400287 p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
288 p.run(0,0, width,1);
Matt Sarett1da27ef2017-01-19 17:14:07 -0500289}
290
291/**
Matt Sarett55213562017-01-23 19:37:37 -0500292 * Transform from kPremul, kRGBA_F16 to 8-bytes-per-pixel RGBA.
Matt Sarett1da27ef2017-01-19 17:14:07 -0500293 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500294static inline void transform_scanline_F16_premul(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
295 int width, int, const SkPMColor*) {
Mike Kleinb11ab572018-10-24 06:42:14 -0400296 SkRasterPipeline_MemoryCtx src_ctx = { (void*)src, 0 },
297 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400298 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400299 p.append(SkRasterPipeline::load_f16, &src_ctx);
Matt Sarett1da27ef2017-01-19 17:14:07 -0500300 p.append(SkRasterPipeline::unpremul);
Mike Kleince988012017-07-21 13:11:37 -0400301 p.append(SkRasterPipeline::clamp_0); // F16 values may be out of [0,1] range, so clamp.
302 p.append(SkRasterPipeline::clamp_1);
Mike Klein45c16fa2017-07-18 18:15:13 -0400303 p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
304 p.run(0,0, width,1);
Matt Sarett1da27ef2017-01-19 17:14:07 -0500305}
Matt Sarett55213562017-01-23 19:37:37 -0500306
307/**
308 * Transform from kRGBA_F16 to 4-bytes-per-pixel RGBA.
309 */
310static inline void transform_scanline_F16_to_8888(char* SK_RESTRICT dst,
311 const char* SK_RESTRICT src, int width, int,
312 const SkPMColor*) {
Mike Kleinb11ab572018-10-24 06:42:14 -0400313 SkRasterPipeline_MemoryCtx src_ctx = { (void*)src, 0 },
314 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400315 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400316 p.append(SkRasterPipeline::load_f16, &src_ctx);
Mike Kleince988012017-07-21 13:11:37 -0400317 p.append(SkRasterPipeline::clamp_0); // F16 values may be out of [0,1] range, so clamp.
318 p.append(SkRasterPipeline::clamp_1);
Mike Klein45c16fa2017-07-18 18:15:13 -0400319 p.append(SkRasterPipeline::store_8888, &dst_ctx);
320 p.run(0,0, width,1);
Matt Sarett55213562017-01-23 19:37:37 -0500321}
322
323/**
324 * Transform from kPremul, kRGBA_F16 to 4-bytes-per-pixel RGBA.
325 */
326static inline void transform_scanline_F16_premul_to_8888(char* SK_RESTRICT dst,
327 const char* SK_RESTRICT src, int width,
328 int, const SkPMColor*) {
Mike Kleinb11ab572018-10-24 06:42:14 -0400329 SkRasterPipeline_MemoryCtx src_ctx = { (void*)src, 0 },
330 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400331 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400332 p.append(SkRasterPipeline::load_f16, &src_ctx);
Matt Sarett55213562017-01-23 19:37:37 -0500333 p.append(SkRasterPipeline::unpremul);
Mike Kleince988012017-07-21 13:11:37 -0400334 p.append(SkRasterPipeline::clamp_0); // F16 values may be out of [0,1] range, so clamp.
335 p.append(SkRasterPipeline::clamp_1);
Mike Klein45c16fa2017-07-18 18:15:13 -0400336 p.append(SkRasterPipeline::store_8888, &dst_ctx);
337 p.run(0,0, width,1);
Matt Sarett55213562017-01-23 19:37:37 -0500338}
Matt Sarett5df93de2017-03-22 21:52:47 +0000339
Matt Sarett2e61b182017-05-09 12:46:50 -0400340/**
341 * Transform from kUnpremul, kRGBA_F16 to premultiplied rgbA 8888.
342 */
343static inline void transform_scanline_F16_to_premul_8888(char* SK_RESTRICT dst,
344 const char* SK_RESTRICT src, int width, int, const SkPMColor*) {
Mike Kleinb11ab572018-10-24 06:42:14 -0400345 SkRasterPipeline_MemoryCtx src_ctx = { (void*)src, 0 },
346 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400347 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400348 p.append(SkRasterPipeline::load_f16, &src_ctx);
Mike Kleince988012017-07-21 13:11:37 -0400349 p.append(SkRasterPipeline::clamp_0); // F16 values may be out of [0,1] range, so clamp.
350 p.append(SkRasterPipeline::clamp_1);
Matt Sarett2e61b182017-05-09 12:46:50 -0400351 p.append(SkRasterPipeline::premul);
Mike Klein45c16fa2017-07-18 18:15:13 -0400352 p.append(SkRasterPipeline::store_8888, &dst_ctx);
353 p.run(0,0, width,1);
Matt Sarett2e61b182017-05-09 12:46:50 -0400354}
355
Mike Klein37854712018-06-26 11:43:06 -0400356/**
357 * Transform from kRGBA_F32 to 8-bytes-per-pixel RGBA.
358 */
359static inline void transform_scanline_F32(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
360 int width, int, const SkPMColor*) {
Mike Kleinb11ab572018-10-24 06:42:14 -0400361 SkRasterPipeline_MemoryCtx src_ctx = { (void*)src, 0 },
362 dst_ctx = { (void*)dst, 0 };
Mike Klein37854712018-06-26 11:43:06 -0400363 SkRasterPipeline_<256> p;
364 p.append(SkRasterPipeline::load_f32, &src_ctx);
365 p.append(SkRasterPipeline::clamp_0); // F32 values may be out of [0,1] range, so clamp.
366 p.append(SkRasterPipeline::clamp_1);
Mike Klein37854712018-06-26 11:43:06 -0400367 p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
368 p.run(0,0, width,1);
369}
370
371/**
372 * Transform from kPremul, kRGBA_F32 to 8-bytes-per-pixel RGBA.
373 */
374static inline void transform_scanline_F32_premul(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
375 int width, int, const SkPMColor*) {
Mike Kleinb11ab572018-10-24 06:42:14 -0400376 SkRasterPipeline_MemoryCtx src_ctx = { (void*)src, 0 },
377 dst_ctx = { (void*)dst, 0 };
Mike Klein37854712018-06-26 11:43:06 -0400378 SkRasterPipeline_<256> p;
379 p.append(SkRasterPipeline::load_f32, &src_ctx);
380 p.append(SkRasterPipeline::unpremul);
381 p.append(SkRasterPipeline::clamp_0); // F32 values may be out of [0,1] range, so clamp.
382 p.append(SkRasterPipeline::clamp_1);
Mike Klein37854712018-06-26 11:43:06 -0400383 p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
384 p.run(0,0, width,1);
385}
386
Matt Sarett1950e0a2017-06-12 16:17:30 -0400387static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
388 SkColorSpace* cs = info.colorSpace();
389 if (!cs) {
390 return nullptr;
391 }
392
Matt Sarett5df93de2017-03-22 21:52:47 +0000393 SkColorSpaceTransferFn fn;
Mike Klein4429a4f2018-10-04 09:06:00 -0400394 SkMatrix44 toXYZD50;
Matt Sarett1950e0a2017-06-12 16:17:30 -0400395 if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {
Matt Sarett5df93de2017-03-22 21:52:47 +0000396 return SkICC::WriteToICC(fn, toXYZD50);
397 }
Matt Sarett5df93de2017-03-22 21:52:47 +0000398 return nullptr;
399}
400
401#endif // SkImageEncoderFns_DEFINED