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