blob: 754b08883544928f7066456b409420d52a596e84 [file] [log] [blame]
scroggof24f2242015-03-03 08:59:20 -08001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
msarett74114382015-03-16 11:55:18 -07008#include "SkCodecPriv.h"
scroggof24f2242015-03-03 08:59:20 -08009#include "SkColorPriv.h"
10#include "SkSwizzler.h"
11#include "SkTemplates.h"
msarett438b2ad2015-04-09 12:43:10 -070012#include "SkUtils.h"
scroggof24f2242015-03-03 08:59:20 -080013
msarett74114382015-03-16 11:55:18 -070014SkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha,
15 uint8_t maxAlpha) {
16 // In the transparent case, this returns 0x0000
17 // In the opaque case, this returns 0xFFFF
18 // If the row is neither transparent nor opaque, returns something else
19 return (((uint16_t) maxAlpha) << 8) | zeroAlpha;
msarett36758742015-03-16 08:27:53 -070020}
21
msarett74114382015-03-16 11:55:18 -070022// kIndex1, kIndex2, kIndex4
23
msarett438b2ad2015-04-09 12:43:10 -070024static SkSwizzler::ResultAlpha swizzle_small_index_to_index(
25 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
26 int bitsPerPixel, int y, const SkPMColor ctable[]) {
27
28 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
29 INIT_RESULT_ALPHA;
30 const uint32_t pixelsPerByte = 8 / bitsPerPixel;
31 const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte);
32 const uint8_t mask = (1 << bitsPerPixel) - 1;
33 int x = 0;
34 for (uint32_t byte = 0; byte < rowBytes; byte++) {
35 uint8_t pixelData = src[byte];
36 for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) {
37 uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
38 UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT);
39 dst[x] = index;
40 pixelData <<= bitsPerPixel;
41 x++;
42 }
43 }
44 return COMPUTE_RESULT_ALPHA;
45}
46
msarett74114382015-03-16 11:55:18 -070047static SkSwizzler::ResultAlpha swizzle_small_index_to_n32(
48 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
49 int bitsPerPixel, int y, const SkPMColor ctable[]) {
50
51 SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
52 INIT_RESULT_ALPHA;
53 const uint32_t pixelsPerByte = 8 / bitsPerPixel;
54 const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte);
55 const uint8_t mask = (1 << bitsPerPixel) - 1;
56 int x = 0;
57 for (uint32_t byte = 0; byte < rowBytes; byte++) {
58 uint8_t pixelData = src[byte];
59 for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) {
60 uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
61 SkPMColor c = ctable[index];
62 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
63 dst[x] = c;
64 pixelData <<= bitsPerPixel;
65 x++;
66 }
67 }
68 return COMPUTE_RESULT_ALPHA;
69}
70
msarett438b2ad2015-04-09 12:43:10 -070071static SkSwizzler::ResultAlpha swizzle_index_to_index(
msaretteed039b2015-03-18 11:11:19 -070072 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
msarett438b2ad2015-04-09 12:43:10 -070073 int bytesPerPixel, int y, const SkPMColor ctable[]) {
msaretteed039b2015-03-18 11:11:19 -070074
msarett438b2ad2015-04-09 12:43:10 -070075 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
76 memcpy(dst, src, width);
77 // TODO (msarett): Should we skip the loop here and guess that the row is opaque/not opaque?
78 // SkScaledBitmap sampler just guesses that it is opaque. This is dangerous
79 // and probably wrong since gif and bmp (rarely) may have alpha.
80 INIT_RESULT_ALPHA;
81 for (int x = 0; x < width; x++) {
82 UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT);
msaretteed039b2015-03-18 11:11:19 -070083 }
msarett438b2ad2015-04-09 12:43:10 -070084 return COMPUTE_RESULT_ALPHA;
msaretteed039b2015-03-18 11:11:19 -070085}
86
msarett74114382015-03-16 11:55:18 -070087// kIndex
88
89static SkSwizzler::ResultAlpha swizzle_index_to_n32(
90 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
91 int bytesPerPixel, int y, const SkPMColor ctable[]) {
msarett36758742015-03-16 08:27:53 -070092
93 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
msarett74114382015-03-16 11:55:18 -070094 INIT_RESULT_ALPHA;
msarett36758742015-03-16 08:27:53 -070095 for (int x = 0; x < width; x++) {
msarett438b2ad2015-04-09 12:43:10 -070096 SkPMColor c = ctable[src[x]];
msarett74114382015-03-16 11:55:18 -070097 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
98 dst[x] = c;
msarett74114382015-03-16 11:55:18 -070099 }
100 return COMPUTE_RESULT_ALPHA;
101}
102
103static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ(
104 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
105 int bytesPerPixel, int y, const SkPMColor ctable[]) {
106
107 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
108 INIT_RESULT_ALPHA;
109 for (int x = 0; x < width; x++) {
msarett438b2ad2015-04-09 12:43:10 -0700110 SkPMColor c = ctable[src[x]];
msarett74114382015-03-16 11:55:18 -0700111 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
scroggof24f2242015-03-03 08:59:20 -0800112 if (c != 0) {
113 dst[x] = c;
114 }
scroggof24f2242015-03-03 08:59:20 -0800115 }
msarett74114382015-03-16 11:55:18 -0700116 return COMPUTE_RESULT_ALPHA;
scroggof24f2242015-03-03 08:59:20 -0800117}
118
119#undef A32_MASK_IN_PLACE
120
msarett74114382015-03-16 11:55:18 -0700121static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32(
122 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
123 int bytesPerPixel, int y, const SkPMColor ctable[]) {
124
125 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
126 for (int x = 0; x < width; x++) {
127 dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]);
128 src += bytesPerPixel;
129 }
130 return SkSwizzler::kOpaque_ResultAlpha;
131}
132
133// kBGRA
134
msaretteed039b2015-03-18 11:11:19 -0700135static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul(
msarett74114382015-03-16 11:55:18 -0700136 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
137 int bytesPerPixel, int y, const SkPMColor ctable[]) {
138
139 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
140 INIT_RESULT_ALPHA;
141 for (int x = 0; x < width; x++) {
142 uint8_t alpha = src[3];
143 UPDATE_RESULT_ALPHA(alpha);
144 dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]);
145 src += bytesPerPixel;
146 }
147 return COMPUTE_RESULT_ALPHA;
148}
149
msaretteed039b2015-03-18 11:11:19 -0700150static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_premul(
151 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
152 int bytesPerPixel, int y, const SkPMColor ctable[]) {
153
154 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
155 INIT_RESULT_ALPHA;
156 for (int x = 0; x < width; x++) {
157 uint8_t alpha = src[3];
158 UPDATE_RESULT_ALPHA(alpha);
159 dst[x] = SkPreMultiplyARGB(alpha, src[2], src[1], src[0]);
160 src += bytesPerPixel;
161 }
162 return COMPUTE_RESULT_ALPHA;
163}
164
scroggof24f2242015-03-03 08:59:20 -0800165// n32
msarett74114382015-03-16 11:55:18 -0700166static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32(
167 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
168 int bytesPerPixel, int y, const SkPMColor ctable[]) {
169
scroggof24f2242015-03-03 08:59:20 -0800170 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
171 for (int x = 0; x < width; x++) {
172 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
msarett74114382015-03-16 11:55:18 -0700173 src += bytesPerPixel;
scroggof24f2242015-03-03 08:59:20 -0800174 }
msarett74114382015-03-16 11:55:18 -0700175 return SkSwizzler::kOpaque_ResultAlpha;
scroggof24f2242015-03-03 08:59:20 -0800176}
177
msarett74114382015-03-16 11:55:18 -0700178static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul(
179 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
180 int bytesPerPixel, int y, const SkPMColor ctable[]) {
181
scroggof24f2242015-03-03 08:59:20 -0800182 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
msarett74114382015-03-16 11:55:18 -0700183 INIT_RESULT_ALPHA;
scroggof24f2242015-03-03 08:59:20 -0800184 for (int x = 0; x < width; x++) {
185 unsigned alpha = src[3];
msarett74114382015-03-16 11:55:18 -0700186 UPDATE_RESULT_ALPHA(alpha);
scroggof24f2242015-03-03 08:59:20 -0800187 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
msarett74114382015-03-16 11:55:18 -0700188 src += bytesPerPixel;
scroggof24f2242015-03-03 08:59:20 -0800189 }
msarett74114382015-03-16 11:55:18 -0700190 return COMPUTE_RESULT_ALPHA;
scroggof24f2242015-03-03 08:59:20 -0800191}
192
msarett74114382015-03-16 11:55:18 -0700193static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul(
194 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
195 int bytesPerPixel, int y, const SkPMColor ctable[]) {
196
scroggof24f2242015-03-03 08:59:20 -0800197 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
msarett74114382015-03-16 11:55:18 -0700198 INIT_RESULT_ALPHA;
scroggof24f2242015-03-03 08:59:20 -0800199 for (int x = 0; x < width; x++) {
200 unsigned alpha = src[3];
msarett74114382015-03-16 11:55:18 -0700201 UPDATE_RESULT_ALPHA(alpha);
scroggof24f2242015-03-03 08:59:20 -0800202 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
msarett74114382015-03-16 11:55:18 -0700203 src += bytesPerPixel;
scroggof24f2242015-03-03 08:59:20 -0800204 }
msarett74114382015-03-16 11:55:18 -0700205 return COMPUTE_RESULT_ALPHA;
scroggof24f2242015-03-03 08:59:20 -0800206}
207
msarett74114382015-03-16 11:55:18 -0700208static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ(
209 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
210 int bytesPerPixel, int y, const SkPMColor ctable[]) {
211
scroggof24f2242015-03-03 08:59:20 -0800212 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
msarett74114382015-03-16 11:55:18 -0700213 INIT_RESULT_ALPHA;
scroggof24f2242015-03-03 08:59:20 -0800214 for (int x = 0; x < width; x++) {
215 unsigned alpha = src[3];
msarett74114382015-03-16 11:55:18 -0700216 UPDATE_RESULT_ALPHA(alpha);
scroggof24f2242015-03-03 08:59:20 -0800217 if (0 != alpha) {
218 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
219 }
msarett74114382015-03-16 11:55:18 -0700220 src += bytesPerPixel;
scroggof24f2242015-03-03 08:59:20 -0800221 }
msarett74114382015-03-16 11:55:18 -0700222 return COMPUTE_RESULT_ALPHA;
scroggof24f2242015-03-03 08:59:20 -0800223}
224
225/**
226 FIXME: This was my idea to cheat in order to continue taking advantage of skipping zeroes.
227 This would be fine for drawing normally, but not for drawing with transfer modes. Being
228 honest means we can draw correctly with transfer modes, with the cost of not being able
229 to take advantage of Android's free unwritten pages. Something to keep in mind when we
230 decide whether to switch to unpremul default.
231static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
232 const uint8_t* SK_RESTRICT src,
msarett74114382015-03-16 11:55:18 -0700233 int width, int bitsPerPixel,
scroggof24f2242015-03-03 08:59:20 -0800234 const SkPMColor[]) {
235 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
236 unsigned alphaMask = 0xFF;
237 for (int x = 0; x < width; x++) {
238 unsigned alpha = src[3];
239 // NOTE: We cheat here. The caller requested unpremul and skip zeroes. It's possible
240 // the color components are not zero, but we skip them anyway, meaning they'll remain
241 // zero (implied by the request to skip zeroes).
242 if (0 != alpha) {
243 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
244 }
245 src += deltaSrc;
246 alphaMask &= alpha;
247 }
248 return alphaMask != 0xFF;
249}
250*/
251
msarett74114382015-03-16 11:55:18 -0700252SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
253 const SkPMColor* ctable,
scroggof24f2242015-03-03 08:59:20 -0800254 const SkImageInfo& info, void* dst,
scroggo95526622015-03-17 05:02:17 -0700255 size_t dstRowBytes,
256 SkImageGenerator::ZeroInitialized zeroInit) {
scroggo05245902015-03-25 11:11:52 -0700257 if (info.colorType() == kUnknown_SkColorType || kUnknown == sc) {
scroggof24f2242015-03-03 08:59:20 -0800258 return NULL;
259 }
260 if (info.minRowBytes() > dstRowBytes) {
261 return NULL;
262 }
msarett74114382015-03-16 11:55:18 -0700263 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
264 && NULL == ctable) {
scroggof24f2242015-03-03 08:59:20 -0800265 return NULL;
266 }
267 RowProc proc = NULL;
268 switch (sc) {
msarett74114382015-03-16 11:55:18 -0700269 case kIndex1:
270 case kIndex2:
271 case kIndex4:
272 switch (info.colorType()) {
273 case kN32_SkColorType:
274 proc = &swizzle_small_index_to_n32;
275 break;
msarett438b2ad2015-04-09 12:43:10 -0700276 case kIndex_8_SkColorType:
277 proc = &swizzle_small_index_to_index;
msaretteed039b2015-03-18 11:11:19 -0700278 break;
msarett74114382015-03-16 11:55:18 -0700279 default:
280 break;
281 }
282 break;
scroggof24f2242015-03-03 08:59:20 -0800283 case kIndex:
284 switch (info.colorType()) {
285 case kN32_SkColorType:
scroggo95526622015-03-17 05:02:17 -0700286 // We assume the color premultiplied ctable (or not) as desired.
287 if (SkImageGenerator::kYes_ZeroInitialized == zeroInit) {
scroggof24f2242015-03-03 08:59:20 -0800288 proc = &swizzle_index_to_n32_skipZ;
msaretteed039b2015-03-18 11:11:19 -0700289 break;
scroggof24f2242015-03-03 08:59:20 -0800290 } else {
291 proc = &swizzle_index_to_n32;
msaretteed039b2015-03-18 11:11:19 -0700292 break;
scroggof24f2242015-03-03 08:59:20 -0800293 }
294 break;
msarett438b2ad2015-04-09 12:43:10 -0700295 case kIndex_8_SkColorType:
296 proc = &swizzle_index_to_index;
msaretteed039b2015-03-18 11:11:19 -0700297 break;
msarett74114382015-03-16 11:55:18 -0700298 default:
299 break;
300 }
301 break;
302 case kBGR:
303 case kBGRX:
304 switch (info.colorType()) {
305 case kN32_SkColorType:
306 proc = &swizzle_bgrx_to_n32;
307 break;
308 default:
309 break;
310 }
311 break;
312 case kBGRA:
313 switch (info.colorType()) {
314 case kN32_SkColorType:
msaretteed039b2015-03-18 11:11:19 -0700315 switch (info.alphaType()) {
316 case kUnpremul_SkAlphaType:
317 proc = &swizzle_bgra_to_n32_unpremul;
318 break;
319 case kPremul_SkAlphaType:
320 proc = &swizzle_bgra_to_n32_premul;
321 break;
322 default:
323 break;
324 }
msarett74114382015-03-16 11:55:18 -0700325 break;
scroggof24f2242015-03-03 08:59:20 -0800326 default:
327 break;
328 }
329 break;
330 case kRGBX:
331 // TODO: Support other swizzles.
332 switch (info.colorType()) {
333 case kN32_SkColorType:
334 proc = &swizzle_rgbx_to_n32;
335 break;
336 default:
337 break;
338 }
339 break;
340 case kRGBA:
341 switch (info.colorType()) {
342 case kN32_SkColorType:
343 if (info.alphaType() == kUnpremul_SkAlphaType) {
scroggo95526622015-03-17 05:02:17 -0700344 // Respect zeroInit?
scroggof24f2242015-03-03 08:59:20 -0800345 proc = &swizzle_rgba_to_n32_unpremul;
346 } else {
scroggo95526622015-03-17 05:02:17 -0700347 if (SkImageGenerator::kYes_ZeroInitialized == zeroInit) {
scroggof24f2242015-03-03 08:59:20 -0800348 proc = &swizzle_rgba_to_n32_premul_skipZ;
349 } else {
350 proc = &swizzle_rgba_to_n32_premul;
351 }
352 }
353 break;
354 default:
355 break;
356 }
357 break;
msarett74114382015-03-16 11:55:18 -0700358 case kRGB:
359 switch (info.colorType()) {
360 case kN32_SkColorType:
361 proc = &swizzle_rgbx_to_n32;
362 break;
363 default:
364 break;
365 }
366 break;
scroggof24f2242015-03-03 08:59:20 -0800367 default:
368 break;
369 }
370 if (NULL == proc) {
371 return NULL;
372 }
msarett74114382015-03-16 11:55:18 -0700373
374 // Store deltaSrc in bytes if it is an even multiple, otherwise use bits
375 int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) :
376 BitsPerPixel(sc);
377 return SkNEW_ARGS(SkSwizzler, (proc, ctable, deltaSrc, info, dst,
378 dstRowBytes));
scroggof24f2242015-03-03 08:59:20 -0800379}
380
msarett74114382015-03-16 11:55:18 -0700381SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable,
382 int deltaSrc, const SkImageInfo& info, void* dst,
383 size_t rowBytes)
scroggof24f2242015-03-03 08:59:20 -0800384 : fRowProc(proc)
385 , fColorTable(ctable)
msarett74114382015-03-16 11:55:18 -0700386 , fDeltaSrc(deltaSrc)
scroggof24f2242015-03-03 08:59:20 -0800387 , fDstInfo(info)
388 , fDstRow(dst)
389 , fDstRowBytes(rowBytes)
390 , fCurrY(0)
391{
msarett74114382015-03-16 11:55:18 -0700392 SkDEBUGCODE(fNextMode = kUninitialized_NextMode);
scroggof24f2242015-03-03 08:59:20 -0800393}
394
msarett74114382015-03-16 11:55:18 -0700395SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src) {
396 SkASSERT(0 <= fCurrY && fCurrY < fDstInfo.height());
scroggo05245902015-03-25 11:11:52 -0700397 SkASSERT(fDstRow != NULL);
msarett74114382015-03-16 11:55:18 -0700398 SkASSERT(kDesignateRow_NextMode != fNextMode);
399 SkDEBUGCODE(fNextMode = kConsecutive_NextMode);
400
401 // Decode a row
402 const ResultAlpha result = fRowProc(fDstRow, src, fDstInfo.width(),
403 fDeltaSrc, fCurrY, fColorTable);
404
405 // Move to the next row and return the result
scroggo05245902015-03-25 11:11:52 -0700406 fCurrY++;
scroggof24f2242015-03-03 08:59:20 -0800407 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes);
msarett74114382015-03-16 11:55:18 -0700408 return result;
409}
410
411SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src,
412 int y) {
413 SkASSERT(0 <= y && y < fDstInfo.height());
414 SkASSERT(kConsecutive_NextMode != fNextMode);
415 SkDEBUGCODE(fNextMode = kDesignateRow_NextMode);
416
417 // Choose the row
418 void* row = SkTAddOffset<void>(fDstRow, y*fDstRowBytes);
419
420 // Decode the row
421 return fRowProc(row, src, fDstInfo.width(), fDeltaSrc, fCurrY,
422 fColorTable);
scroggof24f2242015-03-03 08:59:20 -0800423}
msarett438b2ad2015-04-09 12:43:10 -0700424
425void SkSwizzler::Fill(void* dst, const SkImageInfo& dstInfo, size_t dstRowBytes, uint32_t y,
426 uint32_t colorOrIndex, SkPMColor* colorTable) {
427 SkASSERT(dst != NULL);
428 SkASSERT(y < (uint32_t) dstInfo.height());
429
430 // Get dst start row
431 void* dstRow = SkTAddOffset<void*>(dst, y * dstRowBytes);
432
433 // Calculate remaining bytes. This is tricky since the final row may not be padded.
434 const size_t totalBytes = dstInfo.getSafeSize(dstRowBytes);
435 const size_t remainingBytes = totalBytes - y * dstRowBytes;
436
437 // Use the proper memset routine to fill the remaining bytes
438 switch(dstInfo.colorType()) {
439 case kN32_SkColorType:
440 // Assume input is an index if we have a color table
441 uint32_t color;
442 if (NULL != colorTable) {
443 SkASSERT(colorOrIndex == (uint8_t) colorOrIndex);
444 color = colorTable[colorOrIndex];
445 // Otherwise, assume the input is a color
446 } else {
447 color = colorOrIndex;
448 }
449
450 // We must fill row by row in the case of unaligned row bytes
451 if (SkIsAlign4((size_t) dstRow) && SkIsAlign4(dstRowBytes)) {
452 sk_memset32((uint32_t*) dstRow, color,
453 (uint32_t) remainingBytes / sizeof(SkPMColor));
454 } else {
455 // This is an unlikely, slow case
456 SkCodecPrintf("Warning: Strange number of row bytes, fill will be slow.\n");
457 for (int32_t row = y; row < dstInfo.height(); row++) {
458 uint32_t* dstPtr = (uint32_t*) dstRow;
459 for (int32_t col = 0; col < dstInfo.width(); col++) {
460 dstPtr[col] = color;
461 }
462 dstRow = SkTAddOffset<void*>(dstRow, dstRowBytes);
463 }
464 }
465 break;
466 // On an index destination color type, always assume the input is an index
467 case kIndex_8_SkColorType:
468 SkASSERT(colorOrIndex == (uint8_t) colorOrIndex);
469 memset(dstRow, colorOrIndex, remainingBytes);
470 break;
471 default:
472 SkCodecPrintf("Error: Unsupported dst color type for fill(). Doing nothing.\n");
473 SkASSERT(false);
474 break;
475 }
476}