14ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/*
24ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Copyright 2012 The Android Open Source Project
34ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com *
44ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Use of this source code is governed by a BSD-style license that can be
54ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * found in the LICENSE file.
64ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
75df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett
85df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett#ifndef SkImageEncoderFns_DEFINED
95df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett#define SkImageEncoderFns_DEFINED
104ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
114ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
124ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Functions to transform scanlines between packed-pixel formats.
134ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
144ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
154ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com#include "SkBitmap.h"
164ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com#include "SkColor.h"
17a4083c97d48e8a4f88e2797d7363f141e3d42553Cary Clark#include "SkColorData.h"
185df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett#include "SkICC.h"
192e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett#include "SkOpts.h"
204ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com#include "SkPreConfig.h"
2184014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett#include "SkRasterPipeline.h"
224ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com#include "SkUnPreMultiply.h"
23c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett#include "SkUnPreMultiplyPriv.h"
2445c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein#include "../jumper/SkJumper.h"
254ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
264ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
274ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Function template for transforming scanlines.
284ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform 'width' pixels from 'src' buffer into 'dst' buffer,
294ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * repacking color channel data as appropriate for the given transformation.
30f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * 'bpp' is bytes per pixel in the 'src' buffer.
314ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
32f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msaretttypedef void (*transform_scanline_proc)(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
3362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                        int width, int bpp, const SkPMColor* colors);
344ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
354ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
364ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Identity transformation: just copy bytes from src to dst.
374ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
3862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_memcpy(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
3962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                             int width, int bpp, const SkPMColor*) {
40f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    memcpy(dst, src, width * bpp);
414ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
424ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
4362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_index8_opaque(char* SK_RESTRICT dst,
4462bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                                    const char* SK_RESTRICT src, int width, int,
4562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                                    const SkPMColor* colors) {
4662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    for (int i = 0; i < width; i++) {
4762bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        const uint32_t c = colors[(uint8_t)*src++];
4862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[0] = SkGetPackedR32(c);
4962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[1] = SkGetPackedG32(c);
5062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[2] = SkGetPackedB32(c);
5162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst += 3;
5262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    }
5362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett}
5462bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett
5562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_index8_unpremul(char* SK_RESTRICT dst,
5662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                                      const char* SK_RESTRICT src, int width, int,
5762bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                                      const SkPMColor* colors) {
5862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    uint32_t* SK_RESTRICT dst32 = (uint32_t*) dst;
5962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    for (int i = 0; i < width; i++) {
6062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        // This function swizzles R and B on platforms where SkPMColor is BGRA.  This is
6162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        // exactly what we want.
6262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst32[i] = SkSwizzle_RGBA_to_PMColor(colors[(uint8_t)*src++]);
6362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    }
6462bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett}
6562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett
6662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_gray(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
6762bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor* colors) {
6862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    for (int i = 0; i < width; i++) {
6962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        const uint8_t g = (uint8_t) *src++;
7062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[0] = g;
7162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[1] = g;
7262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[2] = g;
7362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst += 3;
7462bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    }
7562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett}
7662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett
774ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
784ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB.
794ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Alpha channel data is not present in kRGB_565_Config format, so there is no
804ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * alpha channel data to preserve.
814ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
8262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_565(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
8362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                          int width, int, const SkPMColor*) {
84f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint16_t* srcP = (const uint16_t*)src;
854ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
864ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned c = *srcP++;
874ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked16ToR32(c);
884ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked16ToG32(c);
894ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked16ToB32(c);
904ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
914ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
924ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
934ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
94d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed * Transform from kAlpha_8_Config to 2-bytes-per-pixel GrayAlpha.
95d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed */
96d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reedstatic inline void transform_scanline_A8_to_GrayAlpha(char* SK_RESTRICT dst,
97d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed                                                      const char* SK_RESTRICT src,
98d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed                                                      int width, int, const SkPMColor*) {
99d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed    for (int i = 0; i < width; i++) {
100d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed        *dst++ = 0;         // gray (ignored)
101d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed        *dst++ = *src++;    // alpha
102d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed    }
103d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed}
104d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed
105d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed/**
106f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Transform from kRGBA_8888_SkColorType to 3-bytes-per-pixel RGB.
107f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Alpha channel data is abandoned.
108f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
10962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_RGBX(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
11062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
111f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
112f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    for (int i = 0; i < width; i++) {
113f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
114f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  0) & 0xFF;
115f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  8) & 0xFF;
116f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 16) & 0xFF;
117f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    }
118f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
119f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
120f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
121f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Transform from kBGRA_8888_SkColorType to 3-bytes-per-pixel RGB.
122f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Alpha channel data is abandoned.
1234ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
12462bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_BGRX(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
12562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
126f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
1274ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
128f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
129f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 16) & 0xFF;
130f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  8) & 0xFF;
131f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  0) & 0xFF;
1324ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
1334ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
1344ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
1354ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
1364ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB.
1374ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Alpha channel data, if any, is abandoned.
1384ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
13962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_444(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
14062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                          int width, int, const SkPMColor*) {
141f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkPMColor16* srcP = (const SkPMColor16*)src;
1424ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
1434ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        SkPMColor16 c = *srcP++;
1444ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked4444ToR32(c);
1454ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked4444ToG32(c);
1464ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked4444ToB32(c);
1474ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
1484ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
1494ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
1504ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
15184014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from legacy kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
152f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
15362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_rgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
15462bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
155c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett    SkUnpremultiplyRow<false>((uint32_t*) dst, (const uint32_t*) src, width);
156f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
157f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
158f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
15984014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from legacy kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
160f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
16162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_bgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
16262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
163c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett    SkUnpremultiplyRow<true>((uint32_t*) dst, (const uint32_t*) src, width);
164f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
165f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
16684014f03a90d137c0f5c95e15c1e5f8503df7101Matt Saretttemplate <bool kIsRGBA>
1671da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarettstatic inline void transform_scanline_unpremultiply_sRGB(void* dst, const void* src, int width) {
16845c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
16945c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                       dst_ctx = { (void*)dst, 0 };
170b24704d35f67f5b460be9c92794892e06adceb46Mike Klein    SkRasterPipeline_<256> p;
171c2d207603edbbd3809d5144fe4a048a2ad774910Mike Klein    if (kIsRGBA) {
17245c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein        p.append(SkRasterPipeline::load_8888, &src_ctx);
173c2d207603edbbd3809d5144fe4a048a2ad774910Mike Klein    } else {
17445c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein        p.append(SkRasterPipeline::load_bgra, &src_ctx);
17584014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    }
17684014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
177f1f1162273b382db99f8609e5bbfff24f5594821Mike Klein    p.append(SkRasterPipeline::from_srgb);
17884014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append(SkRasterPipeline::unpremul);
17984014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append(SkRasterPipeline::to_srgb);
18045c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::store_8888, &dst_ctx);
18145c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.run(0,0, width,1);
18284014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett}
18384014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
18484014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett/**
1852e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett * Premultiply RGBA to rgbA.
1862e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett */
1872e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarettstatic inline void transform_scanline_to_premul_legacy(char* SK_RESTRICT dst,
1882e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett                                                       const char* SK_RESTRICT src,
1892e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett                                                       int width, int, const SkPMColor*) {
1902e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett    SkOpts::RGBA_to_rgbA((uint32_t*)dst, (const uint32_t*)src, width);
1912e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett}
1922e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett
1932e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett/**
1942e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett * Premultiply RGBA to rgbA linearly.
1952e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett */
1962e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarettstatic inline void transform_scanline_to_premul_linear(char* SK_RESTRICT dst,
1972e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett                                                       const char* SK_RESTRICT src,
1982e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett                                                       int width, int, const SkPMColor*) {
19945c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
20045c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                       dst_ctx = { (void*)dst, 0 };
201b24704d35f67f5b460be9c92794892e06adceb46Mike Klein    SkRasterPipeline_<256> p;
20245c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::load_8888, &src_ctx);
203f1f1162273b382db99f8609e5bbfff24f5594821Mike Klein    p.append(SkRasterPipeline::from_srgb);
2042e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett    p.append(SkRasterPipeline::premul);
2052e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett    p.append(SkRasterPipeline::to_srgb);
20645c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::store_8888, &dst_ctx);
20745c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.run(0,0, width,1);
2082e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett}
2092e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett
2102e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett/**
21184014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
21284014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett */
21362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_srgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
21462bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                            int width, int, const SkPMColor*) {
2151da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    transform_scanline_unpremultiply_sRGB<true>(dst, src, width);
21684014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett}
21784014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
21884014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett/**
21984014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
22084014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett */
22162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_sbgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
22262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                            int width, int, const SkPMColor*) {
2231da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    transform_scanline_unpremultiply_sRGB<false>(dst, src, width);
22484014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett}
22584014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
226f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
227f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Transform from kUnpremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
228f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
22962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_BGRA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
23062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
231f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
232f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    for (int i = 0; i < width; i++) {
233f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
234f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 16) & 0xFF;
235f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  8) & 0xFF;
236f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  0) & 0xFF;
237f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 24) & 0xFF;
238f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    }
239f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
240f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
241f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
2424ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA,
2434ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * with scaling of RGB based on alpha channel.
2444ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
24562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_4444(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
24662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
247f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkPMColor16* srcP = (const SkPMColor16*)src;
248f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
2494ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
2504ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
2514ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        SkPMColor16 c = *srcP++;
2524ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned a = SkPacked4444ToA32(c);
2534ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned r = SkPacked4444ToR32(c);
2544ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned g = SkPacked4444ToG32(c);
2554ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned b = SkPacked4444ToB32(c);
2564ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
2574ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        if (0 != a && 255 != a) {
2584ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            SkUnPreMultiply::Scale scale = table[a];
2594ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            r = SkUnPreMultiply::ApplyScale(scale, r);
2604ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            g = SkUnPreMultiply::ApplyScale(scale, g);
2614ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            b = SkUnPreMultiply::ApplyScale(scale, b);
2624ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        }
2634ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = r;
2644ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = g;
2654ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = b;
2664ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = a;
2674ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
2684ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
2691da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett
270ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein// 888x is opaque RGB in four bytes, with 8 junk bits.  We convert that to 3 byte RGB.
271ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Kleinstatic inline void transform_scanline_888x(char* dst, const char* src,
272ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein                                           int width, int, const SkPMColor*) {
273ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    while (width --> 0) {
274ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        dst[0] = src[0];
275ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        dst[1] = src[1];
276ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        dst[2] = src[2];
277ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        dst += 3;
278ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        src += 4;
279ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    }
280ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein}
281ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein
282ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein// 101010x is opaque RGB in four bytes, with 2 bits junk.  We convert to 6 byte RGB (big endian).
283ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Kleinstatic inline void transform_scanline_101010x(char* dst, const char* src,
284ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein                                              int width, int, const SkPMColor*) {
285ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    auto d = (      uint16_t*)dst;
286ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    auto s = (const uint32_t*)src;
287ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    while (width --> 0) {
288ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        uint32_t r = (*s >>  0) & 1023,
289ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein                 g = (*s >> 10) & 1023,
290ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein                 b = (*s >> 20) & 1023;
291ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein
292ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        // Scale 10-bit unorms to 16-bit by replicating the most significant bits.
293ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        r = (r << 6) | (r >> 4);
294ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        g = (g << 6) | (g >> 4);
295ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        b = (b << 6) | (b >> 4);
296ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein
297ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        // Store big-endian.
298ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        d[0] = (r >> 8) | (r << 8);
299ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        d[1] = (g >> 8) | (g << 8);
300ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        d[2] = (b >> 8) | (b << 8);
301ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein
302ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        d += 3;  // 3 channels
303ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein        s += 1;  // 1 whole pixel
304ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    }
305ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein}
306ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein
307ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Kleinstatic inline void transform_scanline_1010102(char* dst, const char* src,
308ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein                                              int width, int, const SkPMColor*) {
309ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
310ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein                       dst_ctx = { (void*)dst, 0 };
311ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    SkRasterPipeline_<256> p;
312ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    p.append(SkRasterPipeline::load_1010102, &src_ctx);
313ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
314ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    p.run(0,0, width,1);
315ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein}
316ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein
317ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Kleinstatic inline void transform_scanline_1010102_premul(char* dst, const char* src,
318ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein                                                     int width, int, const SkPMColor*) {
319ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
320ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein                       dst_ctx = { (void*)dst, 0 };
321ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    SkRasterPipeline_<256> p;
322ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    p.append(SkRasterPipeline::load_1010102, &src_ctx);
323ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    p.append(SkRasterPipeline::unpremul);
324ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
325ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein    p.run(0,0, width,1);
326ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein}
327ac568a934f8f82bf3a359b757d67eb3a797d3593Mike Klein
3281da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett/**
32955213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett * Transform from kRGBA_F16 to 8-bytes-per-pixel RGBA.
3301da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett */
33162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_F16(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
33262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                          int width, int, const SkPMColor*) {
33345c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
33445c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                       dst_ctx = { (void*)dst, 0 };
335b24704d35f67f5b460be9c92794892e06adceb46Mike Klein    SkRasterPipeline_<256> p;
33645c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::load_f16, &src_ctx);
337ce98801bbb5ac251b374f8b565445add43017aaaMike Klein    p.append(SkRasterPipeline::clamp_0);  // F16 values may be out of [0,1] range, so clamp.
338ce98801bbb5ac251b374f8b565445add43017aaaMike Klein    p.append(SkRasterPipeline::clamp_1);
3391950e0a868774330330555a9a368992218f42240Matt Sarett    p.append(SkRasterPipeline::to_srgb);
34045c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
34145c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.run(0,0, width,1);
3421da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett}
3431da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett
3441da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett/**
34555213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett * Transform from kPremul, kRGBA_F16 to 8-bytes-per-pixel RGBA.
3461da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett */
34762bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_F16_premul(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
34862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                                 int width, int, const SkPMColor*) {
34945c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
35045c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                       dst_ctx = { (void*)dst, 0 };
351b24704d35f67f5b460be9c92794892e06adceb46Mike Klein    SkRasterPipeline_<256> p;
35245c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::load_f16, &src_ctx);
3531da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::unpremul);
354ce98801bbb5ac251b374f8b565445add43017aaaMike Klein    p.append(SkRasterPipeline::clamp_0);  // F16 values may be out of [0,1] range, so clamp.
355ce98801bbb5ac251b374f8b565445add43017aaaMike Klein    p.append(SkRasterPipeline::clamp_1);
3561950e0a868774330330555a9a368992218f42240Matt Sarett    p.append(SkRasterPipeline::to_srgb);
35745c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
35845c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.run(0,0, width,1);
3591da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett}
36055213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett
36155213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett/**
36255213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett * Transform from kRGBA_F16 to 4-bytes-per-pixel RGBA.
36355213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett */
36455213562f9a63cbc324833fdd1c16cc79646515aMatt Sarettstatic inline void transform_scanline_F16_to_8888(char* SK_RESTRICT dst,
36555213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett                                                  const char* SK_RESTRICT src, int width, int,
36655213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett                                                  const SkPMColor*) {
36745c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
36845c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                       dst_ctx = { (void*)dst, 0 };
369b24704d35f67f5b460be9c92794892e06adceb46Mike Klein    SkRasterPipeline_<256> p;
37045c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::load_f16, &src_ctx);
371ce98801bbb5ac251b374f8b565445add43017aaaMike Klein    p.append(SkRasterPipeline::clamp_0);  // F16 values may be out of [0,1] range, so clamp.
372ce98801bbb5ac251b374f8b565445add43017aaaMike Klein    p.append(SkRasterPipeline::clamp_1);
37355213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.append(SkRasterPipeline::to_srgb);
37445c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::store_8888, &dst_ctx);
37545c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.run(0,0, width,1);
37655213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett}
37755213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett
37855213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett/**
37955213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett * Transform from kPremul, kRGBA_F16 to 4-bytes-per-pixel RGBA.
38055213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett */
38155213562f9a63cbc324833fdd1c16cc79646515aMatt Sarettstatic inline void transform_scanline_F16_premul_to_8888(char* SK_RESTRICT dst,
38255213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett                                                         const char* SK_RESTRICT src, int width,
38355213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett                                                         int, const SkPMColor*) {
38445c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
38545c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                       dst_ctx = { (void*)dst, 0 };
386b24704d35f67f5b460be9c92794892e06adceb46Mike Klein    SkRasterPipeline_<256> p;
38745c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::load_f16, &src_ctx);
38855213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.append(SkRasterPipeline::unpremul);
389ce98801bbb5ac251b374f8b565445add43017aaaMike Klein    p.append(SkRasterPipeline::clamp_0);  // F16 values may be out of [0,1] range, so clamp.
390ce98801bbb5ac251b374f8b565445add43017aaaMike Klein    p.append(SkRasterPipeline::clamp_1);
39155213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.append(SkRasterPipeline::to_srgb);
39245c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::store_8888, &dst_ctx);
39345c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.run(0,0, width,1);
39455213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett}
3955df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett
3962e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett/**
3972e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett * Transform from kUnpremul, kRGBA_F16 to premultiplied rgbA 8888.
3982e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett */
3992e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarettstatic inline void transform_scanline_F16_to_premul_8888(char* SK_RESTRICT dst,
4002e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett        const char* SK_RESTRICT src, int width, int, const SkPMColor*) {
40145c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
40245c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein                       dst_ctx = { (void*)dst, 0 };
403b24704d35f67f5b460be9c92794892e06adceb46Mike Klein    SkRasterPipeline_<256> p;
40445c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::load_f16, &src_ctx);
405ce98801bbb5ac251b374f8b565445add43017aaaMike Klein    p.append(SkRasterPipeline::clamp_0);  // F16 values may be out of [0,1] range, so clamp.
406ce98801bbb5ac251b374f8b565445add43017aaaMike Klein    p.append(SkRasterPipeline::clamp_1);
4072e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett    p.append(SkRasterPipeline::premul);
4082e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett    p.append(SkRasterPipeline::to_srgb);
40945c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.append(SkRasterPipeline::store_8888, &dst_ctx);
41045c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein    p.run(0,0, width,1);
4112e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett}
4122e61b182dad86e592d12c8a73ffcc7555a6e11a2Matt Sarett
4131950e0a868774330330555a9a368992218f42240Matt Sarettstatic inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
4141950e0a868774330330555a9a368992218f42240Matt Sarett    SkColorSpace* cs = info.colorSpace();
4151950e0a868774330330555a9a368992218f42240Matt Sarett    if (!cs) {
4161950e0a868774330330555a9a368992218f42240Matt Sarett        return nullptr;
4171950e0a868774330330555a9a368992218f42240Matt Sarett    }
4181950e0a868774330330555a9a368992218f42240Matt Sarett
4191950e0a868774330330555a9a368992218f42240Matt Sarett    sk_sp<SkColorSpace> owned;
4201950e0a868774330330555a9a368992218f42240Matt Sarett    if (kRGBA_F16_SkColorType == info.colorType()) {
42136703d9d368050a20764b5336534bd718fd00a6eBrian Osman        owned = cs->makeSRGBGamma();
4221950e0a868774330330555a9a368992218f42240Matt Sarett        cs = owned.get();
4231950e0a868774330330555a9a368992218f42240Matt Sarett    }
4241950e0a868774330330555a9a368992218f42240Matt Sarett
4255df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett    SkColorSpaceTransferFn fn;
4265df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett    SkMatrix44 toXYZD50(SkMatrix44::kUninitialized_Constructor);
4271950e0a868774330330555a9a368992218f42240Matt Sarett    if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {
4285df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett        return SkICC::WriteToICC(fn, toXYZD50);
4295df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett    }
4305df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett
4315df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett    // TODO: Should we support writing ICC profiles for additional color spaces?
4325df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett    return nullptr;
4335df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett}
4345df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett
4355df93de8ad968b4e25708964e558979375eeaa9eMatt Sarett#endif  // SkImageEncoderFns_DEFINED
436