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