blob: dd02ebf78bf6e4ce9bddbfcbce791351cb7b86a2 [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 Sarett1950e0a2017-06-12 16:17:30 -040018#include "SkColorSpace_Base.h"
Matt Sarett5df93de2017-03-22 21:52:47 +000019#include "SkICC.h"
Matt Sarett2e61b182017-05-09 12:46:50 -040020#include "SkOpts.h"
epoger@google.com4ce738b2012-11-16 18:44:18 +000021#include "SkPreConfig.h"
Matt Sarett84014f02017-01-10 11:28:54 -050022#include "SkRasterPipeline.h"
epoger@google.com4ce738b2012-11-16 18:44:18 +000023#include "SkUnPreMultiply.h"
Matt Sarettc7b29082017-02-09 16:22:39 -050024#include "SkUnPreMultiplyPriv.h"
Mike Klein45c16fa2017-07-18 18:15:13 -040025#include "../jumper/SkJumper.h"
epoger@google.com4ce738b2012-11-16 18:44:18 +000026
27/**
28 * Function template for transforming scanlines.
29 * Transform 'width' pixels from 'src' buffer into 'dst' buffer,
30 * repacking color channel data as appropriate for the given transformation.
msarettf17b71f2016-09-12 14:30:03 -070031 * 'bpp' is bytes per pixel in the 'src' buffer.
epoger@google.com4ce738b2012-11-16 18:44:18 +000032 */
msarettf17b71f2016-09-12 14:30:03 -070033typedef void (*transform_scanline_proc)(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
Matt Sarett62bb2802017-01-23 12:28:02 -050034 int width, int bpp, const SkPMColor* colors);
epoger@google.com4ce738b2012-11-16 18:44:18 +000035
36/**
37 * Identity transformation: just copy bytes from src to dst.
38 */
Matt Sarett62bb2802017-01-23 12:28:02 -050039static inline void transform_scanline_memcpy(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
40 int width, int bpp, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -070041 memcpy(dst, src, width * bpp);
epoger@google.com4ce738b2012-11-16 18:44:18 +000042}
43
Matt Sarett62bb2802017-01-23 12:28:02 -050044static inline void transform_scanline_index8_opaque(char* SK_RESTRICT dst,
45 const char* SK_RESTRICT src, int width, int,
46 const SkPMColor* colors) {
47 for (int i = 0; i < width; i++) {
48 const uint32_t c = colors[(uint8_t)*src++];
49 dst[0] = SkGetPackedR32(c);
50 dst[1] = SkGetPackedG32(c);
51 dst[2] = SkGetPackedB32(c);
52 dst += 3;
53 }
54}
55
56static inline void transform_scanline_index8_unpremul(char* SK_RESTRICT dst,
57 const char* SK_RESTRICT src, int width, int,
58 const SkPMColor* colors) {
59 uint32_t* SK_RESTRICT dst32 = (uint32_t*) dst;
60 for (int i = 0; i < width; i++) {
61 // This function swizzles R and B on platforms where SkPMColor is BGRA. This is
62 // exactly what we want.
63 dst32[i] = SkSwizzle_RGBA_to_PMColor(colors[(uint8_t)*src++]);
64 }
65}
66
67static inline void transform_scanline_gray(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
68 int width, int, const SkPMColor* colors) {
69 for (int i = 0; i < width; i++) {
70 const uint8_t g = (uint8_t) *src++;
71 dst[0] = g;
72 dst[1] = g;
73 dst[2] = g;
74 dst += 3;
75 }
76}
77
epoger@google.com4ce738b2012-11-16 18:44:18 +000078/**
79 * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB.
80 * Alpha channel data is not present in kRGB_565_Config format, so there is no
81 * alpha channel data to preserve.
82 */
Matt Sarett62bb2802017-01-23 12:28:02 -050083static inline void transform_scanline_565(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
84 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -070085 const uint16_t* srcP = (const uint16_t*)src;
epoger@google.com4ce738b2012-11-16 18:44:18 +000086 for (int i = 0; i < width; i++) {
87 unsigned c = *srcP++;
88 *dst++ = SkPacked16ToR32(c);
89 *dst++ = SkPacked16ToG32(c);
90 *dst++ = SkPacked16ToB32(c);
91 }
92}
93
94/**
Mike Reedd6cb11e2017-11-30 15:33:04 -050095 * Transform from kAlpha_8_Config to 2-bytes-per-pixel GrayAlpha.
96 */
97static inline void transform_scanline_A8_to_GrayAlpha(char* SK_RESTRICT dst,
98 const char* SK_RESTRICT src,
99 int width, int, const SkPMColor*) {
100 for (int i = 0; i < width; i++) {
101 *dst++ = 0; // gray (ignored)
102 *dst++ = *src++; // alpha
103 }
104}
105
106/**
msarettf17b71f2016-09-12 14:30:03 -0700107 * Transform from kRGBA_8888_SkColorType to 3-bytes-per-pixel RGB.
108 * Alpha channel data is abandoned.
epoger@google.com4ce738b2012-11-16 18:44:18 +0000109 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500110static inline void transform_scanline_RGBX(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
111 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -0700112 const uint32_t* srcP = (const SkPMColor*)src;
epoger@google.com4ce738b2012-11-16 18:44:18 +0000113 for (int i = 0; i < width; i++) {
msarettf17b71f2016-09-12 14:30:03 -0700114 uint32_t c = *srcP++;
115 *dst++ = (c >> 0) & 0xFF;
116 *dst++ = (c >> 8) & 0xFF;
117 *dst++ = (c >> 16) & 0xFF;
118 }
119}
120
121/**
122 * Transform from kBGRA_8888_SkColorType to 3-bytes-per-pixel RGB.
123 * Alpha channel data is abandoned.
124 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500125static inline void transform_scanline_BGRX(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
126 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -0700127 const uint32_t* srcP = (const SkPMColor*)src;
128 for (int i = 0; i < width; i++) {
129 uint32_t c = *srcP++;
130 *dst++ = (c >> 16) & 0xFF;
131 *dst++ = (c >> 8) & 0xFF;
132 *dst++ = (c >> 0) & 0xFF;
epoger@google.com4ce738b2012-11-16 18:44:18 +0000133 }
134}
135
136/**
137 * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB.
138 * Alpha channel data, if any, is abandoned.
139 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500140static inline void transform_scanline_444(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
141 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -0700142 const SkPMColor16* srcP = (const SkPMColor16*)src;
epoger@google.com4ce738b2012-11-16 18:44:18 +0000143 for (int i = 0; i < width; i++) {
144 SkPMColor16 c = *srcP++;
145 *dst++ = SkPacked4444ToR32(c);
146 *dst++ = SkPacked4444ToG32(c);
147 *dst++ = SkPacked4444ToB32(c);
148 }
149}
150
epoger@google.com4ce738b2012-11-16 18:44:18 +0000151/**
Matt Sarett84014f02017-01-10 11:28:54 -0500152 * Transform from legacy kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
153 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500154static inline void transform_scanline_rgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
155 int width, int, const SkPMColor*) {
Matt Sarettc7b29082017-02-09 16:22:39 -0500156 SkUnpremultiplyRow<false>((uint32_t*) dst, (const uint32_t*) src, width);
Matt Sarett84014f02017-01-10 11:28:54 -0500157}
158
159/**
160 * Transform from legacy kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
161 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500162static inline void transform_scanline_bgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
163 int width, int, const SkPMColor*) {
Matt Sarettc7b29082017-02-09 16:22:39 -0500164 SkUnpremultiplyRow<true>((uint32_t*) dst, (const uint32_t*) src, width);
Matt Sarett84014f02017-01-10 11:28:54 -0500165}
166
167template <bool kIsRGBA>
Matt Sarett1da27ef2017-01-19 17:14:07 -0500168static inline void transform_scanline_unpremultiply_sRGB(void* dst, const void* src, int width) {
Mike Klein45c16fa2017-07-18 18:15:13 -0400169 SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
170 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400171 SkRasterPipeline_<256> p;
Mike Kleinc2d20762017-06-27 19:53:21 -0400172 if (kIsRGBA) {
Mike Klein45c16fa2017-07-18 18:15:13 -0400173 p.append(SkRasterPipeline::load_8888, &src_ctx);
Mike Kleinc2d20762017-06-27 19:53:21 -0400174 } else {
Mike Klein45c16fa2017-07-18 18:15:13 -0400175 p.append(SkRasterPipeline::load_bgra, &src_ctx);
Matt Sarett84014f02017-01-10 11:28:54 -0500176 }
177
178 p.append_from_srgb(kPremul_SkAlphaType);
179 p.append(SkRasterPipeline::unpremul);
180 p.append(SkRasterPipeline::to_srgb);
Mike Klein45c16fa2017-07-18 18:15:13 -0400181 p.append(SkRasterPipeline::store_8888, &dst_ctx);
182 p.run(0,0, width,1);
Matt Sarett84014f02017-01-10 11:28:54 -0500183}
184
185/**
Matt Sarett2e61b182017-05-09 12:46:50 -0400186 * Premultiply RGBA to rgbA.
187 */
188static inline void transform_scanline_to_premul_legacy(char* SK_RESTRICT dst,
189 const char* SK_RESTRICT src,
190 int width, int, const SkPMColor*) {
191 SkOpts::RGBA_to_rgbA((uint32_t*)dst, (const uint32_t*)src, width);
192}
193
194/**
195 * Premultiply RGBA to rgbA linearly.
196 */
197static inline void transform_scanline_to_premul_linear(char* SK_RESTRICT dst,
198 const char* SK_RESTRICT src,
199 int width, int, const SkPMColor*) {
Mike Klein45c16fa2017-07-18 18:15:13 -0400200 SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
201 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400202 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400203 p.append(SkRasterPipeline::load_8888, &src_ctx);
Matt Sarett2e61b182017-05-09 12:46:50 -0400204 p.append_from_srgb(kUnpremul_SkAlphaType);
205 p.append(SkRasterPipeline::premul);
206 p.append(SkRasterPipeline::to_srgb);
Mike Klein45c16fa2017-07-18 18:15:13 -0400207 p.append(SkRasterPipeline::store_8888, &dst_ctx);
208 p.run(0,0, width,1);
Matt Sarett2e61b182017-05-09 12:46:50 -0400209}
210
211/**
msarettf17b71f2016-09-12 14:30:03 -0700212 * Transform from kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
213 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500214static inline void transform_scanline_srgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
215 int width, int, const SkPMColor*) {
Matt Sarett1da27ef2017-01-19 17:14:07 -0500216 transform_scanline_unpremultiply_sRGB<true>(dst, src, width);
msarettf17b71f2016-09-12 14:30:03 -0700217}
218
219/**
220 * Transform from kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
221 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500222static inline void transform_scanline_sbgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
223 int width, int, const SkPMColor*) {
Matt Sarett1da27ef2017-01-19 17:14:07 -0500224 transform_scanline_unpremultiply_sRGB<false>(dst, src, width);
msarettf17b71f2016-09-12 14:30:03 -0700225}
226
227/**
228 * Transform from kUnpremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
229 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500230static inline void transform_scanline_BGRA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
231 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -0700232 const uint32_t* srcP = (const SkPMColor*)src;
233 for (int i = 0; i < width; i++) {
234 uint32_t c = *srcP++;
235 *dst++ = (c >> 16) & 0xFF;
236 *dst++ = (c >> 8) & 0xFF;
237 *dst++ = (c >> 0) & 0xFF;
238 *dst++ = (c >> 24) & 0xFF;
239 }
240}
241
242/**
epoger@google.com4ce738b2012-11-16 18:44:18 +0000243 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA,
244 * with scaling of RGB based on alpha channel.
245 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500246static inline void transform_scanline_4444(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
247 int width, int, const SkPMColor*) {
msarettf17b71f2016-09-12 14:30:03 -0700248 const SkPMColor16* srcP = (const SkPMColor16*)src;
249 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
epoger@google.com4ce738b2012-11-16 18:44:18 +0000250
251 for (int i = 0; i < width; i++) {
252 SkPMColor16 c = *srcP++;
253 unsigned a = SkPacked4444ToA32(c);
254 unsigned r = SkPacked4444ToR32(c);
255 unsigned g = SkPacked4444ToG32(c);
256 unsigned b = SkPacked4444ToB32(c);
257
258 if (0 != a && 255 != a) {
259 SkUnPreMultiply::Scale scale = table[a];
260 r = SkUnPreMultiply::ApplyScale(scale, r);
261 g = SkUnPreMultiply::ApplyScale(scale, g);
262 b = SkUnPreMultiply::ApplyScale(scale, b);
263 }
264 *dst++ = r;
265 *dst++ = g;
266 *dst++ = b;
267 *dst++ = a;
268 }
269}
Matt Sarett1da27ef2017-01-19 17:14:07 -0500270
271/**
Matt Sarett55213562017-01-23 19:37:37 -0500272 * Transform from kRGBA_F16 to 8-bytes-per-pixel RGBA.
Matt Sarett1da27ef2017-01-19 17:14:07 -0500273 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500274static inline void transform_scanline_F16(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
275 int width, int, const SkPMColor*) {
Mike Klein45c16fa2017-07-18 18:15:13 -0400276 SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
277 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400278 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400279 p.append(SkRasterPipeline::load_f16, &src_ctx);
Mike Kleince988012017-07-21 13:11:37 -0400280 p.append(SkRasterPipeline::clamp_0); // F16 values may be out of [0,1] range, so clamp.
281 p.append(SkRasterPipeline::clamp_1);
Matt Sarett1950e0a2017-06-12 16:17:30 -0400282 p.append(SkRasterPipeline::to_srgb);
Mike Klein45c16fa2017-07-18 18:15:13 -0400283 p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
284 p.run(0,0, width,1);
Matt Sarett1da27ef2017-01-19 17:14:07 -0500285}
286
287/**
Matt Sarett55213562017-01-23 19:37:37 -0500288 * Transform from kPremul, kRGBA_F16 to 8-bytes-per-pixel RGBA.
Matt Sarett1da27ef2017-01-19 17:14:07 -0500289 */
Matt Sarett62bb2802017-01-23 12:28:02 -0500290static inline void transform_scanline_F16_premul(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
291 int width, int, const SkPMColor*) {
Mike Klein45c16fa2017-07-18 18:15:13 -0400292 SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
293 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400294 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400295 p.append(SkRasterPipeline::load_f16, &src_ctx);
Matt Sarett1da27ef2017-01-19 17:14:07 -0500296 p.append(SkRasterPipeline::unpremul);
Mike Kleince988012017-07-21 13:11:37 -0400297 p.append(SkRasterPipeline::clamp_0); // F16 values may be out of [0,1] range, so clamp.
298 p.append(SkRasterPipeline::clamp_1);
Matt Sarett1950e0a2017-06-12 16:17:30 -0400299 p.append(SkRasterPipeline::to_srgb);
Mike Klein45c16fa2017-07-18 18:15:13 -0400300 p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
301 p.run(0,0, width,1);
Matt Sarett1da27ef2017-01-19 17:14:07 -0500302}
Matt Sarett55213562017-01-23 19:37:37 -0500303
304/**
305 * Transform from kRGBA_F16 to 4-bytes-per-pixel RGBA.
306 */
307static inline void transform_scanline_F16_to_8888(char* SK_RESTRICT dst,
308 const char* SK_RESTRICT src, int width, int,
309 const SkPMColor*) {
Mike Klein45c16fa2017-07-18 18:15:13 -0400310 SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
311 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400312 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400313 p.append(SkRasterPipeline::load_f16, &src_ctx);
Mike Kleince988012017-07-21 13:11:37 -0400314 p.append(SkRasterPipeline::clamp_0); // F16 values may be out of [0,1] range, so clamp.
315 p.append(SkRasterPipeline::clamp_1);
Matt Sarett55213562017-01-23 19:37:37 -0500316 p.append(SkRasterPipeline::to_srgb);
Mike Klein45c16fa2017-07-18 18:15:13 -0400317 p.append(SkRasterPipeline::store_8888, &dst_ctx);
318 p.run(0,0, width,1);
Matt Sarett55213562017-01-23 19:37:37 -0500319}
320
321/**
322 * Transform from kPremul, kRGBA_F16 to 4-bytes-per-pixel RGBA.
323 */
324static inline void transform_scanline_F16_premul_to_8888(char* SK_RESTRICT dst,
325 const char* SK_RESTRICT src, int width,
326 int, const SkPMColor*) {
Mike Klein45c16fa2017-07-18 18:15:13 -0400327 SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
328 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400329 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400330 p.append(SkRasterPipeline::load_f16, &src_ctx);
Matt Sarett55213562017-01-23 19:37:37 -0500331 p.append(SkRasterPipeline::unpremul);
Mike Kleince988012017-07-21 13:11:37 -0400332 p.append(SkRasterPipeline::clamp_0); // F16 values may be out of [0,1] range, so clamp.
333 p.append(SkRasterPipeline::clamp_1);
Matt Sarett55213562017-01-23 19:37:37 -0500334 p.append(SkRasterPipeline::to_srgb);
Mike Klein45c16fa2017-07-18 18:15:13 -0400335 p.append(SkRasterPipeline::store_8888, &dst_ctx);
336 p.run(0,0, width,1);
Matt Sarett55213562017-01-23 19:37:37 -0500337}
Matt Sarett5df93de2017-03-22 21:52:47 +0000338
Matt Sarett2e61b182017-05-09 12:46:50 -0400339/**
340 * Transform from kUnpremul, kRGBA_F16 to premultiplied rgbA 8888.
341 */
342static inline void transform_scanline_F16_to_premul_8888(char* SK_RESTRICT dst,
343 const char* SK_RESTRICT src, int width, int, const SkPMColor*) {
Mike Klein45c16fa2017-07-18 18:15:13 -0400344 SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
345 dst_ctx = { (void*)dst, 0 };
Mike Kleinb24704d2017-05-24 07:53:00 -0400346 SkRasterPipeline_<256> p;
Mike Klein45c16fa2017-07-18 18:15:13 -0400347 p.append(SkRasterPipeline::load_f16, &src_ctx);
Mike Kleince988012017-07-21 13:11:37 -0400348 p.append(SkRasterPipeline::clamp_0); // F16 values may be out of [0,1] range, so clamp.
349 p.append(SkRasterPipeline::clamp_1);
Matt Sarett2e61b182017-05-09 12:46:50 -0400350 p.append(SkRasterPipeline::premul);
351 p.append(SkRasterPipeline::to_srgb);
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
Matt Sarett1950e0a2017-06-12 16:17:30 -0400356static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
357 SkColorSpace* cs = info.colorSpace();
358 if (!cs) {
359 return nullptr;
360 }
361
362 sk_sp<SkColorSpace> owned;
363 if (kRGBA_F16_SkColorType == info.colorType()) {
364 owned = as_CSB(cs)->makeSRGBGamma();
365 cs = owned.get();
366 }
367
Matt Sarett5df93de2017-03-22 21:52:47 +0000368 SkColorSpaceTransferFn fn;
369 SkMatrix44 toXYZD50(SkMatrix44::kUninitialized_Constructor);
Matt Sarett1950e0a2017-06-12 16:17:30 -0400370 if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {
Matt Sarett5df93de2017-03-22 21:52:47 +0000371 return SkICC::WriteToICC(fn, toXYZD50);
372 }
373
374 // TODO: Should we support writing ICC profiles for additional color spaces?
375 return nullptr;
376}
377
378#endif // SkImageEncoderFns_DEFINED