SkImageEncoderFns.h revision 55213562f9a63cbc324833fdd1c16cc79646515a
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,
2662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                        int width, int bpp, const SkPMColor* colors);
274ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
284ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
294ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Identity transformation: just copy bytes from src to dst.
304ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
3162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_memcpy(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
3262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                             int width, int bpp, const SkPMColor*) {
33f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    memcpy(dst, src, width * bpp);
344ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
354ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
3662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_index8_opaque(char* SK_RESTRICT dst,
3762bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                                    const char* SK_RESTRICT src, int width, int,
3862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                                    const SkPMColor* colors) {
3962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    for (int i = 0; i < width; i++) {
4062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        const uint32_t c = colors[(uint8_t)*src++];
4162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[0] = SkGetPackedR32(c);
4262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[1] = SkGetPackedG32(c);
4362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[2] = SkGetPackedB32(c);
4462bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst += 3;
4562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    }
4662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett}
4762bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett
4862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_index8_unpremul(char* SK_RESTRICT dst,
4962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                                      const char* SK_RESTRICT src, int width, int,
5062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                                      const SkPMColor* colors) {
5162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    uint32_t* SK_RESTRICT dst32 = (uint32_t*) dst;
5262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    for (int i = 0; i < width; i++) {
5362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        // This function swizzles R and B on platforms where SkPMColor is BGRA.  This is
5462bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        // exactly what we want.
5562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst32[i] = SkSwizzle_RGBA_to_PMColor(colors[(uint8_t)*src++]);
5662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    }
5762bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett}
5862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett
5962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_gray(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
6062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor* colors) {
6162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    for (int i = 0; i < width; i++) {
6262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        const uint8_t g = (uint8_t) *src++;
6362bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[0] = g;
6462bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[1] = g;
6562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst[2] = g;
6662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett        dst += 3;
6762bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett    }
6862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett}
6962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett
704ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
714ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB.
724ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Alpha channel data is not present in kRGB_565_Config format, so there is no
734ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * alpha channel data to preserve.
744ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
7562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_565(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
7662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                          int width, int, const SkPMColor*) {
77f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint16_t* srcP = (const uint16_t*)src;
784ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
794ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned c = *srcP++;
804ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked16ToR32(c);
814ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked16ToG32(c);
824ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked16ToB32(c);
834ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
844ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
854ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
864ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
87f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Transform from kRGBA_8888_SkColorType to 3-bytes-per-pixel RGB.
88f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Alpha channel data is abandoned.
89f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
9062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_RGBX(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
9162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
92f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
93f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    for (int i = 0; i < width; i++) {
94f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
95f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  0) & 0xFF;
96f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  8) & 0xFF;
97f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 16) & 0xFF;
98f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    }
99f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
100f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
101f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
102f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Transform from kBGRA_8888_SkColorType to 3-bytes-per-pixel RGB.
103f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Alpha channel data is abandoned.
1044ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
10562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_BGRX(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
10662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
107f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
1084ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
109f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
110f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 16) & 0xFF;
111f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  8) & 0xFF;
112f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  0) & 0xFF;
1134ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
1144ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
1154ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
1164ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
1174ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB.
1184ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Alpha channel data, if any, is abandoned.
1194ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
12062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_444(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
12162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                          int width, int, const SkPMColor*) {
122f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkPMColor16* srcP = (const SkPMColor16*)src;
1234ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
1244ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        SkPMColor16 c = *srcP++;
1254ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked4444ToR32(c);
1264ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked4444ToG32(c);
1274ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = SkPacked4444ToB32(c);
1284ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
1294ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
1304ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
131f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msaretttemplate <bool kIsRGBA>
132f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarettstatic inline void transform_scanline_unpremultiply(char* SK_RESTRICT dst,
1331da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett                                                    const char* SK_RESTRICT src, int width) {
134f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
135f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
1364ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
1374ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
138f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
139f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        unsigned r, g, b, a;
140f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        if (kIsRGBA) {
141f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            r = (c >>  0) & 0xFF;
142f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            g = (c >>  8) & 0xFF;
143f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            b = (c >> 16) & 0xFF;
144f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            a = (c >> 24) & 0xFF;
145f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        } else {
146f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            r = (c >> 16) & 0xFF;
147f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            g = (c >>  8) & 0xFF;
148f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            b = (c >>  0) & 0xFF;
149f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett            a = (c >> 24) & 0xFF;
150f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        }
1514ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
1524ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        if (0 != a && 255 != a) {
1534ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            SkUnPreMultiply::Scale scale = table[a];
1544ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            r = SkUnPreMultiply::ApplyScale(scale, r);
1554ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            g = SkUnPreMultiply::ApplyScale(scale, g);
1564ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            b = SkUnPreMultiply::ApplyScale(scale, b);
1574ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        }
1584ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = r;
1594ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = g;
1604ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = b;
1614ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = a;
1624ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
1634ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
1644ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
1654ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com/**
16684014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from legacy kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
167f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
16862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_rgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
16962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
1701da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    transform_scanline_unpremultiply<true>(dst, src, width);
171f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
172f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
173f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
17484014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from legacy kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
175f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
17662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_bgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
17762bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
1781da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    transform_scanline_unpremultiply<false>(dst, src, width);
179f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
180f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
18184014f03a90d137c0f5c95e15c1e5f8503df7101Matt Saretttemplate <bool kIsRGBA>
1821da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarettstatic inline void transform_scanline_unpremultiply_sRGB(void* dst, const void* src, int width) {
18384014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    SkRasterPipeline p;
18484014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append(SkRasterPipeline::load_8888, &src);
18584014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    if (!kIsRGBA) {
18684014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett        p.append(SkRasterPipeline::swap_rb);
18784014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    }
18884014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
18984014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append_from_srgb(kPremul_SkAlphaType);
19084014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append(SkRasterPipeline::unpremul);
19184014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append(SkRasterPipeline::to_srgb);
19284014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett    p.append(SkRasterPipeline::store_8888, &dst);
193319ba3d3a177498095c31696e0aec8b3af25f663Mike Klein    p.run(0, width);
19484014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett}
19584014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
19684014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett/**
19784014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
19884014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett */
19962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_srgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
20062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                            int width, int, const SkPMColor*) {
2011da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    transform_scanline_unpremultiply_sRGB<true>(dst, src, width);
20284014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett}
20384014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
20484014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett/**
20584014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett * Transform from kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
20684014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett */
20762bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_sbgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
20862bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                            int width, int, const SkPMColor*) {
2091da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    transform_scanline_unpremultiply_sRGB<false>(dst, src, width);
21084014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett}
21184014f03a90d137c0f5c95e15c1e5f8503df7101Matt Sarett
212f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
213f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett * Transform from kUnpremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
214f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett */
21562bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_BGRA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
21662bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
217f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const uint32_t* srcP = (const SkPMColor*)src;
218f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    for (int i = 0; i < width; i++) {
219f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        uint32_t c = *srcP++;
220f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 16) & 0xFF;
221f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  8) & 0xFF;
222f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >>  0) & 0xFF;
223f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett        *dst++ = (c >> 24) & 0xFF;
224f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    }
225f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett}
226f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett
227f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett/**
2284ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA,
2294ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com * with scaling of RGB based on alpha channel.
2304ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com */
23162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_4444(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
23262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                           int width, int, const SkPMColor*) {
233f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkPMColor16* srcP = (const SkPMColor16*)src;
234f17b71f6c9b94e93f88e103b3b6cab61cbee76d7msarett    const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
2354ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
2364ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    for (int i = 0; i < width; i++) {
2374ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        SkPMColor16 c = *srcP++;
2384ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned a = SkPacked4444ToA32(c);
2394ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned r = SkPacked4444ToR32(c);
2404ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned g = SkPacked4444ToG32(c);
2414ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        unsigned b = SkPacked4444ToB32(c);
2424ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com
2434ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        if (0 != a && 255 != a) {
2444ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            SkUnPreMultiply::Scale scale = table[a];
2454ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            r = SkUnPreMultiply::ApplyScale(scale, r);
2464ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            g = SkUnPreMultiply::ApplyScale(scale, g);
2474ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com            b = SkUnPreMultiply::ApplyScale(scale, b);
2484ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        }
2494ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = r;
2504ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = g;
2514ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = b;
2524ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com        *dst++ = a;
2534ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com    }
2544ce738b98ee0be1771712e3036a7711c21f3b7f4epoger@google.com}
2551da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett
2561da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett/**
25755213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett * Transform from kRGBA_F16 to 8-bytes-per-pixel RGBA.
2581da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett */
25962bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_F16(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
26062bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                          int width, int, const SkPMColor*) {
2611da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    SkRasterPipeline p;
2621da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::load_f16, (const void**) &src);
2631da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::to_srgb);
2641da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::store_u16_be, (void**) &dst);
265319ba3d3a177498095c31696e0aec8b3af25f663Mike Klein    p.run(0, width);
2661da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett}
2671da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett
2681da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett/**
26955213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett * Transform from kPremul, kRGBA_F16 to 8-bytes-per-pixel RGBA.
2701da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett */
27162bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarettstatic inline void transform_scanline_F16_premul(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
27262bb2803a8e0ab2571ccec8de72a6a995d46a726Matt Sarett                                                 int width, int, const SkPMColor*) {
2731da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    SkRasterPipeline p;
2741da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::load_f16, (const void**) &src);
2751da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::unpremul);
2761da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::to_srgb);
2771da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett    p.append(SkRasterPipeline::store_u16_be, (void**) &dst);
278319ba3d3a177498095c31696e0aec8b3af25f663Mike Klein    p.run(0, width);
2791da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett}
28055213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett
28155213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett/**
28255213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett * Transform from kRGBA_F16 to 4-bytes-per-pixel RGBA.
28355213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett */
28455213562f9a63cbc324833fdd1c16cc79646515aMatt Sarettstatic inline void transform_scanline_F16_to_8888(char* SK_RESTRICT dst,
28555213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett                                                  const char* SK_RESTRICT src, int width, int,
28655213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett                                                  const SkPMColor*) {
28755213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    SkRasterPipeline p;
28855213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.append(SkRasterPipeline::load_f16, (const void**) &src);
28955213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.append(SkRasterPipeline::to_srgb);
29055213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.append(SkRasterPipeline::store_8888, (void**) &dst);
29155213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.run(0, width);
29255213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett}
29355213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett
29455213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett/**
29555213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett * Transform from kPremul, kRGBA_F16 to 4-bytes-per-pixel RGBA.
29655213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett */
29755213562f9a63cbc324833fdd1c16cc79646515aMatt Sarettstatic inline void transform_scanline_F16_premul_to_8888(char* SK_RESTRICT dst,
29855213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett                                                         const char* SK_RESTRICT src, int width,
29955213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett                                                         int, const SkPMColor*) {
30055213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    SkRasterPipeline p;
30155213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.append(SkRasterPipeline::load_f16, (const void**) &src);
30255213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.append(SkRasterPipeline::unpremul);
30355213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.append(SkRasterPipeline::to_srgb);
30455213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.append(SkRasterPipeline::store_8888, (void**) &dst);
30555213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett    p.run(0, width);
30655213562f9a63cbc324833fdd1c16cc79646515aMatt Sarett}
307