1f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo/*
2f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo * Copyright 2015 Google Inc.
3f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo *
4f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo * Use of this source code is governed by a BSD-style license that can be
5f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo * found in the LICENSE file.
6f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo */
7f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
8741143878b23d22cd9cb7b9cba8055179115ce17msarett#include "SkCodecPriv.h"
9f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo#include "SkColorPriv.h"
10f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo#include "SkSwizzler.h"
11f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo#include "SkTemplates.h"
12438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett#include "SkUtils.h"
13f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
14741143878b23d22cd9cb7b9cba8055179115ce17msarettSkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha,
15741143878b23d22cd9cb7b9cba8055179115ce17msarett                                              uint8_t maxAlpha) {
16741143878b23d22cd9cb7b9cba8055179115ce17msarett    // In the transparent case, this returns 0x0000
17741143878b23d22cd9cb7b9cba8055179115ce17msarett    // In the opaque case, this returns 0xFFFF
18741143878b23d22cd9cb7b9cba8055179115ce17msarett    // If the row is neither transparent nor opaque, returns something else
19741143878b23d22cd9cb7b9cba8055179115ce17msarett    return (((uint16_t) maxAlpha) << 8) | zeroAlpha;
20741143878b23d22cd9cb7b9cba8055179115ce17msarett}
21741143878b23d22cd9cb7b9cba8055179115ce17msarett
22741143878b23d22cd9cb7b9cba8055179115ce17msarett// kIndex1, kIndex2, kIndex4
23741143878b23d22cd9cb7b9cba8055179115ce17msarett
24438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarettstatic SkSwizzler::ResultAlpha swizzle_small_index_to_index(
25741143878b23d22cd9cb7b9cba8055179115ce17msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
26741143878b23d22cd9cb7b9cba8055179115ce17msarett        int bitsPerPixel, int y, const SkPMColor ctable[]) {
27741143878b23d22cd9cb7b9cba8055179115ce17msarett
28438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
29741143878b23d22cd9cb7b9cba8055179115ce17msarett    INIT_RESULT_ALPHA;
30741143878b23d22cd9cb7b9cba8055179115ce17msarett    const uint32_t pixelsPerByte = 8 / bitsPerPixel;
31741143878b23d22cd9cb7b9cba8055179115ce17msarett    const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte);
32741143878b23d22cd9cb7b9cba8055179115ce17msarett    const uint8_t mask = (1 << bitsPerPixel) - 1;
33741143878b23d22cd9cb7b9cba8055179115ce17msarett    int x = 0;
34741143878b23d22cd9cb7b9cba8055179115ce17msarett    for (uint32_t byte = 0; byte < rowBytes; byte++) {
35741143878b23d22cd9cb7b9cba8055179115ce17msarett        uint8_t pixelData = src[byte];
36741143878b23d22cd9cb7b9cba8055179115ce17msarett        for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) {
37741143878b23d22cd9cb7b9cba8055179115ce17msarett            uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
38438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT);
39438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            dst[x] = index;
40741143878b23d22cd9cb7b9cba8055179115ce17msarett            pixelData <<= bitsPerPixel;
41741143878b23d22cd9cb7b9cba8055179115ce17msarett            x++;
42741143878b23d22cd9cb7b9cba8055179115ce17msarett        }
43741143878b23d22cd9cb7b9cba8055179115ce17msarett    }
44741143878b23d22cd9cb7b9cba8055179115ce17msarett    return COMPUTE_RESULT_ALPHA;
45741143878b23d22cd9cb7b9cba8055179115ce17msarett}
46f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
47438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarettstatic SkSwizzler::ResultAlpha swizzle_small_index_to_n32(
48eed039b5ffbdff958053ac80b09451ad6caa1787msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
49eed039b5ffbdff958053ac80b09451ad6caa1787msarett        int bitsPerPixel, int y, const SkPMColor ctable[]) {
50eed039b5ffbdff958053ac80b09451ad6caa1787msarett
51438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
52438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    INIT_RESULT_ALPHA;
53eed039b5ffbdff958053ac80b09451ad6caa1787msarett    const uint32_t pixelsPerByte = 8 / bitsPerPixel;
54eed039b5ffbdff958053ac80b09451ad6caa1787msarett    const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte);
55eed039b5ffbdff958053ac80b09451ad6caa1787msarett    const uint8_t mask = (1 << bitsPerPixel) - 1;
56eed039b5ffbdff958053ac80b09451ad6caa1787msarett    int x = 0;
57eed039b5ffbdff958053ac80b09451ad6caa1787msarett    for (uint32_t byte = 0; byte < rowBytes; byte++) {
58eed039b5ffbdff958053ac80b09451ad6caa1787msarett        uint8_t pixelData = src[byte];
59eed039b5ffbdff958053ac80b09451ad6caa1787msarett        for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) {
60eed039b5ffbdff958053ac80b09451ad6caa1787msarett            uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
61438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            SkPMColor c = ctable[index];
62438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
63eed039b5ffbdff958053ac80b09451ad6caa1787msarett            dst[x] = c;
64eed039b5ffbdff958053ac80b09451ad6caa1787msarett            pixelData <<= bitsPerPixel;
65eed039b5ffbdff958053ac80b09451ad6caa1787msarett            x++;
66eed039b5ffbdff958053ac80b09451ad6caa1787msarett        }
67eed039b5ffbdff958053ac80b09451ad6caa1787msarett    }
68438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    return COMPUTE_RESULT_ALPHA;
69438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett}
70438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett
71e16b04aa6041efb6507546547737e9603fa1606emsarett// kIndex
72e16b04aa6041efb6507546547737e9603fa1606emsarett
73438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarettstatic SkSwizzler::ResultAlpha swizzle_index_to_index(
74438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
75438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
76438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett
77438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
78438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    memcpy(dst, src, width);
79438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    // TODO (msarett): Should we skip the loop here and guess that the row is opaque/not opaque?
80438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    //                 SkScaledBitmap sampler just guesses that it is opaque.  This is dangerous
81438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    //                 and probably wrong since gif and bmp (rarely) may have alpha.
82438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    INIT_RESULT_ALPHA;
83438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    for (int x = 0; x < width; x++) {
84438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett        UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT);
85438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    }
86438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    return COMPUTE_RESULT_ALPHA;
87eed039b5ffbdff958053ac80b09451ad6caa1787msarett}
88eed039b5ffbdff958053ac80b09451ad6caa1787msarett
89741143878b23d22cd9cb7b9cba8055179115ce17msarettstatic SkSwizzler::ResultAlpha swizzle_index_to_n32(
90741143878b23d22cd9cb7b9cba8055179115ce17msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
91741143878b23d22cd9cb7b9cba8055179115ce17msarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
92f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
93f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
94741143878b23d22cd9cb7b9cba8055179115ce17msarett    INIT_RESULT_ALPHA;
95f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    for (int x = 0; x < width; x++) {
96438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett        SkPMColor c = ctable[src[x]];
97741143878b23d22cd9cb7b9cba8055179115ce17msarett        UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
98f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        dst[x] = c;
99f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
100741143878b23d22cd9cb7b9cba8055179115ce17msarett    return COMPUTE_RESULT_ALPHA;
101f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
102f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
103741143878b23d22cd9cb7b9cba8055179115ce17msarettstatic SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ(
104741143878b23d22cd9cb7b9cba8055179115ce17msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
105741143878b23d22cd9cb7b9cba8055179115ce17msarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
106f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
107f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
108741143878b23d22cd9cb7b9cba8055179115ce17msarett    INIT_RESULT_ALPHA;
109f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    for (int x = 0; x < width; x++) {
110438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett        SkPMColor c = ctable[src[x]];
111741143878b23d22cd9cb7b9cba8055179115ce17msarett        UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
112f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        if (c != 0) {
113f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            dst[x] = c;
114f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        }
115f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
116741143878b23d22cd9cb7b9cba8055179115ce17msarett    return COMPUTE_RESULT_ALPHA;
117f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
118f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
119f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo#undef A32_MASK_IN_PLACE
120f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
121e16b04aa6041efb6507546547737e9603fa1606emsarett// kGray
122e16b04aa6041efb6507546547737e9603fa1606emsarett
123e16b04aa6041efb6507546547737e9603fa1606emsarettstatic SkSwizzler::ResultAlpha swizzle_gray_to_n32(
124e16b04aa6041efb6507546547737e9603fa1606emsarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
125e16b04aa6041efb6507546547737e9603fa1606emsarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
126e16b04aa6041efb6507546547737e9603fa1606emsarett
127e16b04aa6041efb6507546547737e9603fa1606emsarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
128e16b04aa6041efb6507546547737e9603fa1606emsarett    for (int x = 0; x < width; x++) {
129e16b04aa6041efb6507546547737e9603fa1606emsarett        dst[x] = SkPackARGB32NoCheck(0xFF, src[x], src[x], src[x]);
130e16b04aa6041efb6507546547737e9603fa1606emsarett    }
131e16b04aa6041efb6507546547737e9603fa1606emsarett    return SkSwizzler::kOpaque_ResultAlpha;
132e16b04aa6041efb6507546547737e9603fa1606emsarett}
133e16b04aa6041efb6507546547737e9603fa1606emsarett
134e16b04aa6041efb6507546547737e9603fa1606emsarettstatic SkSwizzler::ResultAlpha swizzle_gray_to_gray(
135e16b04aa6041efb6507546547737e9603fa1606emsarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
136e16b04aa6041efb6507546547737e9603fa1606emsarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
137e16b04aa6041efb6507546547737e9603fa1606emsarett    memcpy(dstRow, src, width);
138e16b04aa6041efb6507546547737e9603fa1606emsarett    return SkSwizzler::kOpaque_ResultAlpha;
139e16b04aa6041efb6507546547737e9603fa1606emsarett}
140e16b04aa6041efb6507546547737e9603fa1606emsarett
141e16b04aa6041efb6507546547737e9603fa1606emsarett// kBGRX
142e16b04aa6041efb6507546547737e9603fa1606emsarett
143741143878b23d22cd9cb7b9cba8055179115ce17msarettstatic SkSwizzler::ResultAlpha swizzle_bgrx_to_n32(
144741143878b23d22cd9cb7b9cba8055179115ce17msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
145741143878b23d22cd9cb7b9cba8055179115ce17msarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
146741143878b23d22cd9cb7b9cba8055179115ce17msarett
147741143878b23d22cd9cb7b9cba8055179115ce17msarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
148741143878b23d22cd9cb7b9cba8055179115ce17msarett    for (int x = 0; x < width; x++) {
149741143878b23d22cd9cb7b9cba8055179115ce17msarett        dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]);
150741143878b23d22cd9cb7b9cba8055179115ce17msarett        src += bytesPerPixel;
151741143878b23d22cd9cb7b9cba8055179115ce17msarett    }
152741143878b23d22cd9cb7b9cba8055179115ce17msarett    return SkSwizzler::kOpaque_ResultAlpha;
153741143878b23d22cd9cb7b9cba8055179115ce17msarett}
154741143878b23d22cd9cb7b9cba8055179115ce17msarett
155741143878b23d22cd9cb7b9cba8055179115ce17msarett// kBGRA
156741143878b23d22cd9cb7b9cba8055179115ce17msarett
157eed039b5ffbdff958053ac80b09451ad6caa1787msarettstatic SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul(
158741143878b23d22cd9cb7b9cba8055179115ce17msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
159741143878b23d22cd9cb7b9cba8055179115ce17msarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
160741143878b23d22cd9cb7b9cba8055179115ce17msarett
161741143878b23d22cd9cb7b9cba8055179115ce17msarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
162741143878b23d22cd9cb7b9cba8055179115ce17msarett    INIT_RESULT_ALPHA;
163741143878b23d22cd9cb7b9cba8055179115ce17msarett    for (int x = 0; x < width; x++) {
164741143878b23d22cd9cb7b9cba8055179115ce17msarett        uint8_t alpha = src[3];
165741143878b23d22cd9cb7b9cba8055179115ce17msarett        UPDATE_RESULT_ALPHA(alpha);
166741143878b23d22cd9cb7b9cba8055179115ce17msarett        dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]);
167741143878b23d22cd9cb7b9cba8055179115ce17msarett        src += bytesPerPixel;
168741143878b23d22cd9cb7b9cba8055179115ce17msarett    }
169741143878b23d22cd9cb7b9cba8055179115ce17msarett    return COMPUTE_RESULT_ALPHA;
170741143878b23d22cd9cb7b9cba8055179115ce17msarett}
171741143878b23d22cd9cb7b9cba8055179115ce17msarett
172eed039b5ffbdff958053ac80b09451ad6caa1787msarettstatic SkSwizzler::ResultAlpha swizzle_bgra_to_n32_premul(
173eed039b5ffbdff958053ac80b09451ad6caa1787msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
174eed039b5ffbdff958053ac80b09451ad6caa1787msarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
175eed039b5ffbdff958053ac80b09451ad6caa1787msarett
176eed039b5ffbdff958053ac80b09451ad6caa1787msarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
177eed039b5ffbdff958053ac80b09451ad6caa1787msarett    INIT_RESULT_ALPHA;
178eed039b5ffbdff958053ac80b09451ad6caa1787msarett    for (int x = 0; x < width; x++) {
179eed039b5ffbdff958053ac80b09451ad6caa1787msarett        uint8_t alpha = src[3];
180eed039b5ffbdff958053ac80b09451ad6caa1787msarett        UPDATE_RESULT_ALPHA(alpha);
181eed039b5ffbdff958053ac80b09451ad6caa1787msarett        dst[x] = SkPreMultiplyARGB(alpha, src[2], src[1], src[0]);
182eed039b5ffbdff958053ac80b09451ad6caa1787msarett        src += bytesPerPixel;
183eed039b5ffbdff958053ac80b09451ad6caa1787msarett    }
184eed039b5ffbdff958053ac80b09451ad6caa1787msarett    return COMPUTE_RESULT_ALPHA;
185eed039b5ffbdff958053ac80b09451ad6caa1787msarett}
186eed039b5ffbdff958053ac80b09451ad6caa1787msarett
187f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo// n32
188741143878b23d22cd9cb7b9cba8055179115ce17msarettstatic SkSwizzler::ResultAlpha swizzle_rgbx_to_n32(
189741143878b23d22cd9cb7b9cba8055179115ce17msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
190741143878b23d22cd9cb7b9cba8055179115ce17msarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
191741143878b23d22cd9cb7b9cba8055179115ce17msarett
192f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
193f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    for (int x = 0; x < width; x++) {
194f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
195741143878b23d22cd9cb7b9cba8055179115ce17msarett        src += bytesPerPixel;
196f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
197741143878b23d22cd9cb7b9cba8055179115ce17msarett    return SkSwizzler::kOpaque_ResultAlpha;
198f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
199f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
200741143878b23d22cd9cb7b9cba8055179115ce17msarettstatic SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul(
201741143878b23d22cd9cb7b9cba8055179115ce17msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
202741143878b23d22cd9cb7b9cba8055179115ce17msarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
203741143878b23d22cd9cb7b9cba8055179115ce17msarett
204f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
205741143878b23d22cd9cb7b9cba8055179115ce17msarett    INIT_RESULT_ALPHA;
206f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    for (int x = 0; x < width; x++) {
207f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        unsigned alpha = src[3];
208741143878b23d22cd9cb7b9cba8055179115ce17msarett        UPDATE_RESULT_ALPHA(alpha);
209f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
210741143878b23d22cd9cb7b9cba8055179115ce17msarett        src += bytesPerPixel;
211f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
212741143878b23d22cd9cb7b9cba8055179115ce17msarett    return COMPUTE_RESULT_ALPHA;
213f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
214f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
215741143878b23d22cd9cb7b9cba8055179115ce17msarettstatic SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul(
216741143878b23d22cd9cb7b9cba8055179115ce17msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
217741143878b23d22cd9cb7b9cba8055179115ce17msarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
218741143878b23d22cd9cb7b9cba8055179115ce17msarett
219f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
220741143878b23d22cd9cb7b9cba8055179115ce17msarett    INIT_RESULT_ALPHA;
221f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    for (int x = 0; x < width; x++) {
222f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        unsigned alpha = src[3];
223741143878b23d22cd9cb7b9cba8055179115ce17msarett        UPDATE_RESULT_ALPHA(alpha);
224f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
225741143878b23d22cd9cb7b9cba8055179115ce17msarett        src += bytesPerPixel;
226f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
227741143878b23d22cd9cb7b9cba8055179115ce17msarett    return COMPUTE_RESULT_ALPHA;
228f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
229f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
230741143878b23d22cd9cb7b9cba8055179115ce17msarettstatic SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ(
231741143878b23d22cd9cb7b9cba8055179115ce17msarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
232741143878b23d22cd9cb7b9cba8055179115ce17msarett        int bytesPerPixel, int y, const SkPMColor ctable[]) {
233741143878b23d22cd9cb7b9cba8055179115ce17msarett
234f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
235741143878b23d22cd9cb7b9cba8055179115ce17msarett    INIT_RESULT_ALPHA;
236f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    for (int x = 0; x < width; x++) {
237f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        unsigned alpha = src[3];
238741143878b23d22cd9cb7b9cba8055179115ce17msarett        UPDATE_RESULT_ALPHA(alpha);
239f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        if (0 != alpha) {
240f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
241f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        }
242741143878b23d22cd9cb7b9cba8055179115ce17msarett        src += bytesPerPixel;
243f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
244741143878b23d22cd9cb7b9cba8055179115ce17msarett    return COMPUTE_RESULT_ALPHA;
245f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
246f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
247f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo/**
248f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    FIXME: This was my idea to cheat in order to continue taking advantage of skipping zeroes.
249f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    This would be fine for drawing normally, but not for drawing with transfer modes. Being
250f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    honest means we can draw correctly with transfer modes, with the cost of not being able
251f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    to take advantage of Android's free unwritten pages. Something to keep in mind when we
252f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    decide whether to switch to unpremul default.
253f24f2247c25b842327e12c70e44efe4cc1b28dfascroggostatic bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
254f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                                               const uint8_t* SK_RESTRICT src,
255741143878b23d22cd9cb7b9cba8055179115ce17msarett                                               int width, int bitsPerPixel,
256f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                                               const SkPMColor[]) {
257f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
258f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    unsigned alphaMask = 0xFF;
259f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    for (int x = 0; x < width; x++) {
260f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        unsigned alpha = src[3];
261f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        // NOTE: We cheat here. The caller requested unpremul and skip zeroes. It's possible
262f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        // the color components are not zero, but we skip them anyway, meaning they'll remain
263f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        // zero (implied by the request to skip zeroes).
264f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        if (0 != alpha) {
265f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
266f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        }
267f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        src += deltaSrc;
268f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        alphaMask &= alpha;
269f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
270f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    return alphaMask != 0xFF;
271f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
272f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo*/
273f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
274741143878b23d22cd9cb7b9cba8055179115ce17msarettSkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
275741143878b23d22cd9cb7b9cba8055179115ce17msarett                                       const SkPMColor* ctable,
276f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                                       const SkImageInfo& info, void* dst,
2779552662e9fee5eb0ef435e52ab9db505d7ebe4adscroggo                                       size_t dstRowBytes,
2789552662e9fee5eb0ef435e52ab9db505d7ebe4adscroggo                                       SkImageGenerator::ZeroInitialized zeroInit) {
27905245900bf6d49068b1668da1b38890a41e09bc5scroggo    if (info.colorType() == kUnknown_SkColorType || kUnknown == sc) {
280f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        return NULL;
281f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
282f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    if (info.minRowBytes() > dstRowBytes) {
283f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        return  NULL;
284f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
285741143878b23d22cd9cb7b9cba8055179115ce17msarett    if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
286741143878b23d22cd9cb7b9cba8055179115ce17msarett            && NULL == ctable) {
287f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        return NULL;
288f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
289f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    RowProc proc = NULL;
290f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    switch (sc) {
291741143878b23d22cd9cb7b9cba8055179115ce17msarett        case kIndex1:
292741143878b23d22cd9cb7b9cba8055179115ce17msarett        case kIndex2:
293741143878b23d22cd9cb7b9cba8055179115ce17msarett        case kIndex4:
294741143878b23d22cd9cb7b9cba8055179115ce17msarett            switch (info.colorType()) {
295741143878b23d22cd9cb7b9cba8055179115ce17msarett                case kN32_SkColorType:
296741143878b23d22cd9cb7b9cba8055179115ce17msarett                    proc = &swizzle_small_index_to_n32;
297741143878b23d22cd9cb7b9cba8055179115ce17msarett                    break;
298438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                case kIndex_8_SkColorType:
299438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                    proc = &swizzle_small_index_to_index;
300eed039b5ffbdff958053ac80b09451ad6caa1787msarett                    break;
301741143878b23d22cd9cb7b9cba8055179115ce17msarett                default:
302741143878b23d22cd9cb7b9cba8055179115ce17msarett                    break;
303741143878b23d22cd9cb7b9cba8055179115ce17msarett            }
304741143878b23d22cd9cb7b9cba8055179115ce17msarett            break;
305f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        case kIndex:
306f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            switch (info.colorType()) {
307f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                case kN32_SkColorType:
3089552662e9fee5eb0ef435e52ab9db505d7ebe4adscroggo                    // We assume the color premultiplied ctable (or not) as desired.
3099552662e9fee5eb0ef435e52ab9db505d7ebe4adscroggo                    if (SkImageGenerator::kYes_ZeroInitialized == zeroInit) {
310f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                        proc = &swizzle_index_to_n32_skipZ;
311eed039b5ffbdff958053ac80b09451ad6caa1787msarett                        break;
312f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    } else {
313f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                        proc = &swizzle_index_to_n32;
314eed039b5ffbdff958053ac80b09451ad6caa1787msarett                        break;
315f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    }
316f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    break;
317438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                case kIndex_8_SkColorType:
318438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                    proc = &swizzle_index_to_index;
319eed039b5ffbdff958053ac80b09451ad6caa1787msarett                    break;
320741143878b23d22cd9cb7b9cba8055179115ce17msarett                default:
321741143878b23d22cd9cb7b9cba8055179115ce17msarett                    break;
322741143878b23d22cd9cb7b9cba8055179115ce17msarett            }
323741143878b23d22cd9cb7b9cba8055179115ce17msarett            break;
324e16b04aa6041efb6507546547737e9603fa1606emsarett        case kGray:
325e16b04aa6041efb6507546547737e9603fa1606emsarett            switch (info.colorType()) {
326e16b04aa6041efb6507546547737e9603fa1606emsarett                case kN32_SkColorType:
327e16b04aa6041efb6507546547737e9603fa1606emsarett                    proc = &swizzle_gray_to_n32;
328e16b04aa6041efb6507546547737e9603fa1606emsarett                    break;
329e16b04aa6041efb6507546547737e9603fa1606emsarett                case kGray_8_SkColorType:
330e16b04aa6041efb6507546547737e9603fa1606emsarett                    proc = &swizzle_gray_to_gray;
331e16b04aa6041efb6507546547737e9603fa1606emsarett                default:
332e16b04aa6041efb6507546547737e9603fa1606emsarett                    break;
333e16b04aa6041efb6507546547737e9603fa1606emsarett            }
334e16b04aa6041efb6507546547737e9603fa1606emsarett            break;
335741143878b23d22cd9cb7b9cba8055179115ce17msarett        case kBGR:
336741143878b23d22cd9cb7b9cba8055179115ce17msarett        case kBGRX:
337741143878b23d22cd9cb7b9cba8055179115ce17msarett            switch (info.colorType()) {
338741143878b23d22cd9cb7b9cba8055179115ce17msarett                case kN32_SkColorType:
339741143878b23d22cd9cb7b9cba8055179115ce17msarett                    proc = &swizzle_bgrx_to_n32;
340741143878b23d22cd9cb7b9cba8055179115ce17msarett                    break;
341741143878b23d22cd9cb7b9cba8055179115ce17msarett                default:
342741143878b23d22cd9cb7b9cba8055179115ce17msarett                    break;
343741143878b23d22cd9cb7b9cba8055179115ce17msarett            }
344741143878b23d22cd9cb7b9cba8055179115ce17msarett            break;
345741143878b23d22cd9cb7b9cba8055179115ce17msarett        case kBGRA:
346741143878b23d22cd9cb7b9cba8055179115ce17msarett            switch (info.colorType()) {
347741143878b23d22cd9cb7b9cba8055179115ce17msarett                case kN32_SkColorType:
348eed039b5ffbdff958053ac80b09451ad6caa1787msarett                    switch (info.alphaType()) {
349eed039b5ffbdff958053ac80b09451ad6caa1787msarett                        case kUnpremul_SkAlphaType:
350eed039b5ffbdff958053ac80b09451ad6caa1787msarett                            proc = &swizzle_bgra_to_n32_unpremul;
351eed039b5ffbdff958053ac80b09451ad6caa1787msarett                            break;
352eed039b5ffbdff958053ac80b09451ad6caa1787msarett                        case kPremul_SkAlphaType:
353eed039b5ffbdff958053ac80b09451ad6caa1787msarett                            proc = &swizzle_bgra_to_n32_premul;
354eed039b5ffbdff958053ac80b09451ad6caa1787msarett                            break;
355eed039b5ffbdff958053ac80b09451ad6caa1787msarett                        default:
356eed039b5ffbdff958053ac80b09451ad6caa1787msarett                            break;
357eed039b5ffbdff958053ac80b09451ad6caa1787msarett                    }
358741143878b23d22cd9cb7b9cba8055179115ce17msarett                    break;
359f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                default:
360f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    break;
361f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            }
362f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            break;
363f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        case kRGBX:
364f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            // TODO: Support other swizzles.
365f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            switch (info.colorType()) {
366f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                case kN32_SkColorType:
367f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    proc = &swizzle_rgbx_to_n32;
368f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    break;
369f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                default:
370f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    break;
371f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            }
372f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            break;
373f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        case kRGBA:
374f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            switch (info.colorType()) {
375f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                case kN32_SkColorType:
376f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    if (info.alphaType() == kUnpremul_SkAlphaType) {
3779552662e9fee5eb0ef435e52ab9db505d7ebe4adscroggo                        // Respect zeroInit?
378f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                        proc = &swizzle_rgba_to_n32_unpremul;
379f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    } else {
3809552662e9fee5eb0ef435e52ab9db505d7ebe4adscroggo                        if (SkImageGenerator::kYes_ZeroInitialized == zeroInit) {
381f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                            proc = &swizzle_rgba_to_n32_premul_skipZ;
382f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                        } else {
383f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                            proc = &swizzle_rgba_to_n32_premul;
384f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                        }
385f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    }
386f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    break;
387f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                default:
388f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                    break;
389f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            }
390f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            break;
391741143878b23d22cd9cb7b9cba8055179115ce17msarett        case kRGB:
392741143878b23d22cd9cb7b9cba8055179115ce17msarett            switch (info.colorType()) {
393741143878b23d22cd9cb7b9cba8055179115ce17msarett                case kN32_SkColorType:
394741143878b23d22cd9cb7b9cba8055179115ce17msarett                    proc = &swizzle_rgbx_to_n32;
395741143878b23d22cd9cb7b9cba8055179115ce17msarett                    break;
396741143878b23d22cd9cb7b9cba8055179115ce17msarett                default:
397741143878b23d22cd9cb7b9cba8055179115ce17msarett                    break;
398741143878b23d22cd9cb7b9cba8055179115ce17msarett            }
399741143878b23d22cd9cb7b9cba8055179115ce17msarett            break;
400f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        default:
401f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            break;
402f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
403f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    if (NULL == proc) {
404f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        return NULL;
405f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
406741143878b23d22cd9cb7b9cba8055179115ce17msarett
407741143878b23d22cd9cb7b9cba8055179115ce17msarett    // Store deltaSrc in bytes if it is an even multiple, otherwise use bits
408741143878b23d22cd9cb7b9cba8055179115ce17msarett    int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) :
409741143878b23d22cd9cb7b9cba8055179115ce17msarett            BitsPerPixel(sc);
410741143878b23d22cd9cb7b9cba8055179115ce17msarett    return SkNEW_ARGS(SkSwizzler, (proc, ctable, deltaSrc, info, dst,
411741143878b23d22cd9cb7b9cba8055179115ce17msarett                                   dstRowBytes));
412f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
413f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
414741143878b23d22cd9cb7b9cba8055179115ce17msarettSkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable,
415741143878b23d22cd9cb7b9cba8055179115ce17msarett                       int deltaSrc, const SkImageInfo& info, void* dst,
416741143878b23d22cd9cb7b9cba8055179115ce17msarett                       size_t rowBytes)
417f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    : fRowProc(proc)
418f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    , fColorTable(ctable)
419741143878b23d22cd9cb7b9cba8055179115ce17msarett    , fDeltaSrc(deltaSrc)
420f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    , fDstInfo(info)
421f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    , fDstRow(dst)
422f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    , fDstRowBytes(rowBytes)
423f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    , fCurrY(0)
424f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo{
425741143878b23d22cd9cb7b9cba8055179115ce17msarett    SkDEBUGCODE(fNextMode = kUninitialized_NextMode);
426f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
427f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
428741143878b23d22cd9cb7b9cba8055179115ce17msarettSkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src) {
429741143878b23d22cd9cb7b9cba8055179115ce17msarett    SkASSERT(0 <= fCurrY && fCurrY < fDstInfo.height());
43005245900bf6d49068b1668da1b38890a41e09bc5scroggo    SkASSERT(fDstRow != NULL);
431741143878b23d22cd9cb7b9cba8055179115ce17msarett    SkASSERT(kDesignateRow_NextMode != fNextMode);
432741143878b23d22cd9cb7b9cba8055179115ce17msarett    SkDEBUGCODE(fNextMode = kConsecutive_NextMode);
433741143878b23d22cd9cb7b9cba8055179115ce17msarett
434741143878b23d22cd9cb7b9cba8055179115ce17msarett    // Decode a row
435741143878b23d22cd9cb7b9cba8055179115ce17msarett    const ResultAlpha result = fRowProc(fDstRow, src, fDstInfo.width(),
436741143878b23d22cd9cb7b9cba8055179115ce17msarett            fDeltaSrc, fCurrY, fColorTable);
437741143878b23d22cd9cb7b9cba8055179115ce17msarett
438741143878b23d22cd9cb7b9cba8055179115ce17msarett    // Move to the next row and return the result
43905245900bf6d49068b1668da1b38890a41e09bc5scroggo    fCurrY++;
440f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes);
441741143878b23d22cd9cb7b9cba8055179115ce17msarett    return result;
442741143878b23d22cd9cb7b9cba8055179115ce17msarett}
443741143878b23d22cd9cb7b9cba8055179115ce17msarett
444741143878b23d22cd9cb7b9cba8055179115ce17msarettSkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src,
445741143878b23d22cd9cb7b9cba8055179115ce17msarett        int y) {
446741143878b23d22cd9cb7b9cba8055179115ce17msarett    SkASSERT(0 <= y && y < fDstInfo.height());
447741143878b23d22cd9cb7b9cba8055179115ce17msarett    SkASSERT(kConsecutive_NextMode != fNextMode);
448741143878b23d22cd9cb7b9cba8055179115ce17msarett    SkDEBUGCODE(fNextMode = kDesignateRow_NextMode);
449741143878b23d22cd9cb7b9cba8055179115ce17msarett
450741143878b23d22cd9cb7b9cba8055179115ce17msarett    // Choose the row
451741143878b23d22cd9cb7b9cba8055179115ce17msarett    void* row = SkTAddOffset<void>(fDstRow, y*fDstRowBytes);
452741143878b23d22cd9cb7b9cba8055179115ce17msarett
453741143878b23d22cd9cb7b9cba8055179115ce17msarett    // Decode the row
454741143878b23d22cd9cb7b9cba8055179115ce17msarett    return fRowProc(row, src, fDstInfo.width(), fDeltaSrc, fCurrY,
455741143878b23d22cd9cb7b9cba8055179115ce17msarett            fColorTable);
456f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
457438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett
4583c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarettvoid SkSwizzler::Fill(void* dstStartRow, const SkImageInfo& dstInfo, size_t dstRowBytes,
4593c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett        uint32_t numRows, uint32_t colorOrIndex, const SkPMColor* colorTable) {
4603c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett    SkASSERT(dstStartRow != NULL);
4613c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett    SkASSERT(numRows <= (uint32_t) dstInfo.height());
462438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett
4633c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett    // Calculate bytes to fill.  We use getSafeSize since the last row may not be padded.
4643c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett    const size_t bytesToFill = dstInfo.makeWH(dstInfo.width(), numRows).getSafeSize(dstRowBytes);
465438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett
466438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    // Use the proper memset routine to fill the remaining bytes
467438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    switch(dstInfo.colorType()) {
468438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett        case kN32_SkColorType:
469438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            // Assume input is an index if we have a color table
470438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            uint32_t color;
471438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            if (NULL != colorTable) {
472438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                SkASSERT(colorOrIndex == (uint8_t) colorOrIndex);
473438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                color = colorTable[colorOrIndex];
474438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            // Otherwise, assume the input is a color
475438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            } else {
476438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                color = colorOrIndex;
477438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            }
478438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett
479438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            // We must fill row by row in the case of unaligned row bytes
4803c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett            if (SkIsAlign4((size_t) dstStartRow) && SkIsAlign4(dstRowBytes)) {
4813c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett                sk_memset32((uint32_t*) dstStartRow, color,
4823c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett                        (uint32_t) bytesToFill / sizeof(SkPMColor));
483438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            } else {
484438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                // This is an unlikely, slow case
485438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                SkCodecPrintf("Warning: Strange number of row bytes, fill will be slow.\n");
4863c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett                uint32_t* dstRow = (uint32_t*) dstStartRow;
4873c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett                for (uint32_t row = 0; row < numRows; row++) {
488438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                    for (int32_t col = 0; col < dstInfo.width(); col++) {
4893c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett                        dstRow[col] = color;
490438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                    }
4913c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett                    dstRow = SkTAddOffset<uint32_t>(dstRow, dstRowBytes);
492438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett                }
493438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            }
494438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            break;
495438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett        // On an index destination color type, always assume the input is an index
496438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett        case kIndex_8_SkColorType:
497438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            SkASSERT(colorOrIndex == (uint8_t) colorOrIndex);
4983c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett            memset(dstStartRow, colorOrIndex, bytesToFill);
499438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            break;
500e16b04aa6041efb6507546547737e9603fa1606emsarett        case kGray_8_SkColorType:
501e16b04aa6041efb6507546547737e9603fa1606emsarett            // If the destination is kGray, the caller passes in an 8-bit color.
502e16b04aa6041efb6507546547737e9603fa1606emsarett            // We will not assert that the high bits of colorOrIndex must be zeroed.
503e16b04aa6041efb6507546547737e9603fa1606emsarett            // This allows us to take advantage of the fact that the low 8 bits of an
504e16b04aa6041efb6507546547737e9603fa1606emsarett            // SKPMColor may be a valid a grayscale color.  For example, the low 8
505e16b04aa6041efb6507546547737e9603fa1606emsarett            // bits of SK_ColorBLACK are identical to the grayscale representation
506e16b04aa6041efb6507546547737e9603fa1606emsarett            // for black.
507e16b04aa6041efb6507546547737e9603fa1606emsarett            memset(dstStartRow, (uint8_t) colorOrIndex, bytesToFill);
508e16b04aa6041efb6507546547737e9603fa1606emsarett            break;
509438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett        default:
510438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            SkCodecPrintf("Error: Unsupported dst color type for fill().  Doing nothing.\n");
511438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            SkASSERT(false);
512438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett            break;
513438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett    }
514438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett}
515