1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/private/SkColorData.h" 9cb93a386Sopenharmony_ci#include "src/codec/SkCodecPriv.h" 10cb93a386Sopenharmony_ci#include "src/codec/SkMaskSwizzler.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_cistatic void swizzle_mask16_to_rgba_opaque( 13cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 14cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci // Use the masks to decode to the destination 17cb93a386Sopenharmony_ci uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; 18cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 19cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 20cb93a386Sopenharmony_ci uint16_t p = srcPtr[0]; 21cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 22cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 23cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 24cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue); 25cb93a386Sopenharmony_ci srcPtr += sampleX; 26cb93a386Sopenharmony_ci } 27cb93a386Sopenharmony_ci} 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_cistatic void swizzle_mask16_to_bgra_opaque( 30cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 31cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci // Use the masks to decode to the destination 34cb93a386Sopenharmony_ci uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; 35cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 36cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 37cb93a386Sopenharmony_ci uint16_t p = srcPtr[0]; 38cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 39cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 40cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 41cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue); 42cb93a386Sopenharmony_ci srcPtr += sampleX; 43cb93a386Sopenharmony_ci } 44cb93a386Sopenharmony_ci} 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_cistatic void swizzle_mask16_to_rgba_unpremul( 47cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 48cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci // Use the masks to decode to the destination 51cb93a386Sopenharmony_ci uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; 52cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 53cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 54cb93a386Sopenharmony_ci uint16_t p = srcPtr[0]; 55cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 56cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 57cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 58cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 59cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue); 60cb93a386Sopenharmony_ci srcPtr += sampleX; 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci} 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_cistatic void swizzle_mask16_to_bgra_unpremul( 65cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 66cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci // Use the masks to decode to the destination 69cb93a386Sopenharmony_ci uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; 70cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 71cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 72cb93a386Sopenharmony_ci uint16_t p = srcPtr[0]; 73cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 74cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 75cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 76cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 77cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue); 78cb93a386Sopenharmony_ci srcPtr += sampleX; 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci} 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_cistatic void swizzle_mask16_to_rgba_premul( 83cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 84cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci // Use the masks to decode to the destination 87cb93a386Sopenharmony_ci uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; 88cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 89cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 90cb93a386Sopenharmony_ci uint16_t p = srcPtr[0]; 91cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 92cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 93cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 94cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 95cb93a386Sopenharmony_ci dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue); 96cb93a386Sopenharmony_ci srcPtr += sampleX; 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci} 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_cistatic void swizzle_mask16_to_bgra_premul( 101cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 102cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci // Use the masks to decode to the destination 105cb93a386Sopenharmony_ci uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; 106cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 107cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 108cb93a386Sopenharmony_ci uint16_t p = srcPtr[0]; 109cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 110cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 111cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 112cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 113cb93a386Sopenharmony_ci dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue); 114cb93a386Sopenharmony_ci srcPtr += sampleX; 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci} 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci// TODO (msarett): We have promoted a two byte per pixel image to 8888, only to 119cb93a386Sopenharmony_ci// convert it back to 565. Instead, we should swizzle to 565 directly. 120cb93a386Sopenharmony_cistatic void swizzle_mask16_to_565( 121cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 122cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci // Use the masks to decode to the destination 125cb93a386Sopenharmony_ci uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; 126cb93a386Sopenharmony_ci uint16_t* dstPtr = (uint16_t*) dstRow; 127cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 128cb93a386Sopenharmony_ci uint16_t p = srcPtr[0]; 129cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 130cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 131cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 132cb93a386Sopenharmony_ci dstPtr[i] = SkPack888ToRGB16(red, green, blue); 133cb93a386Sopenharmony_ci srcPtr += sampleX; 134cb93a386Sopenharmony_ci } 135cb93a386Sopenharmony_ci} 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_cistatic void swizzle_mask24_to_rgba_opaque( 138cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 139cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 140cb93a386Sopenharmony_ci 141cb93a386Sopenharmony_ci // Use the masks to decode to the destination 142cb93a386Sopenharmony_ci srcRow += 3 * startX; 143cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 144cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 145cb93a386Sopenharmony_ci uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; 146cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 147cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 148cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 149cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue); 150cb93a386Sopenharmony_ci srcRow += 3 * sampleX; 151cb93a386Sopenharmony_ci } 152cb93a386Sopenharmony_ci} 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_cistatic void swizzle_mask24_to_bgra_opaque( 155cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 156cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci // Use the masks to decode to the destination 159cb93a386Sopenharmony_ci srcRow += 3 * startX; 160cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 161cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 162cb93a386Sopenharmony_ci uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; 163cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 164cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 165cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 166cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue); 167cb93a386Sopenharmony_ci srcRow += 3 * sampleX; 168cb93a386Sopenharmony_ci } 169cb93a386Sopenharmony_ci} 170cb93a386Sopenharmony_ci 171cb93a386Sopenharmony_cistatic void swizzle_mask24_to_rgba_unpremul( 172cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 173cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_ci // Use the masks to decode to the destination 176cb93a386Sopenharmony_ci srcRow += 3 * startX; 177cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 178cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 179cb93a386Sopenharmony_ci uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; 180cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 181cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 182cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 183cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 184cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue); 185cb93a386Sopenharmony_ci srcRow += 3 * sampleX; 186cb93a386Sopenharmony_ci } 187cb93a386Sopenharmony_ci} 188cb93a386Sopenharmony_ci 189cb93a386Sopenharmony_cistatic void swizzle_mask24_to_bgra_unpremul( 190cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 191cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci // Use the masks to decode to the destination 194cb93a386Sopenharmony_ci srcRow += 3 * startX; 195cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 196cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 197cb93a386Sopenharmony_ci uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; 198cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 199cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 200cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 201cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 202cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue); 203cb93a386Sopenharmony_ci srcRow += 3 * sampleX; 204cb93a386Sopenharmony_ci } 205cb93a386Sopenharmony_ci} 206cb93a386Sopenharmony_ci 207cb93a386Sopenharmony_cistatic void swizzle_mask24_to_rgba_premul( 208cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 209cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 210cb93a386Sopenharmony_ci 211cb93a386Sopenharmony_ci // Use the masks to decode to the destination 212cb93a386Sopenharmony_ci srcRow += 3 * startX; 213cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 214cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 215cb93a386Sopenharmony_ci uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; 216cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 217cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 218cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 219cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 220cb93a386Sopenharmony_ci dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue); 221cb93a386Sopenharmony_ci srcRow += 3 * sampleX; 222cb93a386Sopenharmony_ci } 223cb93a386Sopenharmony_ci} 224cb93a386Sopenharmony_ci 225cb93a386Sopenharmony_cistatic void swizzle_mask24_to_bgra_premul( 226cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 227cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_ci // Use the masks to decode to the destination 230cb93a386Sopenharmony_ci srcRow += 3 * startX; 231cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 232cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 233cb93a386Sopenharmony_ci uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; 234cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 235cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 236cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 237cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 238cb93a386Sopenharmony_ci dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue); 239cb93a386Sopenharmony_ci srcRow += 3 * sampleX; 240cb93a386Sopenharmony_ci } 241cb93a386Sopenharmony_ci} 242cb93a386Sopenharmony_ci 243cb93a386Sopenharmony_cistatic void swizzle_mask24_to_565( 244cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 245cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 246cb93a386Sopenharmony_ci 247cb93a386Sopenharmony_ci // Use the masks to decode to the destination 248cb93a386Sopenharmony_ci srcRow += 3 * startX; 249cb93a386Sopenharmony_ci uint16_t* dstPtr = (uint16_t*) dstRow; 250cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 251cb93a386Sopenharmony_ci uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; 252cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 253cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 254cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 255cb93a386Sopenharmony_ci dstPtr[i] = SkPack888ToRGB16(red, green, blue); 256cb93a386Sopenharmony_ci srcRow += 3 * sampleX; 257cb93a386Sopenharmony_ci } 258cb93a386Sopenharmony_ci} 259cb93a386Sopenharmony_ci 260cb93a386Sopenharmony_cistatic void swizzle_mask32_to_rgba_opaque( 261cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 262cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 263cb93a386Sopenharmony_ci 264cb93a386Sopenharmony_ci // Use the masks to decode to the destination 265cb93a386Sopenharmony_ci uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; 266cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 267cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 268cb93a386Sopenharmony_ci uint32_t p = srcPtr[0]; 269cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 270cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 271cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 272cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue); 273cb93a386Sopenharmony_ci srcPtr += sampleX; 274cb93a386Sopenharmony_ci } 275cb93a386Sopenharmony_ci} 276cb93a386Sopenharmony_ci 277cb93a386Sopenharmony_cistatic void swizzle_mask32_to_bgra_opaque( 278cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 279cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 280cb93a386Sopenharmony_ci 281cb93a386Sopenharmony_ci // Use the masks to decode to the destination 282cb93a386Sopenharmony_ci uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; 283cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 284cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 285cb93a386Sopenharmony_ci uint32_t p = srcPtr[0]; 286cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 287cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 288cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 289cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue); 290cb93a386Sopenharmony_ci srcPtr += sampleX; 291cb93a386Sopenharmony_ci } 292cb93a386Sopenharmony_ci} 293cb93a386Sopenharmony_ci 294cb93a386Sopenharmony_cistatic void swizzle_mask32_to_rgba_unpremul( 295cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 296cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 297cb93a386Sopenharmony_ci 298cb93a386Sopenharmony_ci // Use the masks to decode to the destination 299cb93a386Sopenharmony_ci uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; 300cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 301cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 302cb93a386Sopenharmony_ci uint32_t p = srcPtr[0]; 303cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 304cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 305cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 306cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 307cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue); 308cb93a386Sopenharmony_ci srcPtr += sampleX; 309cb93a386Sopenharmony_ci } 310cb93a386Sopenharmony_ci} 311cb93a386Sopenharmony_ci 312cb93a386Sopenharmony_cistatic void swizzle_mask32_to_bgra_unpremul( 313cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 314cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 315cb93a386Sopenharmony_ci 316cb93a386Sopenharmony_ci // Use the masks to decode to the destination 317cb93a386Sopenharmony_ci uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; 318cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 319cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 320cb93a386Sopenharmony_ci uint32_t p = srcPtr[0]; 321cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 322cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 323cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 324cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 325cb93a386Sopenharmony_ci dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue); 326cb93a386Sopenharmony_ci srcPtr += sampleX; 327cb93a386Sopenharmony_ci } 328cb93a386Sopenharmony_ci} 329cb93a386Sopenharmony_ci 330cb93a386Sopenharmony_cistatic void swizzle_mask32_to_rgba_premul( 331cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 332cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 333cb93a386Sopenharmony_ci 334cb93a386Sopenharmony_ci // Use the masks to decode to the destination 335cb93a386Sopenharmony_ci uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; 336cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 337cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 338cb93a386Sopenharmony_ci uint32_t p = srcPtr[0]; 339cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 340cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 341cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 342cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 343cb93a386Sopenharmony_ci dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue); 344cb93a386Sopenharmony_ci srcPtr += sampleX; 345cb93a386Sopenharmony_ci } 346cb93a386Sopenharmony_ci} 347cb93a386Sopenharmony_ci 348cb93a386Sopenharmony_cistatic void swizzle_mask32_to_bgra_premul( 349cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 350cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 351cb93a386Sopenharmony_ci 352cb93a386Sopenharmony_ci // Use the masks to decode to the destination 353cb93a386Sopenharmony_ci uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; 354cb93a386Sopenharmony_ci SkPMColor* dstPtr = (SkPMColor*) dstRow; 355cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 356cb93a386Sopenharmony_ci uint32_t p = srcPtr[0]; 357cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 358cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 359cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 360cb93a386Sopenharmony_ci uint8_t alpha = masks->getAlpha(p); 361cb93a386Sopenharmony_ci dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue); 362cb93a386Sopenharmony_ci srcPtr += sampleX; 363cb93a386Sopenharmony_ci } 364cb93a386Sopenharmony_ci} 365cb93a386Sopenharmony_ci 366cb93a386Sopenharmony_cistatic void swizzle_mask32_to_565( 367cb93a386Sopenharmony_ci void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, 368cb93a386Sopenharmony_ci uint32_t startX, uint32_t sampleX) { 369cb93a386Sopenharmony_ci // Use the masks to decode to the destination 370cb93a386Sopenharmony_ci uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; 371cb93a386Sopenharmony_ci uint16_t* dstPtr = (uint16_t*) dstRow; 372cb93a386Sopenharmony_ci for (int i = 0; i < width; i++) { 373cb93a386Sopenharmony_ci uint32_t p = srcPtr[0]; 374cb93a386Sopenharmony_ci uint8_t red = masks->getRed(p); 375cb93a386Sopenharmony_ci uint8_t green = masks->getGreen(p); 376cb93a386Sopenharmony_ci uint8_t blue = masks->getBlue(p); 377cb93a386Sopenharmony_ci dstPtr[i] = SkPack888ToRGB16(red, green, blue); 378cb93a386Sopenharmony_ci srcPtr += sampleX; 379cb93a386Sopenharmony_ci } 380cb93a386Sopenharmony_ci} 381cb93a386Sopenharmony_ci 382cb93a386Sopenharmony_ci/* 383cb93a386Sopenharmony_ci * 384cb93a386Sopenharmony_ci * Create a new mask swizzler 385cb93a386Sopenharmony_ci * 386cb93a386Sopenharmony_ci */ 387cb93a386Sopenharmony_ciSkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo, 388cb93a386Sopenharmony_ci bool srcIsOpaque, SkMasks* masks, uint32_t bitsPerPixel, 389cb93a386Sopenharmony_ci const SkCodec::Options& options) { 390cb93a386Sopenharmony_ci 391cb93a386Sopenharmony_ci // Choose the appropriate row procedure 392cb93a386Sopenharmony_ci RowProc proc = nullptr; 393cb93a386Sopenharmony_ci switch (bitsPerPixel) { 394cb93a386Sopenharmony_ci case 16: 395cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 396cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 397cb93a386Sopenharmony_ci if (srcIsOpaque) { 398cb93a386Sopenharmony_ci proc = &swizzle_mask16_to_rgba_opaque; 399cb93a386Sopenharmony_ci } else { 400cb93a386Sopenharmony_ci switch (dstInfo.alphaType()) { 401cb93a386Sopenharmony_ci case kUnpremul_SkAlphaType: 402cb93a386Sopenharmony_ci proc = &swizzle_mask16_to_rgba_unpremul; 403cb93a386Sopenharmony_ci break; 404cb93a386Sopenharmony_ci case kPremul_SkAlphaType: 405cb93a386Sopenharmony_ci proc = &swizzle_mask16_to_rgba_premul; 406cb93a386Sopenharmony_ci break; 407cb93a386Sopenharmony_ci default: 408cb93a386Sopenharmony_ci break; 409cb93a386Sopenharmony_ci } 410cb93a386Sopenharmony_ci } 411cb93a386Sopenharmony_ci break; 412cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 413cb93a386Sopenharmony_ci if (srcIsOpaque) { 414cb93a386Sopenharmony_ci proc = &swizzle_mask16_to_bgra_opaque; 415cb93a386Sopenharmony_ci } else { 416cb93a386Sopenharmony_ci switch (dstInfo.alphaType()) { 417cb93a386Sopenharmony_ci case kUnpremul_SkAlphaType: 418cb93a386Sopenharmony_ci proc = &swizzle_mask16_to_bgra_unpremul; 419cb93a386Sopenharmony_ci break; 420cb93a386Sopenharmony_ci case kPremul_SkAlphaType: 421cb93a386Sopenharmony_ci proc = &swizzle_mask16_to_bgra_premul; 422cb93a386Sopenharmony_ci break; 423cb93a386Sopenharmony_ci default: 424cb93a386Sopenharmony_ci break; 425cb93a386Sopenharmony_ci } 426cb93a386Sopenharmony_ci } 427cb93a386Sopenharmony_ci break; 428cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 429cb93a386Sopenharmony_ci proc = &swizzle_mask16_to_565; 430cb93a386Sopenharmony_ci break; 431cb93a386Sopenharmony_ci default: 432cb93a386Sopenharmony_ci break; 433cb93a386Sopenharmony_ci } 434cb93a386Sopenharmony_ci break; 435cb93a386Sopenharmony_ci case 24: 436cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 437cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 438cb93a386Sopenharmony_ci if (srcIsOpaque) { 439cb93a386Sopenharmony_ci proc = &swizzle_mask24_to_rgba_opaque; 440cb93a386Sopenharmony_ci } else { 441cb93a386Sopenharmony_ci switch (dstInfo.alphaType()) { 442cb93a386Sopenharmony_ci case kUnpremul_SkAlphaType: 443cb93a386Sopenharmony_ci proc = &swizzle_mask24_to_rgba_unpremul; 444cb93a386Sopenharmony_ci break; 445cb93a386Sopenharmony_ci case kPremul_SkAlphaType: 446cb93a386Sopenharmony_ci proc = &swizzle_mask24_to_rgba_premul; 447cb93a386Sopenharmony_ci break; 448cb93a386Sopenharmony_ci default: 449cb93a386Sopenharmony_ci break; 450cb93a386Sopenharmony_ci } 451cb93a386Sopenharmony_ci } 452cb93a386Sopenharmony_ci break; 453cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 454cb93a386Sopenharmony_ci if (srcIsOpaque) { 455cb93a386Sopenharmony_ci proc = &swizzle_mask24_to_bgra_opaque; 456cb93a386Sopenharmony_ci } else { 457cb93a386Sopenharmony_ci switch (dstInfo.alphaType()) { 458cb93a386Sopenharmony_ci case kUnpremul_SkAlphaType: 459cb93a386Sopenharmony_ci proc = &swizzle_mask24_to_bgra_unpremul; 460cb93a386Sopenharmony_ci break; 461cb93a386Sopenharmony_ci case kPremul_SkAlphaType: 462cb93a386Sopenharmony_ci proc = &swizzle_mask24_to_bgra_premul; 463cb93a386Sopenharmony_ci break; 464cb93a386Sopenharmony_ci default: 465cb93a386Sopenharmony_ci break; 466cb93a386Sopenharmony_ci } 467cb93a386Sopenharmony_ci } 468cb93a386Sopenharmony_ci break; 469cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 470cb93a386Sopenharmony_ci proc = &swizzle_mask24_to_565; 471cb93a386Sopenharmony_ci break; 472cb93a386Sopenharmony_ci default: 473cb93a386Sopenharmony_ci break; 474cb93a386Sopenharmony_ci } 475cb93a386Sopenharmony_ci break; 476cb93a386Sopenharmony_ci case 32: 477cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 478cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 479cb93a386Sopenharmony_ci if (srcIsOpaque) { 480cb93a386Sopenharmony_ci proc = &swizzle_mask32_to_rgba_opaque; 481cb93a386Sopenharmony_ci } else { 482cb93a386Sopenharmony_ci switch (dstInfo.alphaType()) { 483cb93a386Sopenharmony_ci case kUnpremul_SkAlphaType: 484cb93a386Sopenharmony_ci proc = &swizzle_mask32_to_rgba_unpremul; 485cb93a386Sopenharmony_ci break; 486cb93a386Sopenharmony_ci case kPremul_SkAlphaType: 487cb93a386Sopenharmony_ci proc = &swizzle_mask32_to_rgba_premul; 488cb93a386Sopenharmony_ci break; 489cb93a386Sopenharmony_ci default: 490cb93a386Sopenharmony_ci break; 491cb93a386Sopenharmony_ci } 492cb93a386Sopenharmony_ci } 493cb93a386Sopenharmony_ci break; 494cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 495cb93a386Sopenharmony_ci if (srcIsOpaque) { 496cb93a386Sopenharmony_ci proc = &swizzle_mask32_to_bgra_opaque; 497cb93a386Sopenharmony_ci } else { 498cb93a386Sopenharmony_ci switch (dstInfo.alphaType()) { 499cb93a386Sopenharmony_ci case kUnpremul_SkAlphaType: 500cb93a386Sopenharmony_ci proc = &swizzle_mask32_to_bgra_unpremul; 501cb93a386Sopenharmony_ci break; 502cb93a386Sopenharmony_ci case kPremul_SkAlphaType: 503cb93a386Sopenharmony_ci proc = &swizzle_mask32_to_bgra_premul; 504cb93a386Sopenharmony_ci break; 505cb93a386Sopenharmony_ci default: 506cb93a386Sopenharmony_ci break; 507cb93a386Sopenharmony_ci } 508cb93a386Sopenharmony_ci } 509cb93a386Sopenharmony_ci break; 510cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 511cb93a386Sopenharmony_ci proc = &swizzle_mask32_to_565; 512cb93a386Sopenharmony_ci break; 513cb93a386Sopenharmony_ci default: 514cb93a386Sopenharmony_ci break; 515cb93a386Sopenharmony_ci } 516cb93a386Sopenharmony_ci break; 517cb93a386Sopenharmony_ci default: 518cb93a386Sopenharmony_ci SkASSERT(false); 519cb93a386Sopenharmony_ci return nullptr; 520cb93a386Sopenharmony_ci } 521cb93a386Sopenharmony_ci 522cb93a386Sopenharmony_ci int srcOffset = 0; 523cb93a386Sopenharmony_ci int srcWidth = dstInfo.width(); 524cb93a386Sopenharmony_ci if (options.fSubset) { 525cb93a386Sopenharmony_ci srcOffset = options.fSubset->left(); 526cb93a386Sopenharmony_ci srcWidth = options.fSubset->width(); 527cb93a386Sopenharmony_ci } 528cb93a386Sopenharmony_ci 529cb93a386Sopenharmony_ci return new SkMaskSwizzler(masks, proc, srcOffset, srcWidth); 530cb93a386Sopenharmony_ci} 531cb93a386Sopenharmony_ci 532cb93a386Sopenharmony_ci/* 533cb93a386Sopenharmony_ci * 534cb93a386Sopenharmony_ci * Constructor for mask swizzler 535cb93a386Sopenharmony_ci * 536cb93a386Sopenharmony_ci */ 537cb93a386Sopenharmony_ciSkMaskSwizzler::SkMaskSwizzler(SkMasks* masks, RowProc proc, int srcOffset, int subsetWidth) 538cb93a386Sopenharmony_ci : fMasks(masks) 539cb93a386Sopenharmony_ci , fRowProc(proc) 540cb93a386Sopenharmony_ci , fSubsetWidth(subsetWidth) 541cb93a386Sopenharmony_ci , fDstWidth(subsetWidth) 542cb93a386Sopenharmony_ci , fSampleX(1) 543cb93a386Sopenharmony_ci , fSrcOffset(srcOffset) 544cb93a386Sopenharmony_ci , fX0(srcOffset) 545cb93a386Sopenharmony_ci{} 546cb93a386Sopenharmony_ci 547cb93a386Sopenharmony_ciint SkMaskSwizzler::onSetSampleX(int sampleX) { 548cb93a386Sopenharmony_ci // FIXME: Share this function with SkSwizzler? 549cb93a386Sopenharmony_ci SkASSERT(sampleX > 0); // Surely there is an upper limit? Should there be 550cb93a386Sopenharmony_ci // way to report failure? 551cb93a386Sopenharmony_ci fSampleX = sampleX; 552cb93a386Sopenharmony_ci fX0 = get_start_coord(sampleX) + fSrcOffset; 553cb93a386Sopenharmony_ci fDstWidth = get_scaled_dimension(fSubsetWidth, sampleX); 554cb93a386Sopenharmony_ci 555cb93a386Sopenharmony_ci // check that fX0 is valid 556cb93a386Sopenharmony_ci SkASSERT(fX0 >= 0); 557cb93a386Sopenharmony_ci return fDstWidth; 558cb93a386Sopenharmony_ci} 559cb93a386Sopenharmony_ci 560cb93a386Sopenharmony_ci/* 561cb93a386Sopenharmony_ci * 562cb93a386Sopenharmony_ci * Swizzle the specified row 563cb93a386Sopenharmony_ci * 564cb93a386Sopenharmony_ci */ 565cb93a386Sopenharmony_civoid SkMaskSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) { 566cb93a386Sopenharmony_ci SkASSERT(nullptr != dst && nullptr != src); 567cb93a386Sopenharmony_ci fRowProc(dst, src, fDstWidth, fMasks, fX0, fSampleX); 568cb93a386Sopenharmony_ci} 569