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 "include/private/SkHalf.h" 10cb93a386Sopenharmony_ci#include "include/private/SkTemplates.h" 11cb93a386Sopenharmony_ci#include "src/codec/SkCodecPriv.h" 12cb93a386Sopenharmony_ci#include "src/codec/SkSwizzler.h" 13cb93a386Sopenharmony_ci#include "src/core/SkOpts.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 16cb93a386Sopenharmony_ci #include "include/android/SkAndroidFrameworkUtils.h" 17cb93a386Sopenharmony_ci#endif 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_cistatic void copy(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 20cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 21cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 22cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 23cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ci memcpy(dst, src + offset, width * bpp); 26cb93a386Sopenharmony_ci} 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_cistatic void sample1(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 29cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 30cb93a386Sopenharmony_ci src += offset; 31cb93a386Sopenharmony_ci uint8_t* dst8 = (uint8_t*) dst; 32cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 33cb93a386Sopenharmony_ci dst8[x] = *src; 34cb93a386Sopenharmony_ci src += deltaSrc; 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci} 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_cistatic void sample2(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 39cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 40cb93a386Sopenharmony_ci src += offset; 41cb93a386Sopenharmony_ci uint16_t* dst16 = (uint16_t*) dst; 42cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 43cb93a386Sopenharmony_ci dst16[x] = *((const uint16_t*) src); 44cb93a386Sopenharmony_ci src += deltaSrc; 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci} 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_cistatic void sample4(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 49cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 50cb93a386Sopenharmony_ci src += offset; 51cb93a386Sopenharmony_ci uint32_t* dst32 = (uint32_t*) dst; 52cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 53cb93a386Sopenharmony_ci dst32[x] = *((const uint32_t*) src); 54cb93a386Sopenharmony_ci src += deltaSrc; 55cb93a386Sopenharmony_ci } 56cb93a386Sopenharmony_ci} 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_cistatic void sample6(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 59cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 60cb93a386Sopenharmony_ci src += offset; 61cb93a386Sopenharmony_ci uint8_t* dst8 = (uint8_t*) dst; 62cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 63cb93a386Sopenharmony_ci memcpy(dst8, src, 6); 64cb93a386Sopenharmony_ci dst8 += 6; 65cb93a386Sopenharmony_ci src += deltaSrc; 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci} 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_cistatic void sample8(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 70cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 71cb93a386Sopenharmony_ci src += offset; 72cb93a386Sopenharmony_ci uint64_t* dst64 = (uint64_t*) dst; 73cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 74cb93a386Sopenharmony_ci dst64[x] = *((const uint64_t*) src); 75cb93a386Sopenharmony_ci src += deltaSrc; 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci} 78cb93a386Sopenharmony_ci 79cb93a386Sopenharmony_ci// kBit 80cb93a386Sopenharmony_ci// These routines exclusively choose between white and black 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci#define GRAYSCALE_BLACK 0 83cb93a386Sopenharmony_ci#define GRAYSCALE_WHITE 0xFF 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci// same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x] 87cb93a386Sopenharmony_cistatic void swizzle_bit_to_grayscale( 88cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 89cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) { 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci // increment src by byte offset and bitIndex by bit offset 94cb93a386Sopenharmony_ci src += offset / 8; 95cb93a386Sopenharmony_ci int bitIndex = offset % 8; 96cb93a386Sopenharmony_ci uint8_t currByte = *src; 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_ci dst[0] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK; 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci for (int x = 1; x < dstWidth; x++) { 101cb93a386Sopenharmony_ci int bitOffset = bitIndex + deltaSrc; 102cb93a386Sopenharmony_ci bitIndex = bitOffset % 8; 103cb93a386Sopenharmony_ci currByte = *(src += bitOffset / 8); 104cb93a386Sopenharmony_ci dst[x] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK; 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci} 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci#undef GRAYSCALE_BLACK 109cb93a386Sopenharmony_ci#undef GRAYSCALE_WHITE 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci// same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x] 112cb93a386Sopenharmony_cistatic void swizzle_bit_to_n32( 113cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 114cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) { 115cb93a386Sopenharmony_ci SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow; 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci // increment src by byte offset and bitIndex by bit offset 118cb93a386Sopenharmony_ci src += offset / 8; 119cb93a386Sopenharmony_ci int bitIndex = offset % 8; 120cb93a386Sopenharmony_ci uint8_t currByte = *src; 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK; 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci for (int x = 1; x < dstWidth; x++) { 125cb93a386Sopenharmony_ci int bitOffset = bitIndex + deltaSrc; 126cb93a386Sopenharmony_ci bitIndex = bitOffset % 8; 127cb93a386Sopenharmony_ci currByte = *(src += bitOffset / 8); 128cb93a386Sopenharmony_ci dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK; 129cb93a386Sopenharmony_ci } 130cb93a386Sopenharmony_ci} 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_ci#define RGB565_BLACK 0 133cb93a386Sopenharmony_ci#define RGB565_WHITE 0xFFFF 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_cistatic void swizzle_bit_to_565( 136cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 137cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) { 138cb93a386Sopenharmony_ci uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow; 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci // increment src by byte offset and bitIndex by bit offset 141cb93a386Sopenharmony_ci src += offset / 8; 142cb93a386Sopenharmony_ci int bitIndex = offset % 8; 143cb93a386Sopenharmony_ci uint8_t currByte = *src; 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_ci dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK; 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_ci for (int x = 1; x < dstWidth; x++) { 148cb93a386Sopenharmony_ci int bitOffset = bitIndex + deltaSrc; 149cb93a386Sopenharmony_ci bitIndex = bitOffset % 8; 150cb93a386Sopenharmony_ci currByte = *(src += bitOffset / 8); 151cb93a386Sopenharmony_ci dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK; 152cb93a386Sopenharmony_ci } 153cb93a386Sopenharmony_ci} 154cb93a386Sopenharmony_ci 155cb93a386Sopenharmony_ci#undef RGB565_BLACK 156cb93a386Sopenharmony_ci#undef RGB565_WHITE 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_cistatic void swizzle_bit_to_f16( 159cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 160cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) { 161cb93a386Sopenharmony_ci constexpr uint64_t kWhite = (((uint64_t) SK_Half1) << 0) | 162cb93a386Sopenharmony_ci (((uint64_t) SK_Half1) << 16) | 163cb93a386Sopenharmony_ci (((uint64_t) SK_Half1) << 32) | 164cb93a386Sopenharmony_ci (((uint64_t) SK_Half1) << 48); 165cb93a386Sopenharmony_ci constexpr uint64_t kBlack = (((uint64_t) 0) << 0) | 166cb93a386Sopenharmony_ci (((uint64_t) 0) << 16) | 167cb93a386Sopenharmony_ci (((uint64_t) 0) << 32) | 168cb93a386Sopenharmony_ci (((uint64_t) SK_Half1) << 48); 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci uint64_t* SK_RESTRICT dst = (uint64_t*) dstRow; 171cb93a386Sopenharmony_ci 172cb93a386Sopenharmony_ci // increment src by byte offset and bitIndex by bit offset 173cb93a386Sopenharmony_ci src += offset / 8; 174cb93a386Sopenharmony_ci int bitIndex = offset % 8; 175cb93a386Sopenharmony_ci uint8_t currByte = *src; 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_ci dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack; 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_ci for (int x = 1; x < dstWidth; x++) { 180cb93a386Sopenharmony_ci int bitOffset = bitIndex + deltaSrc; 181cb93a386Sopenharmony_ci bitIndex = bitOffset % 8; 182cb93a386Sopenharmony_ci currByte = *(src += bitOffset / 8); 183cb93a386Sopenharmony_ci dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack; 184cb93a386Sopenharmony_ci } 185cb93a386Sopenharmony_ci} 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ci// kIndex1, kIndex2, kIndex4 188cb93a386Sopenharmony_ci 189cb93a386Sopenharmony_cistatic void swizzle_small_index_to_565( 190cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 191cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci uint16_t* dst = (uint16_t*) dstRow; 194cb93a386Sopenharmony_ci src += offset / 8; 195cb93a386Sopenharmony_ci int bitIndex = offset % 8; 196cb93a386Sopenharmony_ci uint8_t currByte = *src; 197cb93a386Sopenharmony_ci const uint8_t mask = (1 << bpp) - 1; 198cb93a386Sopenharmony_ci uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask; 199cb93a386Sopenharmony_ci dst[0] = SkPixel32ToPixel16(ctable[index]); 200cb93a386Sopenharmony_ci 201cb93a386Sopenharmony_ci for (int x = 1; x < dstWidth; x++) { 202cb93a386Sopenharmony_ci int bitOffset = bitIndex + deltaSrc; 203cb93a386Sopenharmony_ci bitIndex = bitOffset % 8; 204cb93a386Sopenharmony_ci currByte = *(src += bitOffset / 8); 205cb93a386Sopenharmony_ci index = (currByte >> (8 - bpp - bitIndex)) & mask; 206cb93a386Sopenharmony_ci dst[x] = SkPixel32ToPixel16(ctable[index]); 207cb93a386Sopenharmony_ci } 208cb93a386Sopenharmony_ci} 209cb93a386Sopenharmony_ci 210cb93a386Sopenharmony_cistatic void swizzle_small_index_to_n32( 211cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 212cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 213cb93a386Sopenharmony_ci 214cb93a386Sopenharmony_ci SkPMColor* dst = (SkPMColor*) dstRow; 215cb93a386Sopenharmony_ci src += offset / 8; 216cb93a386Sopenharmony_ci int bitIndex = offset % 8; 217cb93a386Sopenharmony_ci uint8_t currByte = *src; 218cb93a386Sopenharmony_ci const uint8_t mask = (1 << bpp) - 1; 219cb93a386Sopenharmony_ci uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask; 220cb93a386Sopenharmony_ci dst[0] = ctable[index]; 221cb93a386Sopenharmony_ci 222cb93a386Sopenharmony_ci for (int x = 1; x < dstWidth; x++) { 223cb93a386Sopenharmony_ci int bitOffset = bitIndex + deltaSrc; 224cb93a386Sopenharmony_ci bitIndex = bitOffset % 8; 225cb93a386Sopenharmony_ci currByte = *(src += bitOffset / 8); 226cb93a386Sopenharmony_ci index = (currByte >> (8 - bpp - bitIndex)) & mask; 227cb93a386Sopenharmony_ci dst[x] = ctable[index]; 228cb93a386Sopenharmony_ci } 229cb93a386Sopenharmony_ci} 230cb93a386Sopenharmony_ci 231cb93a386Sopenharmony_ci// kIndex 232cb93a386Sopenharmony_ci 233cb93a386Sopenharmony_cistatic void swizzle_index_to_n32( 234cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 235cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 236cb93a386Sopenharmony_ci 237cb93a386Sopenharmony_ci src += offset; 238cb93a386Sopenharmony_ci SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 239cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 240cb93a386Sopenharmony_ci SkPMColor c = ctable[*src]; 241cb93a386Sopenharmony_ci dst[x] = c; 242cb93a386Sopenharmony_ci src += deltaSrc; 243cb93a386Sopenharmony_ci } 244cb93a386Sopenharmony_ci} 245cb93a386Sopenharmony_ci 246cb93a386Sopenharmony_cistatic void swizzle_index_to_n32_skipZ( 247cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 248cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_ci src += offset; 251cb93a386Sopenharmony_ci SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 252cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 253cb93a386Sopenharmony_ci SkPMColor c = ctable[*src]; 254cb93a386Sopenharmony_ci if (c != 0) { 255cb93a386Sopenharmony_ci dst[x] = c; 256cb93a386Sopenharmony_ci } 257cb93a386Sopenharmony_ci src += deltaSrc; 258cb93a386Sopenharmony_ci } 259cb93a386Sopenharmony_ci} 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_cistatic void swizzle_index_to_565( 262cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 263cb93a386Sopenharmony_ci int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) { 264cb93a386Sopenharmony_ci src += offset; 265cb93a386Sopenharmony_ci uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 266cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 267cb93a386Sopenharmony_ci dst[x] = SkPixel32ToPixel16(ctable[*src]); 268cb93a386Sopenharmony_ci src += deltaSrc; 269cb93a386Sopenharmony_ci } 270cb93a386Sopenharmony_ci} 271cb93a386Sopenharmony_ci 272cb93a386Sopenharmony_ci// kGray 273cb93a386Sopenharmony_ci 274cb93a386Sopenharmony_cistatic void swizzle_gray_to_n32( 275cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 276cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 277cb93a386Sopenharmony_ci 278cb93a386Sopenharmony_ci src += offset; 279cb93a386Sopenharmony_ci SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 280cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 281cb93a386Sopenharmony_ci dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src); 282cb93a386Sopenharmony_ci src += deltaSrc; 283cb93a386Sopenharmony_ci } 284cb93a386Sopenharmony_ci} 285cb93a386Sopenharmony_ci 286cb93a386Sopenharmony_cistatic void fast_swizzle_gray_to_n32( 287cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 288cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 289cb93a386Sopenharmony_ci 290cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 291cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 292cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 293cb93a386Sopenharmony_ci 294cb93a386Sopenharmony_ci // Note that there is no need to distinguish between RGB and BGR. 295cb93a386Sopenharmony_ci // Each color channel will get the same value. 296cb93a386Sopenharmony_ci SkOpts::gray_to_RGB1((uint32_t*) dst, src + offset, width); 297cb93a386Sopenharmony_ci} 298cb93a386Sopenharmony_ci 299cb93a386Sopenharmony_cistatic void swizzle_gray_to_565( 300cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 301cb93a386Sopenharmony_ci int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) { 302cb93a386Sopenharmony_ci 303cb93a386Sopenharmony_ci src += offset; 304cb93a386Sopenharmony_ci uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 305cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 306cb93a386Sopenharmony_ci dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); 307cb93a386Sopenharmony_ci src += deltaSrc; 308cb93a386Sopenharmony_ci } 309cb93a386Sopenharmony_ci} 310cb93a386Sopenharmony_ci 311cb93a386Sopenharmony_ci// kGrayAlpha 312cb93a386Sopenharmony_ci 313cb93a386Sopenharmony_cistatic void swizzle_grayalpha_to_n32_unpremul( 314cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 315cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 316cb93a386Sopenharmony_ci 317cb93a386Sopenharmony_ci src += offset; 318cb93a386Sopenharmony_ci SkPMColor* dst32 = (SkPMColor*) dst; 319cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 320cb93a386Sopenharmony_ci dst32[x] = SkPackARGB32NoCheck(src[1], src[0], src[0], src[0]); 321cb93a386Sopenharmony_ci src += deltaSrc; 322cb93a386Sopenharmony_ci } 323cb93a386Sopenharmony_ci} 324cb93a386Sopenharmony_ci 325cb93a386Sopenharmony_cistatic void fast_swizzle_grayalpha_to_n32_unpremul( 326cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 327cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 328cb93a386Sopenharmony_ci 329cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 330cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 331cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 332cb93a386Sopenharmony_ci 333cb93a386Sopenharmony_ci // Note that there is no need to distinguish between RGB and BGR. 334cb93a386Sopenharmony_ci // Each color channel will get the same value. 335cb93a386Sopenharmony_ci SkOpts::grayA_to_RGBA((uint32_t*) dst, src + offset, width); 336cb93a386Sopenharmony_ci} 337cb93a386Sopenharmony_ci 338cb93a386Sopenharmony_cistatic void swizzle_grayalpha_to_n32_premul( 339cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 340cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 341cb93a386Sopenharmony_ci 342cb93a386Sopenharmony_ci src += offset; 343cb93a386Sopenharmony_ci SkPMColor* dst32 = (SkPMColor*) dst; 344cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 345cb93a386Sopenharmony_ci uint8_t pmgray = SkMulDiv255Round(src[1], src[0]); 346cb93a386Sopenharmony_ci dst32[x] = SkPackARGB32NoCheck(src[1], pmgray, pmgray, pmgray); 347cb93a386Sopenharmony_ci src += deltaSrc; 348cb93a386Sopenharmony_ci } 349cb93a386Sopenharmony_ci} 350cb93a386Sopenharmony_ci 351cb93a386Sopenharmony_cistatic void fast_swizzle_grayalpha_to_n32_premul( 352cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 353cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 354cb93a386Sopenharmony_ci 355cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 356cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 357cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 358cb93a386Sopenharmony_ci 359cb93a386Sopenharmony_ci // Note that there is no need to distinguish between rgb and bgr. 360cb93a386Sopenharmony_ci // Each color channel will get the same value. 361cb93a386Sopenharmony_ci SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width); 362cb93a386Sopenharmony_ci} 363cb93a386Sopenharmony_ci 364cb93a386Sopenharmony_cistatic void swizzle_grayalpha_to_a8(void* dst, const uint8_t* src, int width, int bpp, 365cb93a386Sopenharmony_ci int deltaSrc, int offset, const SkPMColor[]) { 366cb93a386Sopenharmony_ci src += offset; 367cb93a386Sopenharmony_ci uint8_t* dst8 = (uint8_t*)dst; 368cb93a386Sopenharmony_ci for (int x = 0; x < width; ++x) { 369cb93a386Sopenharmony_ci dst8[x] = src[1]; // src[0] is gray, ignored 370cb93a386Sopenharmony_ci src += deltaSrc; 371cb93a386Sopenharmony_ci } 372cb93a386Sopenharmony_ci} 373cb93a386Sopenharmony_ci 374cb93a386Sopenharmony_ci// kBGR 375cb93a386Sopenharmony_ci 376cb93a386Sopenharmony_cistatic void swizzle_bgr_to_565( 377cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 378cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 379cb93a386Sopenharmony_ci 380cb93a386Sopenharmony_ci src += offset; 381cb93a386Sopenharmony_ci uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 382cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 383cb93a386Sopenharmony_ci dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]); 384cb93a386Sopenharmony_ci src += deltaSrc; 385cb93a386Sopenharmony_ci } 386cb93a386Sopenharmony_ci} 387cb93a386Sopenharmony_ci 388cb93a386Sopenharmony_ci// kRGB 389cb93a386Sopenharmony_ci 390cb93a386Sopenharmony_cistatic void swizzle_rgb_to_rgba( 391cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 392cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 393cb93a386Sopenharmony_ci 394cb93a386Sopenharmony_ci src += offset; 395cb93a386Sopenharmony_ci SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 396cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 397cb93a386Sopenharmony_ci dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]); 398cb93a386Sopenharmony_ci src += deltaSrc; 399cb93a386Sopenharmony_ci } 400cb93a386Sopenharmony_ci} 401cb93a386Sopenharmony_ci 402cb93a386Sopenharmony_cistatic void swizzle_rgb_to_bgra( 403cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 404cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 405cb93a386Sopenharmony_ci 406cb93a386Sopenharmony_ci src += offset; 407cb93a386Sopenharmony_ci SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 408cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 409cb93a386Sopenharmony_ci dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]); 410cb93a386Sopenharmony_ci src += deltaSrc; 411cb93a386Sopenharmony_ci } 412cb93a386Sopenharmony_ci} 413cb93a386Sopenharmony_ci 414cb93a386Sopenharmony_cistatic void fast_swizzle_rgb_to_rgba( 415cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, 416cb93a386Sopenharmony_ci int offset, const SkPMColor ctable[]) { 417cb93a386Sopenharmony_ci 418cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 419cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 420cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 421cb93a386Sopenharmony_ci 422cb93a386Sopenharmony_ci SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width); 423cb93a386Sopenharmony_ci} 424cb93a386Sopenharmony_ci 425cb93a386Sopenharmony_cistatic void fast_swizzle_rgb_to_bgra( 426cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, 427cb93a386Sopenharmony_ci int offset, const SkPMColor ctable[]) { 428cb93a386Sopenharmony_ci 429cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 430cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 431cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 432cb93a386Sopenharmony_ci 433cb93a386Sopenharmony_ci SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width); 434cb93a386Sopenharmony_ci} 435cb93a386Sopenharmony_ci 436cb93a386Sopenharmony_cistatic void swizzle_rgb_to_565( 437cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 438cb93a386Sopenharmony_ci int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) { 439cb93a386Sopenharmony_ci 440cb93a386Sopenharmony_ci src += offset; 441cb93a386Sopenharmony_ci uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 442cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 443cb93a386Sopenharmony_ci dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); 444cb93a386Sopenharmony_ci src += deltaSrc; 445cb93a386Sopenharmony_ci } 446cb93a386Sopenharmony_ci} 447cb93a386Sopenharmony_ci 448cb93a386Sopenharmony_ci// kRGBA 449cb93a386Sopenharmony_ci 450cb93a386Sopenharmony_cistatic void swizzle_rgba_to_rgba_premul( 451cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 452cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 453cb93a386Sopenharmony_ci 454cb93a386Sopenharmony_ci src += offset; 455cb93a386Sopenharmony_ci SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 456cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 457cb93a386Sopenharmony_ci dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]); 458cb93a386Sopenharmony_ci src += deltaSrc; 459cb93a386Sopenharmony_ci } 460cb93a386Sopenharmony_ci} 461cb93a386Sopenharmony_ci 462cb93a386Sopenharmony_cistatic void swizzle_rgba_to_bgra_premul( 463cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 464cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 465cb93a386Sopenharmony_ci 466cb93a386Sopenharmony_ci src += offset; 467cb93a386Sopenharmony_ci SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 468cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 469cb93a386Sopenharmony_ci dst[x] = premultiply_argb_as_bgra(src[3], src[0], src[1], src[2]); 470cb93a386Sopenharmony_ci src += deltaSrc; 471cb93a386Sopenharmony_ci } 472cb93a386Sopenharmony_ci} 473cb93a386Sopenharmony_ci 474cb93a386Sopenharmony_cistatic void fast_swizzle_rgba_to_rgba_premul( 475cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, 476cb93a386Sopenharmony_ci int offset, const SkPMColor ctable[]) { 477cb93a386Sopenharmony_ci 478cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 479cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 480cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 481cb93a386Sopenharmony_ci 482cb93a386Sopenharmony_ci SkOpts::RGBA_to_rgbA((uint32_t*) dst, (const uint32_t*)(src + offset), width); 483cb93a386Sopenharmony_ci} 484cb93a386Sopenharmony_ci 485cb93a386Sopenharmony_cistatic void fast_swizzle_rgba_to_bgra_premul( 486cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, 487cb93a386Sopenharmony_ci int offset, const SkPMColor ctable[]) { 488cb93a386Sopenharmony_ci 489cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 490cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 491cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 492cb93a386Sopenharmony_ci 493cb93a386Sopenharmony_ci SkOpts::RGBA_to_bgrA((uint32_t*) dst, (const uint32_t*)(src + offset), width); 494cb93a386Sopenharmony_ci} 495cb93a386Sopenharmony_ci 496cb93a386Sopenharmony_cistatic void swizzle_rgba_to_bgra_unpremul( 497cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 498cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 499cb93a386Sopenharmony_ci 500cb93a386Sopenharmony_ci src += offset; 501cb93a386Sopenharmony_ci uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); 502cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 503cb93a386Sopenharmony_ci unsigned alpha = src[3]; 504cb93a386Sopenharmony_ci dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]); 505cb93a386Sopenharmony_ci src += deltaSrc; 506cb93a386Sopenharmony_ci } 507cb93a386Sopenharmony_ci} 508cb93a386Sopenharmony_ci 509cb93a386Sopenharmony_cistatic void fast_swizzle_rgba_to_bgra_unpremul( 510cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 511cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 512cb93a386Sopenharmony_ci 513cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 514cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 515cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 516cb93a386Sopenharmony_ci 517cb93a386Sopenharmony_ci SkOpts::RGBA_to_BGRA((uint32_t*) dst, (const uint32_t*)(src + offset), width); 518cb93a386Sopenharmony_ci} 519cb93a386Sopenharmony_ci 520cb93a386Sopenharmony_ci// 16-bits per component kRGB and kRGBA 521cb93a386Sopenharmony_ci 522cb93a386Sopenharmony_cistatic void swizzle_rgb16_to_rgba( 523cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 524cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 525cb93a386Sopenharmony_ci auto strip16to8 = [](const uint8_t* ptr) { 526cb93a386Sopenharmony_ci return 0xFF000000 | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0]; 527cb93a386Sopenharmony_ci }; 528cb93a386Sopenharmony_ci 529cb93a386Sopenharmony_ci src += offset; 530cb93a386Sopenharmony_ci uint32_t* dst32 = (uint32_t*) dst; 531cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 532cb93a386Sopenharmony_ci dst32[x] = strip16to8(src); 533cb93a386Sopenharmony_ci src += deltaSrc; 534cb93a386Sopenharmony_ci } 535cb93a386Sopenharmony_ci} 536cb93a386Sopenharmony_ci 537cb93a386Sopenharmony_cistatic void swizzle_rgb16_to_bgra( 538cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 539cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 540cb93a386Sopenharmony_ci auto strip16to8 = [](const uint8_t* ptr) { 541cb93a386Sopenharmony_ci return 0xFF000000 | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4]; 542cb93a386Sopenharmony_ci }; 543cb93a386Sopenharmony_ci 544cb93a386Sopenharmony_ci src += offset; 545cb93a386Sopenharmony_ci uint32_t* dst32 = (uint32_t*) dst; 546cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 547cb93a386Sopenharmony_ci dst32[x] = strip16to8(src); 548cb93a386Sopenharmony_ci src += deltaSrc; 549cb93a386Sopenharmony_ci } 550cb93a386Sopenharmony_ci} 551cb93a386Sopenharmony_ci 552cb93a386Sopenharmony_cistatic void swizzle_rgb16_to_565( 553cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 554cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 555cb93a386Sopenharmony_ci auto strip16to565 = [](const uint8_t* ptr) { 556cb93a386Sopenharmony_ci return SkPack888ToRGB16(ptr[0], ptr[2], ptr[4]); 557cb93a386Sopenharmony_ci }; 558cb93a386Sopenharmony_ci 559cb93a386Sopenharmony_ci src += offset; 560cb93a386Sopenharmony_ci uint16_t* dst16 = (uint16_t*) dst; 561cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 562cb93a386Sopenharmony_ci dst16[x] = strip16to565(src); 563cb93a386Sopenharmony_ci src += deltaSrc; 564cb93a386Sopenharmony_ci } 565cb93a386Sopenharmony_ci} 566cb93a386Sopenharmony_ci 567cb93a386Sopenharmony_cistatic void swizzle_rgba16_to_rgba_unpremul( 568cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 569cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 570cb93a386Sopenharmony_ci auto strip16to8 = [](const uint8_t* ptr) { 571cb93a386Sopenharmony_ci return (ptr[6] << 24) | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0]; 572cb93a386Sopenharmony_ci }; 573cb93a386Sopenharmony_ci 574cb93a386Sopenharmony_ci src += offset; 575cb93a386Sopenharmony_ci uint32_t* dst32 = (uint32_t*) dst; 576cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 577cb93a386Sopenharmony_ci dst32[x] = strip16to8(src); 578cb93a386Sopenharmony_ci src += deltaSrc; 579cb93a386Sopenharmony_ci } 580cb93a386Sopenharmony_ci} 581cb93a386Sopenharmony_ci 582cb93a386Sopenharmony_cistatic void swizzle_rgba16_to_rgba_premul( 583cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 584cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 585cb93a386Sopenharmony_ci auto stripAndPremul16to8 = [](const uint8_t* ptr) { 586cb93a386Sopenharmony_ci return premultiply_argb_as_rgba(ptr[6], ptr[0], ptr[2], ptr[4]); 587cb93a386Sopenharmony_ci }; 588cb93a386Sopenharmony_ci 589cb93a386Sopenharmony_ci src += offset; 590cb93a386Sopenharmony_ci uint32_t* dst32 = (uint32_t*) dst; 591cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 592cb93a386Sopenharmony_ci dst32[x] = stripAndPremul16to8(src); 593cb93a386Sopenharmony_ci src += deltaSrc; 594cb93a386Sopenharmony_ci } 595cb93a386Sopenharmony_ci} 596cb93a386Sopenharmony_ci 597cb93a386Sopenharmony_cistatic void swizzle_rgba16_to_bgra_unpremul( 598cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 599cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 600cb93a386Sopenharmony_ci auto strip16to8 = [](const uint8_t* ptr) { 601cb93a386Sopenharmony_ci return (ptr[6] << 24) | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4]; 602cb93a386Sopenharmony_ci }; 603cb93a386Sopenharmony_ci 604cb93a386Sopenharmony_ci src += offset; 605cb93a386Sopenharmony_ci uint32_t* dst32 = (uint32_t*) dst; 606cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 607cb93a386Sopenharmony_ci dst32[x] = strip16to8(src); 608cb93a386Sopenharmony_ci src += deltaSrc; 609cb93a386Sopenharmony_ci } 610cb93a386Sopenharmony_ci} 611cb93a386Sopenharmony_ci 612cb93a386Sopenharmony_cistatic void swizzle_rgba16_to_bgra_premul( 613cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 614cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 615cb93a386Sopenharmony_ci auto stripAndPremul16to8 = [](const uint8_t* ptr) { 616cb93a386Sopenharmony_ci return premultiply_argb_as_bgra(ptr[6], ptr[0], ptr[2], ptr[4]); 617cb93a386Sopenharmony_ci }; 618cb93a386Sopenharmony_ci 619cb93a386Sopenharmony_ci src += offset; 620cb93a386Sopenharmony_ci uint32_t* dst32 = (uint32_t*) dst; 621cb93a386Sopenharmony_ci for (int x = 0; x < width; x++) { 622cb93a386Sopenharmony_ci dst32[x] = stripAndPremul16to8(src); 623cb93a386Sopenharmony_ci src += deltaSrc; 624cb93a386Sopenharmony_ci } 625cb93a386Sopenharmony_ci} 626cb93a386Sopenharmony_ci 627cb93a386Sopenharmony_ci// kCMYK 628cb93a386Sopenharmony_ci// 629cb93a386Sopenharmony_ci// CMYK is stored as four bytes per pixel. 630cb93a386Sopenharmony_ci// 631cb93a386Sopenharmony_ci// We will implement a crude conversion from CMYK -> RGB using formulas 632cb93a386Sopenharmony_ci// from easyrgb.com. 633cb93a386Sopenharmony_ci// 634cb93a386Sopenharmony_ci// CMYK -> CMY 635cb93a386Sopenharmony_ci// C = C * (1 - K) + K 636cb93a386Sopenharmony_ci// M = M * (1 - K) + K 637cb93a386Sopenharmony_ci// Y = Y * (1 - K) + K 638cb93a386Sopenharmony_ci// 639cb93a386Sopenharmony_ci// libjpeg actually gives us inverted CMYK, so we must subtract the 640cb93a386Sopenharmony_ci// original terms from 1. 641cb93a386Sopenharmony_ci// CMYK -> CMY 642cb93a386Sopenharmony_ci// C = (1 - C) * (1 - (1 - K)) + (1 - K) 643cb93a386Sopenharmony_ci// M = (1 - M) * (1 - (1 - K)) + (1 - K) 644cb93a386Sopenharmony_ci// Y = (1 - Y) * (1 - (1 - K)) + (1 - K) 645cb93a386Sopenharmony_ci// 646cb93a386Sopenharmony_ci// Simplifying the above expression. 647cb93a386Sopenharmony_ci// CMYK -> CMY 648cb93a386Sopenharmony_ci// C = 1 - CK 649cb93a386Sopenharmony_ci// M = 1 - MK 650cb93a386Sopenharmony_ci// Y = 1 - YK 651cb93a386Sopenharmony_ci// 652cb93a386Sopenharmony_ci// CMY -> RGB 653cb93a386Sopenharmony_ci// R = (1 - C) * 255 654cb93a386Sopenharmony_ci// G = (1 - M) * 255 655cb93a386Sopenharmony_ci// B = (1 - Y) * 255 656cb93a386Sopenharmony_ci// 657cb93a386Sopenharmony_ci// Therefore the full conversion is below. This can be verified at 658cb93a386Sopenharmony_ci// www.rapidtables.com (assuming inverted CMYK). 659cb93a386Sopenharmony_ci// CMYK -> RGB 660cb93a386Sopenharmony_ci// R = C * K * 255 661cb93a386Sopenharmony_ci// G = M * K * 255 662cb93a386Sopenharmony_ci// B = Y * K * 255 663cb93a386Sopenharmony_ci// 664cb93a386Sopenharmony_ci// As a final note, we have treated the CMYK values as if they were on 665cb93a386Sopenharmony_ci// a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255. 666cb93a386Sopenharmony_ci// We must divide each CMYK component by 255 to obtain the true conversion 667cb93a386Sopenharmony_ci// we should perform. 668cb93a386Sopenharmony_ci// CMYK -> RGB 669cb93a386Sopenharmony_ci// R = C * K / 255 670cb93a386Sopenharmony_ci// G = M * K / 255 671cb93a386Sopenharmony_ci// B = Y * K / 255 672cb93a386Sopenharmony_cistatic void swizzle_cmyk_to_rgba( 673cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 674cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 675cb93a386Sopenharmony_ci 676cb93a386Sopenharmony_ci src += offset; 677cb93a386Sopenharmony_ci SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 678cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 679cb93a386Sopenharmony_ci const uint8_t r = SkMulDiv255Round(src[0], src[3]); 680cb93a386Sopenharmony_ci const uint8_t g = SkMulDiv255Round(src[1], src[3]); 681cb93a386Sopenharmony_ci const uint8_t b = SkMulDiv255Round(src[2], src[3]); 682cb93a386Sopenharmony_ci 683cb93a386Sopenharmony_ci dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b); 684cb93a386Sopenharmony_ci src += deltaSrc; 685cb93a386Sopenharmony_ci } 686cb93a386Sopenharmony_ci} 687cb93a386Sopenharmony_ci 688cb93a386Sopenharmony_cistatic void swizzle_cmyk_to_bgra( 689cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 690cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 691cb93a386Sopenharmony_ci 692cb93a386Sopenharmony_ci src += offset; 693cb93a386Sopenharmony_ci SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 694cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 695cb93a386Sopenharmony_ci const uint8_t r = SkMulDiv255Round(src[0], src[3]); 696cb93a386Sopenharmony_ci const uint8_t g = SkMulDiv255Round(src[1], src[3]); 697cb93a386Sopenharmony_ci const uint8_t b = SkMulDiv255Round(src[2], src[3]); 698cb93a386Sopenharmony_ci 699cb93a386Sopenharmony_ci dst[x] = SkPackARGB_as_BGRA(0xFF, r, g, b); 700cb93a386Sopenharmony_ci src += deltaSrc; 701cb93a386Sopenharmony_ci } 702cb93a386Sopenharmony_ci} 703cb93a386Sopenharmony_ci 704cb93a386Sopenharmony_cistatic void fast_swizzle_cmyk_to_rgba( 705cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 706cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 707cb93a386Sopenharmony_ci 708cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 709cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 710cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 711cb93a386Sopenharmony_ci 712cb93a386Sopenharmony_ci SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, (const uint32_t*)(src + offset), width); 713cb93a386Sopenharmony_ci} 714cb93a386Sopenharmony_ci 715cb93a386Sopenharmony_cistatic void fast_swizzle_cmyk_to_bgra( 716cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 717cb93a386Sopenharmony_ci const SkPMColor ctable[]) { 718cb93a386Sopenharmony_ci 719cb93a386Sopenharmony_ci // This function must not be called if we are sampling. If we are not 720cb93a386Sopenharmony_ci // sampling, deltaSrc should equal bpp. 721cb93a386Sopenharmony_ci SkASSERT(deltaSrc == bpp); 722cb93a386Sopenharmony_ci 723cb93a386Sopenharmony_ci SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, (const uint32_t*)(src + offset), width); 724cb93a386Sopenharmony_ci} 725cb93a386Sopenharmony_ci 726cb93a386Sopenharmony_cistatic void swizzle_cmyk_to_565( 727cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 728cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 729cb93a386Sopenharmony_ci 730cb93a386Sopenharmony_ci src += offset; 731cb93a386Sopenharmony_ci uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 732cb93a386Sopenharmony_ci for (int x = 0; x < dstWidth; x++) { 733cb93a386Sopenharmony_ci const uint8_t r = SkMulDiv255Round(src[0], src[3]); 734cb93a386Sopenharmony_ci const uint8_t g = SkMulDiv255Round(src[1], src[3]); 735cb93a386Sopenharmony_ci const uint8_t b = SkMulDiv255Round(src[2], src[3]); 736cb93a386Sopenharmony_ci 737cb93a386Sopenharmony_ci dst[x] = SkPack888ToRGB16(r, g, b); 738cb93a386Sopenharmony_ci src += deltaSrc; 739cb93a386Sopenharmony_ci } 740cb93a386Sopenharmony_ci} 741cb93a386Sopenharmony_ci 742cb93a386Sopenharmony_citemplate <SkSwizzler::RowProc proc> 743cb93a386Sopenharmony_civoid SkSwizzler::SkipLeadingGrayAlphaZerosThen( 744cb93a386Sopenharmony_ci void* dst, const uint8_t* src, int width, 745cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 746cb93a386Sopenharmony_ci SkASSERT(!ctable); 747cb93a386Sopenharmony_ci 748cb93a386Sopenharmony_ci const uint16_t* src16 = (const uint16_t*) (src + offset); 749cb93a386Sopenharmony_ci uint32_t* dst32 = (uint32_t*) dst; 750cb93a386Sopenharmony_ci 751cb93a386Sopenharmony_ci // This may miss opportunities to skip when the output is premultiplied, 752cb93a386Sopenharmony_ci // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication. 753cb93a386Sopenharmony_ci while (width > 0 && *src16 == 0x0000) { 754cb93a386Sopenharmony_ci width--; 755cb93a386Sopenharmony_ci dst32++; 756cb93a386Sopenharmony_ci src16 += deltaSrc / 2; 757cb93a386Sopenharmony_ci } 758cb93a386Sopenharmony_ci proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable); 759cb93a386Sopenharmony_ci} 760cb93a386Sopenharmony_ci 761cb93a386Sopenharmony_citemplate <SkSwizzler::RowProc proc> 762cb93a386Sopenharmony_civoid SkSwizzler::SkipLeading8888ZerosThen( 763cb93a386Sopenharmony_ci void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 764cb93a386Sopenharmony_ci int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 765cb93a386Sopenharmony_ci SkASSERT(!ctable); 766cb93a386Sopenharmony_ci 767cb93a386Sopenharmony_ci auto src32 = (const uint32_t*)(src+offset); 768cb93a386Sopenharmony_ci auto dst32 = (uint32_t*)dstRow; 769cb93a386Sopenharmony_ci 770cb93a386Sopenharmony_ci // This may miss opportunities to skip when the output is premultiplied, 771cb93a386Sopenharmony_ci // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication. 772cb93a386Sopenharmony_ci while (dstWidth > 0 && *src32 == 0x00000000) { 773cb93a386Sopenharmony_ci dstWidth--; 774cb93a386Sopenharmony_ci dst32++; 775cb93a386Sopenharmony_ci src32 += deltaSrc/4; 776cb93a386Sopenharmony_ci } 777cb93a386Sopenharmony_ci proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable); 778cb93a386Sopenharmony_ci} 779cb93a386Sopenharmony_ci 780cb93a386Sopenharmony_cistd::unique_ptr<SkSwizzler> SkSwizzler::MakeSimple(int srcBPP, const SkImageInfo& dstInfo, 781cb93a386Sopenharmony_ci const SkCodec::Options& options) { 782cb93a386Sopenharmony_ci RowProc proc = nullptr; 783cb93a386Sopenharmony_ci switch (srcBPP) { 784cb93a386Sopenharmony_ci case 1: // kGray_8_SkColorType 785cb93a386Sopenharmony_ci proc = &sample1; 786cb93a386Sopenharmony_ci break; 787cb93a386Sopenharmony_ci case 2: // kRGB_565_SkColorType 788cb93a386Sopenharmony_ci proc = &sample2; 789cb93a386Sopenharmony_ci break; 790cb93a386Sopenharmony_ci case 4: // kRGBA_8888_SkColorType 791cb93a386Sopenharmony_ci // kBGRA_8888_SkColorType 792cb93a386Sopenharmony_ci proc = &sample4; 793cb93a386Sopenharmony_ci break; 794cb93a386Sopenharmony_ci case 6: // 16 bit PNG no alpha 795cb93a386Sopenharmony_ci proc = &sample6; 796cb93a386Sopenharmony_ci break; 797cb93a386Sopenharmony_ci case 8: // 16 bit PNG with alpha 798cb93a386Sopenharmony_ci proc = &sample8; 799cb93a386Sopenharmony_ci break; 800cb93a386Sopenharmony_ci default: 801cb93a386Sopenharmony_ci return nullptr; 802cb93a386Sopenharmony_ci } 803cb93a386Sopenharmony_ci 804cb93a386Sopenharmony_ci return Make(dstInfo, ©, proc, nullptr /*ctable*/, srcBPP, 805cb93a386Sopenharmony_ci dstInfo.bytesPerPixel(), options, nullptr /*frame*/); 806cb93a386Sopenharmony_ci} 807cb93a386Sopenharmony_ci 808cb93a386Sopenharmony_cistd::unique_ptr<SkSwizzler> SkSwizzler::Make(const SkEncodedInfo& encodedInfo, 809cb93a386Sopenharmony_ci const SkPMColor* ctable, 810cb93a386Sopenharmony_ci const SkImageInfo& dstInfo, 811cb93a386Sopenharmony_ci const SkCodec::Options& options, 812cb93a386Sopenharmony_ci const SkIRect* frame) { 813cb93a386Sopenharmony_ci if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) { 814cb93a386Sopenharmony_ci return nullptr; 815cb93a386Sopenharmony_ci } 816cb93a386Sopenharmony_ci 817cb93a386Sopenharmony_ci RowProc fastProc = nullptr; 818cb93a386Sopenharmony_ci RowProc proc = nullptr; 819cb93a386Sopenharmony_ci SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized; 820cb93a386Sopenharmony_ci const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) && 821cb93a386Sopenharmony_ci (kPremul_SkAlphaType == dstInfo.alphaType()); 822cb93a386Sopenharmony_ci 823cb93a386Sopenharmony_ci switch (encodedInfo.color()) { 824cb93a386Sopenharmony_ci case SkEncodedInfo::kGray_Color: 825cb93a386Sopenharmony_ci switch (encodedInfo.bitsPerComponent()) { 826cb93a386Sopenharmony_ci case 1: 827cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 828cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 829cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 830cb93a386Sopenharmony_ci proc = &swizzle_bit_to_n32; 831cb93a386Sopenharmony_ci break; 832cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 833cb93a386Sopenharmony_ci proc = &swizzle_bit_to_565; 834cb93a386Sopenharmony_ci break; 835cb93a386Sopenharmony_ci case kGray_8_SkColorType: 836cb93a386Sopenharmony_ci proc = &swizzle_bit_to_grayscale; 837cb93a386Sopenharmony_ci break; 838cb93a386Sopenharmony_ci case kRGBA_F16_SkColorType: 839cb93a386Sopenharmony_ci proc = &swizzle_bit_to_f16; 840cb93a386Sopenharmony_ci break; 841cb93a386Sopenharmony_ci default: 842cb93a386Sopenharmony_ci return nullptr; 843cb93a386Sopenharmony_ci } 844cb93a386Sopenharmony_ci break; 845cb93a386Sopenharmony_ci case 8: 846cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 847cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 848cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 849cb93a386Sopenharmony_ci proc = &swizzle_gray_to_n32; 850cb93a386Sopenharmony_ci fastProc = &fast_swizzle_gray_to_n32; 851cb93a386Sopenharmony_ci break; 852cb93a386Sopenharmony_ci case kGray_8_SkColorType: 853cb93a386Sopenharmony_ci proc = &sample1; 854cb93a386Sopenharmony_ci fastProc = © 855cb93a386Sopenharmony_ci break; 856cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 857cb93a386Sopenharmony_ci proc = &swizzle_gray_to_565; 858cb93a386Sopenharmony_ci break; 859cb93a386Sopenharmony_ci default: 860cb93a386Sopenharmony_ci return nullptr; 861cb93a386Sopenharmony_ci } 862cb93a386Sopenharmony_ci break; 863cb93a386Sopenharmony_ci default: 864cb93a386Sopenharmony_ci return nullptr; 865cb93a386Sopenharmony_ci } 866cb93a386Sopenharmony_ci break; 867cb93a386Sopenharmony_ci case SkEncodedInfo::kXAlpha_Color: 868cb93a386Sopenharmony_ci case SkEncodedInfo::kGrayAlpha_Color: 869cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 870cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 871cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 872cb93a386Sopenharmony_ci if (premultiply) { 873cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 874cb93a386Sopenharmony_ci proc = &SkipLeadingGrayAlphaZerosThen 875cb93a386Sopenharmony_ci <swizzle_grayalpha_to_n32_premul>; 876cb93a386Sopenharmony_ci fastProc = &SkipLeadingGrayAlphaZerosThen 877cb93a386Sopenharmony_ci <fast_swizzle_grayalpha_to_n32_premul>; 878cb93a386Sopenharmony_ci } else { 879cb93a386Sopenharmony_ci proc = &swizzle_grayalpha_to_n32_premul; 880cb93a386Sopenharmony_ci fastProc = &fast_swizzle_grayalpha_to_n32_premul; 881cb93a386Sopenharmony_ci } 882cb93a386Sopenharmony_ci } else { 883cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 884cb93a386Sopenharmony_ci proc = &SkipLeadingGrayAlphaZerosThen 885cb93a386Sopenharmony_ci <swizzle_grayalpha_to_n32_unpremul>; 886cb93a386Sopenharmony_ci fastProc = &SkipLeadingGrayAlphaZerosThen 887cb93a386Sopenharmony_ci <fast_swizzle_grayalpha_to_n32_unpremul>; 888cb93a386Sopenharmony_ci } else { 889cb93a386Sopenharmony_ci proc = &swizzle_grayalpha_to_n32_unpremul; 890cb93a386Sopenharmony_ci fastProc = &fast_swizzle_grayalpha_to_n32_unpremul; 891cb93a386Sopenharmony_ci } 892cb93a386Sopenharmony_ci } 893cb93a386Sopenharmony_ci break; 894cb93a386Sopenharmony_ci case kAlpha_8_SkColorType: 895cb93a386Sopenharmony_ci proc = &swizzle_grayalpha_to_a8; 896cb93a386Sopenharmony_ci break; 897cb93a386Sopenharmony_ci default: 898cb93a386Sopenharmony_ci return nullptr; 899cb93a386Sopenharmony_ci } 900cb93a386Sopenharmony_ci break; 901cb93a386Sopenharmony_ci case SkEncodedInfo::kPalette_Color: 902cb93a386Sopenharmony_ci // We assume that the color table is premultiplied and swizzled 903cb93a386Sopenharmony_ci // as desired. 904cb93a386Sopenharmony_ci switch (encodedInfo.bitsPerComponent()) { 905cb93a386Sopenharmony_ci case 1: 906cb93a386Sopenharmony_ci case 2: 907cb93a386Sopenharmony_ci case 4: 908cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 909cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 910cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 911cb93a386Sopenharmony_ci proc = &swizzle_small_index_to_n32; 912cb93a386Sopenharmony_ci break; 913cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 914cb93a386Sopenharmony_ci proc = &swizzle_small_index_to_565; 915cb93a386Sopenharmony_ci break; 916cb93a386Sopenharmony_ci default: 917cb93a386Sopenharmony_ci return nullptr; 918cb93a386Sopenharmony_ci } 919cb93a386Sopenharmony_ci break; 920cb93a386Sopenharmony_ci case 8: 921cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 922cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 923cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 924cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 925cb93a386Sopenharmony_ci proc = &swizzle_index_to_n32_skipZ; 926cb93a386Sopenharmony_ci } else { 927cb93a386Sopenharmony_ci proc = &swizzle_index_to_n32; 928cb93a386Sopenharmony_ci } 929cb93a386Sopenharmony_ci break; 930cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 931cb93a386Sopenharmony_ci proc = &swizzle_index_to_565; 932cb93a386Sopenharmony_ci break; 933cb93a386Sopenharmony_ci default: 934cb93a386Sopenharmony_ci return nullptr; 935cb93a386Sopenharmony_ci } 936cb93a386Sopenharmony_ci break; 937cb93a386Sopenharmony_ci default: 938cb93a386Sopenharmony_ci return nullptr; 939cb93a386Sopenharmony_ci } 940cb93a386Sopenharmony_ci break; 941cb93a386Sopenharmony_ci case SkEncodedInfo::k565_Color: 942cb93a386Sopenharmony_ci // Treat 565 exactly like RGB (since it's still encoded as 8 bits per component). 943cb93a386Sopenharmony_ci // We just mark as 565 when we have a hint that there are only 5/6/5 "significant" 944cb93a386Sopenharmony_ci // bits in each channel. 945cb93a386Sopenharmony_ci case SkEncodedInfo::kRGB_Color: 946cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 947cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 948cb93a386Sopenharmony_ci if (16 == encodedInfo.bitsPerComponent()) { 949cb93a386Sopenharmony_ci proc = &swizzle_rgb16_to_rgba; 950cb93a386Sopenharmony_ci break; 951cb93a386Sopenharmony_ci } 952cb93a386Sopenharmony_ci 953cb93a386Sopenharmony_ci SkASSERT(8 == encodedInfo.bitsPerComponent()); 954cb93a386Sopenharmony_ci proc = &swizzle_rgb_to_rgba; 955cb93a386Sopenharmony_ci fastProc = &fast_swizzle_rgb_to_rgba; 956cb93a386Sopenharmony_ci break; 957cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 958cb93a386Sopenharmony_ci if (16 == encodedInfo.bitsPerComponent()) { 959cb93a386Sopenharmony_ci proc = &swizzle_rgb16_to_bgra; 960cb93a386Sopenharmony_ci break; 961cb93a386Sopenharmony_ci } 962cb93a386Sopenharmony_ci 963cb93a386Sopenharmony_ci SkASSERT(8 == encodedInfo.bitsPerComponent()); 964cb93a386Sopenharmony_ci proc = &swizzle_rgb_to_bgra; 965cb93a386Sopenharmony_ci fastProc = &fast_swizzle_rgb_to_bgra; 966cb93a386Sopenharmony_ci break; 967cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 968cb93a386Sopenharmony_ci if (16 == encodedInfo.bitsPerComponent()) { 969cb93a386Sopenharmony_ci proc = &swizzle_rgb16_to_565; 970cb93a386Sopenharmony_ci break; 971cb93a386Sopenharmony_ci } 972cb93a386Sopenharmony_ci 973cb93a386Sopenharmony_ci proc = &swizzle_rgb_to_565; 974cb93a386Sopenharmony_ci break; 975cb93a386Sopenharmony_ci default: 976cb93a386Sopenharmony_ci return nullptr; 977cb93a386Sopenharmony_ci } 978cb93a386Sopenharmony_ci break; 979cb93a386Sopenharmony_ci case SkEncodedInfo::kRGBA_Color: 980cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 981cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 982cb93a386Sopenharmony_ci if (16 == encodedInfo.bitsPerComponent()) { 983cb93a386Sopenharmony_ci proc = premultiply ? &swizzle_rgba16_to_rgba_premul : 984cb93a386Sopenharmony_ci &swizzle_rgba16_to_rgba_unpremul; 985cb93a386Sopenharmony_ci break; 986cb93a386Sopenharmony_ci } 987cb93a386Sopenharmony_ci 988cb93a386Sopenharmony_ci SkASSERT(8 == encodedInfo.bitsPerComponent()); 989cb93a386Sopenharmony_ci if (premultiply) { 990cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 991cb93a386Sopenharmony_ci proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>; 992cb93a386Sopenharmony_ci fastProc = &SkipLeading8888ZerosThen 993cb93a386Sopenharmony_ci <fast_swizzle_rgba_to_rgba_premul>; 994cb93a386Sopenharmony_ci } else { 995cb93a386Sopenharmony_ci proc = &swizzle_rgba_to_rgba_premul; 996cb93a386Sopenharmony_ci fastProc = &fast_swizzle_rgba_to_rgba_premul; 997cb93a386Sopenharmony_ci } 998cb93a386Sopenharmony_ci } else { 999cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1000cb93a386Sopenharmony_ci proc = &SkipLeading8888ZerosThen<sample4>; 1001cb93a386Sopenharmony_ci fastProc = &SkipLeading8888ZerosThen<copy>; 1002cb93a386Sopenharmony_ci } else { 1003cb93a386Sopenharmony_ci proc = &sample4; 1004cb93a386Sopenharmony_ci fastProc = © 1005cb93a386Sopenharmony_ci } 1006cb93a386Sopenharmony_ci } 1007cb93a386Sopenharmony_ci break; 1008cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 1009cb93a386Sopenharmony_ci if (16 == encodedInfo.bitsPerComponent()) { 1010cb93a386Sopenharmony_ci proc = premultiply ? &swizzle_rgba16_to_bgra_premul : 1011cb93a386Sopenharmony_ci &swizzle_rgba16_to_bgra_unpremul; 1012cb93a386Sopenharmony_ci break; 1013cb93a386Sopenharmony_ci } 1014cb93a386Sopenharmony_ci 1015cb93a386Sopenharmony_ci SkASSERT(8 == encodedInfo.bitsPerComponent()); 1016cb93a386Sopenharmony_ci if (premultiply) { 1017cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1018cb93a386Sopenharmony_ci proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>; 1019cb93a386Sopenharmony_ci fastProc = &SkipLeading8888ZerosThen 1020cb93a386Sopenharmony_ci <fast_swizzle_rgba_to_bgra_premul>; 1021cb93a386Sopenharmony_ci } else { 1022cb93a386Sopenharmony_ci proc = &swizzle_rgba_to_bgra_premul; 1023cb93a386Sopenharmony_ci fastProc = &fast_swizzle_rgba_to_bgra_premul; 1024cb93a386Sopenharmony_ci } 1025cb93a386Sopenharmony_ci } else { 1026cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1027cb93a386Sopenharmony_ci proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>; 1028cb93a386Sopenharmony_ci fastProc = &SkipLeading8888ZerosThen 1029cb93a386Sopenharmony_ci <fast_swizzle_rgba_to_bgra_unpremul>; 1030cb93a386Sopenharmony_ci } else { 1031cb93a386Sopenharmony_ci proc = &swizzle_rgba_to_bgra_unpremul; 1032cb93a386Sopenharmony_ci fastProc = &fast_swizzle_rgba_to_bgra_unpremul; 1033cb93a386Sopenharmony_ci } 1034cb93a386Sopenharmony_ci } 1035cb93a386Sopenharmony_ci break; 1036cb93a386Sopenharmony_ci default: 1037cb93a386Sopenharmony_ci return nullptr; 1038cb93a386Sopenharmony_ci } 1039cb93a386Sopenharmony_ci break; 1040cb93a386Sopenharmony_ci case SkEncodedInfo::kBGR_Color: 1041cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 1042cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 1043cb93a386Sopenharmony_ci proc = &swizzle_rgb_to_rgba; 1044cb93a386Sopenharmony_ci fastProc = &fast_swizzle_rgb_to_rgba; 1045cb93a386Sopenharmony_ci break; 1046cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 1047cb93a386Sopenharmony_ci proc = &swizzle_rgb_to_bgra; 1048cb93a386Sopenharmony_ci fastProc = &fast_swizzle_rgb_to_bgra; 1049cb93a386Sopenharmony_ci break; 1050cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 1051cb93a386Sopenharmony_ci proc = &swizzle_bgr_to_565; 1052cb93a386Sopenharmony_ci break; 1053cb93a386Sopenharmony_ci default: 1054cb93a386Sopenharmony_ci return nullptr; 1055cb93a386Sopenharmony_ci } 1056cb93a386Sopenharmony_ci break; 1057cb93a386Sopenharmony_ci case SkEncodedInfo::kBGRX_Color: 1058cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 1059cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 1060cb93a386Sopenharmony_ci proc = &swizzle_rgb_to_rgba; 1061cb93a386Sopenharmony_ci break; 1062cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 1063cb93a386Sopenharmony_ci proc = &swizzle_rgb_to_bgra; 1064cb93a386Sopenharmony_ci break; 1065cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 1066cb93a386Sopenharmony_ci proc = &swizzle_bgr_to_565; 1067cb93a386Sopenharmony_ci break; 1068cb93a386Sopenharmony_ci default: 1069cb93a386Sopenharmony_ci return nullptr; 1070cb93a386Sopenharmony_ci } 1071cb93a386Sopenharmony_ci break; 1072cb93a386Sopenharmony_ci case SkEncodedInfo::kBGRA_Color: 1073cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 1074cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 1075cb93a386Sopenharmony_ci if (premultiply) { 1076cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1077cb93a386Sopenharmony_ci proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>; 1078cb93a386Sopenharmony_ci fastProc = &SkipLeading8888ZerosThen 1079cb93a386Sopenharmony_ci <fast_swizzle_rgba_to_rgba_premul>; 1080cb93a386Sopenharmony_ci } else { 1081cb93a386Sopenharmony_ci proc = &swizzle_rgba_to_rgba_premul; 1082cb93a386Sopenharmony_ci fastProc = &fast_swizzle_rgba_to_rgba_premul; 1083cb93a386Sopenharmony_ci } 1084cb93a386Sopenharmony_ci } else { 1085cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1086cb93a386Sopenharmony_ci proc = &SkipLeading8888ZerosThen<sample4>; 1087cb93a386Sopenharmony_ci fastProc = &SkipLeading8888ZerosThen<copy>; 1088cb93a386Sopenharmony_ci } else { 1089cb93a386Sopenharmony_ci proc = &sample4; 1090cb93a386Sopenharmony_ci fastProc = © 1091cb93a386Sopenharmony_ci } 1092cb93a386Sopenharmony_ci } 1093cb93a386Sopenharmony_ci break; 1094cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 1095cb93a386Sopenharmony_ci if (premultiply) { 1096cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1097cb93a386Sopenharmony_ci proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>; 1098cb93a386Sopenharmony_ci fastProc = &SkipLeading8888ZerosThen 1099cb93a386Sopenharmony_ci <fast_swizzle_rgba_to_bgra_premul>; 1100cb93a386Sopenharmony_ci } else { 1101cb93a386Sopenharmony_ci proc = &swizzle_rgba_to_bgra_premul; 1102cb93a386Sopenharmony_ci fastProc = &fast_swizzle_rgba_to_bgra_premul; 1103cb93a386Sopenharmony_ci } 1104cb93a386Sopenharmony_ci } else { 1105cb93a386Sopenharmony_ci if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1106cb93a386Sopenharmony_ci proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>; 1107cb93a386Sopenharmony_ci fastProc = &SkipLeading8888ZerosThen 1108cb93a386Sopenharmony_ci <fast_swizzle_rgba_to_bgra_unpremul>; 1109cb93a386Sopenharmony_ci } else { 1110cb93a386Sopenharmony_ci proc = &swizzle_rgba_to_bgra_unpremul; 1111cb93a386Sopenharmony_ci fastProc = &fast_swizzle_rgba_to_bgra_unpremul; 1112cb93a386Sopenharmony_ci } 1113cb93a386Sopenharmony_ci } 1114cb93a386Sopenharmony_ci break; 1115cb93a386Sopenharmony_ci default: 1116cb93a386Sopenharmony_ci return nullptr; 1117cb93a386Sopenharmony_ci } 1118cb93a386Sopenharmony_ci break; 1119cb93a386Sopenharmony_ci case SkEncodedInfo::kInvertedCMYK_Color: 1120cb93a386Sopenharmony_ci switch (dstInfo.colorType()) { 1121cb93a386Sopenharmony_ci case kRGBA_8888_SkColorType: 1122cb93a386Sopenharmony_ci proc = &swizzle_cmyk_to_rgba; 1123cb93a386Sopenharmony_ci fastProc = &fast_swizzle_cmyk_to_rgba; 1124cb93a386Sopenharmony_ci break; 1125cb93a386Sopenharmony_ci case kBGRA_8888_SkColorType: 1126cb93a386Sopenharmony_ci proc = &swizzle_cmyk_to_bgra; 1127cb93a386Sopenharmony_ci fastProc = &fast_swizzle_cmyk_to_bgra; 1128cb93a386Sopenharmony_ci break; 1129cb93a386Sopenharmony_ci case kRGB_565_SkColorType: 1130cb93a386Sopenharmony_ci proc = &swizzle_cmyk_to_565; 1131cb93a386Sopenharmony_ci break; 1132cb93a386Sopenharmony_ci default: 1133cb93a386Sopenharmony_ci return nullptr; 1134cb93a386Sopenharmony_ci } 1135cb93a386Sopenharmony_ci break; 1136cb93a386Sopenharmony_ci default: 1137cb93a386Sopenharmony_ci return nullptr; 1138cb93a386Sopenharmony_ci } 1139cb93a386Sopenharmony_ci 1140cb93a386Sopenharmony_ci // Store bpp in bytes if it is an even multiple, otherwise use bits 1141cb93a386Sopenharmony_ci uint8_t bitsPerPixel = encodedInfo.bitsPerPixel(); 1142cb93a386Sopenharmony_ci int srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel; 1143cb93a386Sopenharmony_ci int dstBPP = dstInfo.bytesPerPixel(); 1144cb93a386Sopenharmony_ci return Make(dstInfo, fastProc, proc, ctable, srcBPP, dstBPP, options, frame); 1145cb93a386Sopenharmony_ci} 1146cb93a386Sopenharmony_ci 1147cb93a386Sopenharmony_cistd::unique_ptr<SkSwizzler> SkSwizzler::Make(const SkImageInfo& dstInfo, 1148cb93a386Sopenharmony_ci RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcBPP, 1149cb93a386Sopenharmony_ci int dstBPP, const SkCodec::Options& options, const SkIRect* frame) { 1150cb93a386Sopenharmony_ci int srcOffset = 0; 1151cb93a386Sopenharmony_ci int srcWidth = dstInfo.width(); 1152cb93a386Sopenharmony_ci int dstOffset = 0; 1153cb93a386Sopenharmony_ci int dstWidth = srcWidth; 1154cb93a386Sopenharmony_ci if (options.fSubset) { 1155cb93a386Sopenharmony_ci // We do not currently support subset decodes for image types that may have 1156cb93a386Sopenharmony_ci // frames (gif). 1157cb93a386Sopenharmony_ci SkASSERT(!frame); 1158cb93a386Sopenharmony_ci srcOffset = options.fSubset->left(); 1159cb93a386Sopenharmony_ci srcWidth = options.fSubset->width(); 1160cb93a386Sopenharmony_ci dstWidth = srcWidth; 1161cb93a386Sopenharmony_ci } else if (frame) { 1162cb93a386Sopenharmony_ci dstOffset = frame->left(); 1163cb93a386Sopenharmony_ci srcWidth = frame->width(); 1164cb93a386Sopenharmony_ci } 1165cb93a386Sopenharmony_ci 1166cb93a386Sopenharmony_ci return std::unique_ptr<SkSwizzler>(new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, 1167cb93a386Sopenharmony_ci dstOffset, dstWidth, srcBPP, dstBPP)); 1168cb93a386Sopenharmony_ci} 1169cb93a386Sopenharmony_ci 1170cb93a386Sopenharmony_ciSkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset, 1171cb93a386Sopenharmony_ci int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP) 1172cb93a386Sopenharmony_ci : fFastProc(fastProc) 1173cb93a386Sopenharmony_ci , fSlowProc(proc) 1174cb93a386Sopenharmony_ci , fActualProc(fFastProc ? fFastProc : fSlowProc) 1175cb93a386Sopenharmony_ci , fColorTable(ctable) 1176cb93a386Sopenharmony_ci , fSrcOffset(srcOffset) 1177cb93a386Sopenharmony_ci , fDstOffset(dstOffset) 1178cb93a386Sopenharmony_ci , fSrcOffsetUnits(srcOffset * srcBPP) 1179cb93a386Sopenharmony_ci , fDstOffsetBytes(dstOffset * dstBPP) 1180cb93a386Sopenharmony_ci , fSrcWidth(srcWidth) 1181cb93a386Sopenharmony_ci , fDstWidth(dstWidth) 1182cb93a386Sopenharmony_ci , fSwizzleWidth(srcWidth) 1183cb93a386Sopenharmony_ci , fAllocatedWidth(dstWidth) 1184cb93a386Sopenharmony_ci , fSampleX(1) 1185cb93a386Sopenharmony_ci , fSrcBPP(srcBPP) 1186cb93a386Sopenharmony_ci , fDstBPP(dstBPP) 1187cb93a386Sopenharmony_ci{} 1188cb93a386Sopenharmony_ci 1189cb93a386Sopenharmony_ciint SkSwizzler::onSetSampleX(int sampleX) { 1190cb93a386Sopenharmony_ci SkASSERT(sampleX > 0); 1191cb93a386Sopenharmony_ci 1192cb93a386Sopenharmony_ci fSampleX = sampleX; 1193cb93a386Sopenharmony_ci fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP; 1194cb93a386Sopenharmony_ci fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX); 1195cb93a386Sopenharmony_ci fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX); 1196cb93a386Sopenharmony_ci 1197cb93a386Sopenharmony_ci int frameSampleX = sampleX; 1198cb93a386Sopenharmony_ci if (fSrcWidth < fDstWidth) { 1199cb93a386Sopenharmony_ci // Although SkSampledCodec adjusted sampleX so that it will never be 1200cb93a386Sopenharmony_ci // larger than the width of the image (or subset, if applicable), it 1201cb93a386Sopenharmony_ci // doesn't account for the width of a subset frame (i.e. gif). As a 1202cb93a386Sopenharmony_ci // result, get_start_coord(sampleX) could result in fSrcOffsetUnits 1203cb93a386Sopenharmony_ci // being wider than fSrcWidth. Compute a sampling rate based on the 1204cb93a386Sopenharmony_ci // frame width to ensure that fSrcOffsetUnits is sensible. 1205cb93a386Sopenharmony_ci frameSampleX = fSrcWidth / fSwizzleWidth; 1206cb93a386Sopenharmony_ci } 1207cb93a386Sopenharmony_ci fSrcOffsetUnits = (get_start_coord(frameSampleX) + fSrcOffset) * fSrcBPP; 1208cb93a386Sopenharmony_ci 1209cb93a386Sopenharmony_ci if (fDstOffsetBytes > 0) { 1210cb93a386Sopenharmony_ci const size_t dstSwizzleBytes = fSwizzleWidth * fDstBPP; 1211cb93a386Sopenharmony_ci const size_t dstAllocatedBytes = fAllocatedWidth * fDstBPP; 1212cb93a386Sopenharmony_ci if (fDstOffsetBytes + dstSwizzleBytes > dstAllocatedBytes) { 1213cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 1214cb93a386Sopenharmony_ci SkAndroidFrameworkUtils::SafetyNetLog("118143775"); 1215cb93a386Sopenharmony_ci#endif 1216cb93a386Sopenharmony_ci SkASSERT(dstSwizzleBytes <= dstAllocatedBytes); 1217cb93a386Sopenharmony_ci fDstOffsetBytes = dstAllocatedBytes - dstSwizzleBytes; 1218cb93a386Sopenharmony_ci } 1219cb93a386Sopenharmony_ci } 1220cb93a386Sopenharmony_ci 1221cb93a386Sopenharmony_ci // The optimized swizzler functions do not support sampling. Sampled swizzles 1222cb93a386Sopenharmony_ci // are already fast because they skip pixels. We haven't seen a situation 1223cb93a386Sopenharmony_ci // where speeding up sampling has a significant impact on total decode time. 1224cb93a386Sopenharmony_ci if (1 == fSampleX && fFastProc) { 1225cb93a386Sopenharmony_ci fActualProc = fFastProc; 1226cb93a386Sopenharmony_ci } else { 1227cb93a386Sopenharmony_ci fActualProc = fSlowProc; 1228cb93a386Sopenharmony_ci } 1229cb93a386Sopenharmony_ci 1230cb93a386Sopenharmony_ci return fAllocatedWidth; 1231cb93a386Sopenharmony_ci} 1232cb93a386Sopenharmony_ci 1233cb93a386Sopenharmony_civoid SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) { 1234cb93a386Sopenharmony_ci SkASSERT(nullptr != dst && nullptr != src); 1235cb93a386Sopenharmony_ci fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP, 1236cb93a386Sopenharmony_ci fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable); 1237cb93a386Sopenharmony_ci} 1238