SkImageEncoderFns.h revision 1da27ef853ae3e701b7f4aae670c21684396dcce
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 */
74ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
84ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
94ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Functions to transform scanlines between packed-pixel formats.
104ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
114ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
124ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com#include "SkBitmap.h"
134ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com#include "SkColor.h"
144ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com#include "SkColorPriv.h"
154ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com#include "SkPreConfig.h"
1684014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett#include "SkRasterPipeline.h"
174ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com#include "SkUnPreMultiply.h"
184ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
194ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
204ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Function template for transforming scanlines.
214ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform 'width' pixels from 'src' buffer into 'dst' buffer,
224ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * repacking color channel data as appropriate for the given transformation.
23f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * 'bpp' is bytes per pixel in the 'src' buffer.
244ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
25f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msaretttypedef void (*transform_scanline_proc)(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
26f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett                                        int width, int bpp);
274ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
284ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
294ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Identity transformation: just copy bytes from src to dst.
304ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
31f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarettstatic void transform_scanline_memcpy(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
32f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett                                      int width, int bpp) {
33f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    memcpy(dst, src, width * bpp);
344ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
354ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
364ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
374ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB.
384ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Alpha channel data is not present in kRGB_565_Config format, so there is no
394ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * alpha channel data to preserve.
404ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
41f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarettstatic void transform_scanline_565(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
42f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett                                   int width, int) {
43f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint16_t* srcP = (const uint16_t*)src;
444ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
454ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned c = *srcP++;
464ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked16ToR32(c);
474ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked16ToG32(c);
484ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked16ToB32(c);
494ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
504ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
514ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
524ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
53f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Transform from kRGBA_8888_SkColorType to 3-bytes-per-pixel RGB.
54f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Alpha channel data is abandoned.
55f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
56f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarettstatic void transform_scanline_RGBX(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
57f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett                                    int width, int) {
58f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
59f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    for (int i = 0; i < width; i++) {
60f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
61f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  0) & 0xFF;
62f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  8) & 0xFF;
63f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 16) & 0xFF;
64f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    }
65f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
66f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
67f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
68f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Transform from kBGRA_8888_SkColorType to 3-bytes-per-pixel RGB.
69f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Alpha channel data is abandoned.
704ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
71f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarettstatic void transform_scanline_BGRX(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
72f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett                                    int width, int) {
73f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
744ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
75f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
76f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 16) & 0xFF;
77f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  8) & 0xFF;
78f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  0) & 0xFF;
794ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
804ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
814ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
824ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
834ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB.
844ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Alpha channel data, if any, is abandoned.
854ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
86f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarettstatic void transform_scanline_444(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
87f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett                                   int width, int) {
88f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkPMColor16* srcP = (const SkPMColor16*)src;
894ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
904ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        SkPMColor16 c = *srcP++;
914ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked4444ToR32(c);
924ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked4444ToG32(c);
934ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked4444ToB32(c);
944ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
954ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
964ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
97f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msaretttemplate <bool kIsRGBA>
98f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarettstatic inline void transform_scanline_unpremultiply(char* SK_RESTRICT dst,
991da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett                                                    const char* SK_RESTRICT src, int width) {
100f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
101f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
1024ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
1034ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
104f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
105f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        unsigned r, g, b, a;
106f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        if (kIsRGBA) {
107f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            r = (c >>  0) & 0xFF;
108f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            g = (c >>  8) & 0xFF;
109f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            b = (c >> 16) & 0xFF;
110f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            a = (c >> 24) & 0xFF;
111f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        } else {
112f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            r = (c >> 16) & 0xFF;
113f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            g = (c >>  8) & 0xFF;
114f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            b = (c >>  0) & 0xFF;
115f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            a = (c >> 24) & 0xFF;
116f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        }
1174ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
1184ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        if (0 != a && 255 != a) {
1194ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            SkUnPreMultiply::Scale scale = table[a];
1204ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            r = SkUnPreMultiply::ApplyScale(scale, r);
1214ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            g = SkUnPreMultiply::ApplyScale(scale, g);
1224ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            b = SkUnPreMultiply::ApplyScale(scale, b);
1234ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        }
1244ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = r;
1254ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = g;
1264ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = b;
1274ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = a;
1284ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
1294ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
1304ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
1314ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
13284014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from legacy kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
133f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
13484014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarettstatic void transform_scanline_rgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src, int width,
1351da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett                                    int) {
1361da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    transform_scanline_unpremultiply<true>(dst, src, width);
137f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
138f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
139f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
14084014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from legacy kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
141f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
14284014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarettstatic void transform_scanline_bgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src, int width,
1431da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett                                    int) {
1441da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    transform_scanline_unpremultiply<false>(dst, src, width);
145f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
146f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
14784014f03a90d137c0f5c95e15c1e5f8503df7101Matt Saretttemplate <bool kIsRGBA>
1481da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarettstatic inline void transform_scanline_unpremultiply_sRGB(void* dst, const void* src, int width) {
14984014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    SkRasterPipeline p;
15084014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append(SkRasterPipeline::load_8888, &src);
15184014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    if (!kIsRGBA) {
15284014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett        p.append(SkRasterPipeline::swap_rb);
15384014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    }
15484014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
15584014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append_from_srgb(kPremul_SkAlphaType);
15684014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append(SkRasterPipeline::unpremul);
15784014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append(SkRasterPipeline::to_srgb);
15884014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append(SkRasterPipeline::store_8888, &dst);
15984014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.run(0, 0, width);
16084014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett}
16184014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
16284014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett/**
16384014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
16484014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett */
16584014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarettstatic void transform_scanline_srgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
1661da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett                                     int width, int) {
1671da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    transform_scanline_unpremultiply_sRGB<true>(dst, src, width);
16884014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett}
16984014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
17084014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett/**
17184014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
17284014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett */
17384014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarettstatic void transform_scanline_sbgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
1741da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett                                     int width, int) {
1751da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    transform_scanline_unpremultiply_sRGB<false>(dst, src, width);
17684014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett}
17784014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
178f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
179f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Transform from kUnpremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
180f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
181f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarettstatic void transform_scanline_BGRA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
182f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett                                    int width, int) {
183f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
184f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    for (int i = 0; i < width; i++) {
185f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
186f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 16) & 0xFF;
187f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  8) & 0xFF;
188f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  0) & 0xFF;
189f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 24) & 0xFF;
190f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    }
191f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
192f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
193f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
1944ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA,
1954ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * with scaling of RGB based on alpha channel.
1964ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
197f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarettstatic void transform_scanline_4444(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
198f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett                                    int width, int) {
199f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkPMColor16* srcP = (const SkPMColor16*)src;
200f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
2014ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
2024ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
2034ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        SkPMColor16 c = *srcP++;
2044ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned a = SkPacked4444ToA32(c);
2054ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned r = SkPacked4444ToR32(c);
2064ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned g = SkPacked4444ToG32(c);
2074ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned b = SkPacked4444ToB32(c);
2084ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
2094ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        if (0 != a && 255 != a) {
2104ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            SkUnPreMultiply::Scale scale = table[a];
2114ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            r = SkUnPreMultiply::ApplyScale(scale, r);
2124ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            g = SkUnPreMultiply::ApplyScale(scale, g);
2134ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            b = SkUnPreMultiply::ApplyScale(scale, b);
2144ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        }
2154ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = r;
2164ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = g;
2174ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = b;
2184ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = a;
2194ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
2204ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
2211da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett
2221da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett/**
2231da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett * Transform from kRGBA_F16 to 4-bytes-per-pixel RGBA.
2241da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett */
2251da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarettstatic void transform_scanline_F16(char* SK_RESTRICT dst, const char* SK_RESTRICT src, int width,
2261da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett                                   int) {
2271da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    SkRasterPipeline p;
2281da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::load_f16, (const void**) &src);
2291da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::to_srgb);
2301da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::store_u16_be, (void**) &dst);
2311da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.run(0, 0, width);
2321da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett}
2331da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett
2341da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett/**
2351da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett * Transform from kPremul, kRGBA_F16 to 4-bytes-per-pixel RGBA.
2361da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett */
2371da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarettstatic void transform_scanline_F16_premul(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
2381da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett                                          int width, int) {
2391da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    SkRasterPipeline p;
2401da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::load_f16, (const void**) &src);
2411da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::unpremul);
2421da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::to_srgb);
2431da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::store_u16_be, (void**) &dst);
2441da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.run(0, 0, width);
2451da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett}
246