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 "SkColorData.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 constexpr 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 constexpr 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 static void swizzle_grayalpha_to_a8(void* dst, const uint8_t* src, int width, int bpp, 361 int deltaSrc, int offset, const SkPMColor[]) { 362 src += offset; 363 uint8_t* dst8 = (uint8_t*)dst; 364 for (int x = 0; x < width; ++x) { 365 dst8[x] = src[1]; // src[0] is gray, ignored 366 src += deltaSrc; 367 } 368 } 369 370 // kBGR 371 372 static void swizzle_bgr_to_565( 373 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 374 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 375 376 src += offset; 377 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 378 for (int x = 0; x < dstWidth; x++) { 379 dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]); 380 src += deltaSrc; 381 } 382 } 383 384 // kRGB 385 386 static void swizzle_rgb_to_rgba( 387 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 388 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 389 390 src += offset; 391 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 392 for (int x = 0; x < dstWidth; x++) { 393 dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]); 394 src += deltaSrc; 395 } 396 } 397 398 static void swizzle_rgb_to_bgra( 399 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 400 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 401 402 src += offset; 403 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 404 for (int x = 0; x < dstWidth; x++) { 405 dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]); 406 src += deltaSrc; 407 } 408 } 409 410 static void fast_swizzle_rgb_to_rgba( 411 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, 412 int offset, const SkPMColor ctable[]) { 413 414 // This function must not be called if we are sampling. If we are not 415 // sampling, deltaSrc should equal bpp. 416 SkASSERT(deltaSrc == bpp); 417 418 SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width); 419 } 420 421 static void fast_swizzle_rgb_to_bgra( 422 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, 423 int offset, const SkPMColor ctable[]) { 424 425 // This function must not be called if we are sampling. If we are not 426 // sampling, deltaSrc should equal bpp. 427 SkASSERT(deltaSrc == bpp); 428 429 SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width); 430 } 431 432 static void swizzle_rgb_to_565( 433 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 434 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) { 435 436 src += offset; 437 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 438 for (int x = 0; x < dstWidth; x++) { 439 dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); 440 src += deltaSrc; 441 } 442 } 443 444 // kRGBA 445 446 static void swizzle_rgba_to_rgba_premul( 447 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 448 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 449 450 src += offset; 451 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 452 for (int x = 0; x < dstWidth; x++) { 453 dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]); 454 src += deltaSrc; 455 } 456 } 457 458 static void swizzle_rgba_to_bgra_premul( 459 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 460 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 461 462 src += offset; 463 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 464 for (int x = 0; x < dstWidth; x++) { 465 dst[x] = premultiply_argb_as_bgra(src[3], src[0], src[1], src[2]); 466 src += deltaSrc; 467 } 468 } 469 470 static void fast_swizzle_rgba_to_rgba_premul( 471 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, 472 int offset, const SkPMColor ctable[]) { 473 474 // This function must not be called if we are sampling. If we are not 475 // sampling, deltaSrc should equal bpp. 476 SkASSERT(deltaSrc == bpp); 477 478 SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width); 479 } 480 481 static void fast_swizzle_rgba_to_bgra_premul( 482 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, 483 int offset, const SkPMColor ctable[]) { 484 485 // This function must not be called if we are sampling. If we are not 486 // sampling, deltaSrc should equal bpp. 487 SkASSERT(deltaSrc == bpp); 488 489 SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width); 490 } 491 492 static void swizzle_rgba_to_bgra_unpremul( 493 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 494 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 495 496 src += offset; 497 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); 498 for (int x = 0; x < dstWidth; x++) { 499 unsigned alpha = src[3]; 500 dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]); 501 src += deltaSrc; 502 } 503 } 504 505 static void fast_swizzle_rgba_to_bgra_unpremul( 506 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 507 const SkPMColor ctable[]) { 508 509 // This function must not be called if we are sampling. If we are not 510 // sampling, deltaSrc should equal bpp. 511 SkASSERT(deltaSrc == bpp); 512 513 SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width); 514 } 515 516 // 16-bits per component kRGB and kRGBA 517 518 static void swizzle_rgb16_to_rgba( 519 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 520 const SkPMColor ctable[]) { 521 auto strip16to8 = [](const uint8_t* ptr) { 522 return 0xFF000000 | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0]; 523 }; 524 525 src += offset; 526 uint32_t* dst32 = (uint32_t*) dst; 527 for (int x = 0; x < width; x++) { 528 dst32[x] = strip16to8(src); 529 src += deltaSrc; 530 } 531 } 532 533 static void swizzle_rgb16_to_bgra( 534 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 535 const SkPMColor ctable[]) { 536 auto strip16to8 = [](const uint8_t* ptr) { 537 return 0xFF000000 | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4]; 538 }; 539 540 src += offset; 541 uint32_t* dst32 = (uint32_t*) dst; 542 for (int x = 0; x < width; x++) { 543 dst32[x] = strip16to8(src); 544 src += deltaSrc; 545 } 546 } 547 548 static void swizzle_rgb16_to_565( 549 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 550 const SkPMColor ctable[]) { 551 auto strip16to565 = [](const uint8_t* ptr) { 552 return SkPack888ToRGB16(ptr[0], ptr[2], ptr[4]); 553 }; 554 555 src += offset; 556 uint16_t* dst16 = (uint16_t*) dst; 557 for (int x = 0; x < width; x++) { 558 dst16[x] = strip16to565(src); 559 src += deltaSrc; 560 } 561 } 562 563 static void swizzle_rgba16_to_rgba_unpremul( 564 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 565 const SkPMColor ctable[]) { 566 auto strip16to8 = [](const uint8_t* ptr) { 567 return (ptr[6] << 24) | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0]; 568 }; 569 570 src += offset; 571 uint32_t* dst32 = (uint32_t*) dst; 572 for (int x = 0; x < width; x++) { 573 dst32[x] = strip16to8(src); 574 src += deltaSrc; 575 } 576 } 577 578 static void swizzle_rgba16_to_rgba_premul( 579 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 580 const SkPMColor ctable[]) { 581 auto stripAndPremul16to8 = [](const uint8_t* ptr) { 582 return premultiply_argb_as_rgba(ptr[6], ptr[0], ptr[2], ptr[4]); 583 }; 584 585 src += offset; 586 uint32_t* dst32 = (uint32_t*) dst; 587 for (int x = 0; x < width; x++) { 588 dst32[x] = stripAndPremul16to8(src); 589 src += deltaSrc; 590 } 591 } 592 593 static void swizzle_rgba16_to_bgra_unpremul( 594 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 595 const SkPMColor ctable[]) { 596 auto strip16to8 = [](const uint8_t* ptr) { 597 return (ptr[6] << 24) | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4]; 598 }; 599 600 src += offset; 601 uint32_t* dst32 = (uint32_t*) dst; 602 for (int x = 0; x < width; x++) { 603 dst32[x] = strip16to8(src); 604 src += deltaSrc; 605 } 606 } 607 608 static void swizzle_rgba16_to_bgra_premul( 609 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 610 const SkPMColor ctable[]) { 611 auto stripAndPremul16to8 = [](const uint8_t* ptr) { 612 return premultiply_argb_as_bgra(ptr[6], ptr[0], ptr[2], ptr[4]); 613 }; 614 615 src += offset; 616 uint32_t* dst32 = (uint32_t*) dst; 617 for (int x = 0; x < width; x++) { 618 dst32[x] = stripAndPremul16to8(src); 619 src += deltaSrc; 620 } 621 } 622 623 // kCMYK 624 // 625 // CMYK is stored as four bytes per pixel. 626 // 627 // We will implement a crude conversion from CMYK -> RGB using formulas 628 // from easyrgb.com. 629 // 630 // CMYK -> CMY 631 // C = C * (1 - K) + K 632 // M = M * (1 - K) + K 633 // Y = Y * (1 - K) + K 634 // 635 // libjpeg actually gives us inverted CMYK, so we must subtract the 636 // original terms from 1. 637 // CMYK -> CMY 638 // C = (1 - C) * (1 - (1 - K)) + (1 - K) 639 // M = (1 - M) * (1 - (1 - K)) + (1 - K) 640 // Y = (1 - Y) * (1 - (1 - K)) + (1 - K) 641 // 642 // Simplifying the above expression. 643 // CMYK -> CMY 644 // C = 1 - CK 645 // M = 1 - MK 646 // Y = 1 - YK 647 // 648 // CMY -> RGB 649 // R = (1 - C) * 255 650 // G = (1 - M) * 255 651 // B = (1 - Y) * 255 652 // 653 // Therefore the full conversion is below. This can be verified at 654 // www.rapidtables.com (assuming inverted CMYK). 655 // CMYK -> RGB 656 // R = C * K * 255 657 // G = M * K * 255 658 // B = Y * K * 255 659 // 660 // As a final note, we have treated the CMYK values as if they were on 661 // a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255. 662 // We must divide each CMYK component by 255 to obtain the true conversion 663 // we should perform. 664 // CMYK -> RGB 665 // R = C * K / 255 666 // G = M * K / 255 667 // B = Y * K / 255 668 static void swizzle_cmyk_to_rgba( 669 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 670 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 671 672 src += offset; 673 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 674 for (int x = 0; x < dstWidth; x++) { 675 const uint8_t r = SkMulDiv255Round(src[0], src[3]); 676 const uint8_t g = SkMulDiv255Round(src[1], src[3]); 677 const uint8_t b = SkMulDiv255Round(src[2], src[3]); 678 679 dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b); 680 src += deltaSrc; 681 } 682 } 683 684 static void swizzle_cmyk_to_bgra( 685 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 686 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 687 688 src += offset; 689 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 690 for (int x = 0; x < dstWidth; x++) { 691 const uint8_t r = SkMulDiv255Round(src[0], src[3]); 692 const uint8_t g = SkMulDiv255Round(src[1], src[3]); 693 const uint8_t b = SkMulDiv255Round(src[2], src[3]); 694 695 dst[x] = SkPackARGB_as_BGRA(0xFF, r, g, b); 696 src += deltaSrc; 697 } 698 } 699 700 static void fast_swizzle_cmyk_to_rgba( 701 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 702 const SkPMColor ctable[]) { 703 704 // This function must not be called if we are sampling. If we are not 705 // sampling, deltaSrc should equal bpp. 706 SkASSERT(deltaSrc == bpp); 707 708 SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width); 709 } 710 711 static void fast_swizzle_cmyk_to_bgra( 712 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, 713 const SkPMColor ctable[]) { 714 715 // This function must not be called if we are sampling. If we are not 716 // sampling, deltaSrc should equal bpp. 717 SkASSERT(deltaSrc == bpp); 718 719 SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width); 720 } 721 722 static void swizzle_cmyk_to_565( 723 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 724 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 725 726 src += offset; 727 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 728 for (int x = 0; x < dstWidth; x++) { 729 const uint8_t r = SkMulDiv255Round(src[0], src[3]); 730 const uint8_t g = SkMulDiv255Round(src[1], src[3]); 731 const uint8_t b = SkMulDiv255Round(src[2], src[3]); 732 733 dst[x] = SkPack888ToRGB16(r, g, b); 734 src += deltaSrc; 735 } 736 } 737 738 template <SkSwizzler::RowProc proc> 739 void SkSwizzler::SkipLeadingGrayAlphaZerosThen( 740 void* dst, const uint8_t* src, int width, 741 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 742 SkASSERT(!ctable); 743 744 const uint16_t* src16 = (const uint16_t*) (src + offset); 745 uint32_t* dst32 = (uint32_t*) dst; 746 747 // This may miss opportunities to skip when the output is premultiplied, 748 // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication. 749 while (width > 0 && *src16 == 0x0000) { 750 width--; 751 dst32++; 752 src16 += deltaSrc / 2; 753 } 754 proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable); 755 } 756 757 template <SkSwizzler::RowProc proc> 758 void SkSwizzler::SkipLeading8888ZerosThen( 759 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 760 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 761 SkASSERT(!ctable); 762 763 auto src32 = (const uint32_t*)(src+offset); 764 auto dst32 = (uint32_t*)dstRow; 765 766 // This may miss opportunities to skip when the output is premultiplied, 767 // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication. 768 while (dstWidth > 0 && *src32 == 0x00000000) { 769 dstWidth--; 770 dst32++; 771 src32 += deltaSrc/4; 772 } 773 proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable); 774 } 775 776 SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, 777 const SkPMColor* ctable, 778 const SkImageInfo& dstInfo, 779 const SkCodec::Options& options, 780 const SkIRect* frame, 781 bool skipFormatConversion) { 782 if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) { 783 return nullptr; 784 } 785 786 RowProc fastProc = nullptr; 787 RowProc proc = nullptr; 788 int srcBPP; 789 const int dstBPP = dstInfo.bytesPerPixel(); 790 if (skipFormatConversion) { 791 switch (encodedInfo.color()) { 792 case SkEncodedInfo::kGray_Color: 793 case SkEncodedInfo::kYUV_Color: 794 // We have a jpeg that has already been converted to the dstColorType. 795 srcBPP = dstBPP; 796 switch (dstInfo.colorType()) { 797 case kGray_8_SkColorType: 798 proc = &sample1; 799 fastProc = © 800 break; 801 case kRGB_565_SkColorType: 802 proc = &sample2; 803 fastProc = © 804 break; 805 case kRGBA_8888_SkColorType: 806 case kBGRA_8888_SkColorType: 807 proc = &sample4; 808 fastProc = © 809 break; 810 default: 811 return nullptr; 812 } 813 break; 814 case SkEncodedInfo::kInvertedCMYK_Color: 815 case SkEncodedInfo::kYCCK_Color: 816 // We have a jpeg that remains in its original format. 817 srcBPP = 4; 818 proc = &sample4; 819 fastProc = © 820 break; 821 case SkEncodedInfo::kRGBA_Color: 822 // We have a png that should remain in its original format. 823 SkASSERT(16 == encodedInfo.bitsPerComponent() || 824 8 == encodedInfo.bitsPerComponent()); 825 if (8 == encodedInfo.bitsPerComponent()) { 826 srcBPP = 4; 827 proc = &sample4; 828 } else { 829 srcBPP = 8; 830 proc = &sample8; 831 } 832 fastProc = © 833 break; 834 case SkEncodedInfo::kRGB_Color: 835 // We have a png that remains in its original format. 836 SkASSERT(16 == encodedInfo.bitsPerComponent()); 837 srcBPP = 6; 838 proc = &sample6; 839 fastProc = © 840 break; 841 default: 842 return nullptr; 843 } 844 } else { 845 SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized; 846 const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) && 847 (kPremul_SkAlphaType == dstInfo.alphaType()); 848 849 switch (encodedInfo.color()) { 850 case SkEncodedInfo::kGray_Color: 851 switch (encodedInfo.bitsPerComponent()) { 852 case 1: 853 switch (dstInfo.colorType()) { 854 case kRGBA_8888_SkColorType: 855 case kBGRA_8888_SkColorType: 856 proc = &swizzle_bit_to_n32; 857 break; 858 case kRGB_565_SkColorType: 859 proc = &swizzle_bit_to_565; 860 break; 861 case kGray_8_SkColorType: 862 proc = &swizzle_bit_to_grayscale; 863 break; 864 case kRGBA_F16_SkColorType: 865 proc = &swizzle_bit_to_f16; 866 break; 867 default: 868 return nullptr; 869 } 870 break; 871 case 8: 872 switch (dstInfo.colorType()) { 873 case kRGBA_8888_SkColorType: 874 case kBGRA_8888_SkColorType: 875 proc = &swizzle_gray_to_n32; 876 fastProc = &fast_swizzle_gray_to_n32; 877 break; 878 case kGray_8_SkColorType: 879 proc = &sample1; 880 fastProc = © 881 break; 882 case kRGB_565_SkColorType: 883 proc = &swizzle_gray_to_565; 884 break; 885 default: 886 return nullptr; 887 } 888 break; 889 default: 890 return nullptr; 891 } 892 break; 893 case SkEncodedInfo::kGrayAlpha_Color: 894 switch (dstInfo.colorType()) { 895 case kRGBA_8888_SkColorType: 896 case kBGRA_8888_SkColorType: 897 if (premultiply) { 898 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 899 proc = &SkipLeadingGrayAlphaZerosThen 900 <swizzle_grayalpha_to_n32_premul>; 901 fastProc = &SkipLeadingGrayAlphaZerosThen 902 <fast_swizzle_grayalpha_to_n32_premul>; 903 } else { 904 proc = &swizzle_grayalpha_to_n32_premul; 905 fastProc = &fast_swizzle_grayalpha_to_n32_premul; 906 } 907 } else { 908 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 909 proc = &SkipLeadingGrayAlphaZerosThen 910 <swizzle_grayalpha_to_n32_unpremul>; 911 fastProc = &SkipLeadingGrayAlphaZerosThen 912 <fast_swizzle_grayalpha_to_n32_unpremul>; 913 } else { 914 proc = &swizzle_grayalpha_to_n32_unpremul; 915 fastProc = &fast_swizzle_grayalpha_to_n32_unpremul; 916 } 917 } 918 break; 919 case kAlpha_8_SkColorType: 920 proc = &swizzle_grayalpha_to_a8; 921 break; 922 default: 923 return nullptr; 924 } 925 break; 926 case SkEncodedInfo::kPalette_Color: 927 // We assume that the color table is premultiplied and swizzled 928 // as desired. 929 switch (encodedInfo.bitsPerComponent()) { 930 case 1: 931 case 2: 932 case 4: 933 switch (dstInfo.colorType()) { 934 case kRGBA_8888_SkColorType: 935 case kBGRA_8888_SkColorType: 936 proc = &swizzle_small_index_to_n32; 937 break; 938 case kRGB_565_SkColorType: 939 proc = &swizzle_small_index_to_565; 940 break; 941 default: 942 return nullptr; 943 } 944 break; 945 case 8: 946 switch (dstInfo.colorType()) { 947 case kRGBA_8888_SkColorType: 948 case kBGRA_8888_SkColorType: 949 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 950 proc = &swizzle_index_to_n32_skipZ; 951 } else { 952 proc = &swizzle_index_to_n32; 953 } 954 break; 955 case kRGB_565_SkColorType: 956 proc = &swizzle_index_to_565; 957 break; 958 default: 959 return nullptr; 960 } 961 break; 962 default: 963 return nullptr; 964 } 965 break; 966 case SkEncodedInfo::kRGB_Color: 967 switch (dstInfo.colorType()) { 968 case kRGBA_8888_SkColorType: 969 if (16 == encodedInfo.bitsPerComponent()) { 970 proc = &swizzle_rgb16_to_rgba; 971 break; 972 } 973 974 SkASSERT(8 == encodedInfo.bitsPerComponent()); 975 proc = &swizzle_rgb_to_rgba; 976 fastProc = &fast_swizzle_rgb_to_rgba; 977 break; 978 case kBGRA_8888_SkColorType: 979 if (16 == encodedInfo.bitsPerComponent()) { 980 proc = &swizzle_rgb16_to_bgra; 981 break; 982 } 983 984 SkASSERT(8 == encodedInfo.bitsPerComponent()); 985 proc = &swizzle_rgb_to_bgra; 986 fastProc = &fast_swizzle_rgb_to_bgra; 987 break; 988 case kRGB_565_SkColorType: 989 if (16 == encodedInfo.bitsPerComponent()) { 990 proc = &swizzle_rgb16_to_565; 991 break; 992 } 993 994 proc = &swizzle_rgb_to_565; 995 break; 996 default: 997 return nullptr; 998 } 999 break; 1000 case SkEncodedInfo::kRGBA_Color: 1001 switch (dstInfo.colorType()) { 1002 case kRGBA_8888_SkColorType: 1003 if (16 == encodedInfo.bitsPerComponent()) { 1004 proc = premultiply ? &swizzle_rgba16_to_rgba_premul : 1005 &swizzle_rgba16_to_rgba_unpremul; 1006 break; 1007 } 1008 1009 SkASSERT(8 == encodedInfo.bitsPerComponent()); 1010 if (premultiply) { 1011 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1012 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>; 1013 fastProc = &SkipLeading8888ZerosThen 1014 <fast_swizzle_rgba_to_rgba_premul>; 1015 } else { 1016 proc = &swizzle_rgba_to_rgba_premul; 1017 fastProc = &fast_swizzle_rgba_to_rgba_premul; 1018 } 1019 } else { 1020 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1021 proc = &SkipLeading8888ZerosThen<sample4>; 1022 fastProc = &SkipLeading8888ZerosThen<copy>; 1023 } else { 1024 proc = &sample4; 1025 fastProc = © 1026 } 1027 } 1028 break; 1029 case kBGRA_8888_SkColorType: 1030 if (16 == encodedInfo.bitsPerComponent()) { 1031 proc = premultiply ? &swizzle_rgba16_to_bgra_premul : 1032 &swizzle_rgba16_to_bgra_unpremul; 1033 break; 1034 } 1035 1036 SkASSERT(8 == encodedInfo.bitsPerComponent()); 1037 if (premultiply) { 1038 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1039 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>; 1040 fastProc = &SkipLeading8888ZerosThen 1041 <fast_swizzle_rgba_to_bgra_premul>; 1042 } else { 1043 proc = &swizzle_rgba_to_bgra_premul; 1044 fastProc = &fast_swizzle_rgba_to_bgra_premul; 1045 } 1046 } else { 1047 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1048 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>; 1049 fastProc = &SkipLeading8888ZerosThen 1050 <fast_swizzle_rgba_to_bgra_unpremul>; 1051 } else { 1052 proc = &swizzle_rgba_to_bgra_unpremul; 1053 fastProc = &fast_swizzle_rgba_to_bgra_unpremul; 1054 } 1055 } 1056 break; 1057 default: 1058 return nullptr; 1059 } 1060 break; 1061 case SkEncodedInfo::kBGR_Color: 1062 switch (dstInfo.colorType()) { 1063 case kBGRA_8888_SkColorType: 1064 proc = &swizzle_rgb_to_rgba; 1065 fastProc = &fast_swizzle_rgb_to_rgba; 1066 break; 1067 case kRGBA_8888_SkColorType: 1068 proc = &swizzle_rgb_to_bgra; 1069 fastProc = &fast_swizzle_rgb_to_bgra; 1070 break; 1071 case kRGB_565_SkColorType: 1072 proc = &swizzle_bgr_to_565; 1073 break; 1074 default: 1075 return nullptr; 1076 } 1077 break; 1078 case SkEncodedInfo::kBGRX_Color: 1079 switch (dstInfo.colorType()) { 1080 case kBGRA_8888_SkColorType: 1081 proc = &swizzle_rgb_to_rgba; 1082 break; 1083 case kRGBA_8888_SkColorType: 1084 proc = &swizzle_rgb_to_bgra; 1085 break; 1086 case kRGB_565_SkColorType: 1087 proc = &swizzle_bgr_to_565; 1088 break; 1089 default: 1090 return nullptr; 1091 } 1092 break; 1093 case SkEncodedInfo::kBGRA_Color: 1094 switch (dstInfo.colorType()) { 1095 case kBGRA_8888_SkColorType: 1096 if (premultiply) { 1097 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1098 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>; 1099 fastProc = &SkipLeading8888ZerosThen 1100 <fast_swizzle_rgba_to_rgba_premul>; 1101 } else { 1102 proc = &swizzle_rgba_to_rgba_premul; 1103 fastProc = &fast_swizzle_rgba_to_rgba_premul; 1104 } 1105 } else { 1106 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1107 proc = &SkipLeading8888ZerosThen<sample4>; 1108 fastProc = &SkipLeading8888ZerosThen<copy>; 1109 } else { 1110 proc = &sample4; 1111 fastProc = © 1112 } 1113 } 1114 break; 1115 case kRGBA_8888_SkColorType: 1116 if (premultiply) { 1117 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1118 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>; 1119 fastProc = &SkipLeading8888ZerosThen 1120 <fast_swizzle_rgba_to_bgra_premul>; 1121 } else { 1122 proc = &swizzle_rgba_to_bgra_premul; 1123 fastProc = &fast_swizzle_rgba_to_bgra_premul; 1124 } 1125 } else { 1126 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 1127 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>; 1128 fastProc = &SkipLeading8888ZerosThen 1129 <fast_swizzle_rgba_to_bgra_unpremul>; 1130 } else { 1131 proc = &swizzle_rgba_to_bgra_unpremul; 1132 fastProc = &fast_swizzle_rgba_to_bgra_unpremul; 1133 } 1134 } 1135 break; 1136 default: 1137 return nullptr; 1138 } 1139 break; 1140 case SkEncodedInfo::kInvertedCMYK_Color: 1141 switch (dstInfo.colorType()) { 1142 case kRGBA_8888_SkColorType: 1143 proc = &swizzle_cmyk_to_rgba; 1144 fastProc = &fast_swizzle_cmyk_to_rgba; 1145 break; 1146 case kBGRA_8888_SkColorType: 1147 proc = &swizzle_cmyk_to_bgra; 1148 fastProc = &fast_swizzle_cmyk_to_bgra; 1149 break; 1150 case kRGB_565_SkColorType: 1151 proc = &swizzle_cmyk_to_565; 1152 break; 1153 default: 1154 return nullptr; 1155 } 1156 break; 1157 default: 1158 return nullptr; 1159 } 1160 1161 // Store bpp in bytes if it is an even multiple, otherwise use bits 1162 uint8_t bitsPerPixel = encodedInfo.bitsPerPixel(); 1163 srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel; 1164 } 1165 1166 int srcOffset = 0; 1167 int srcWidth = dstInfo.width(); 1168 int dstOffset = 0; 1169 int dstWidth = srcWidth; 1170 if (options.fSubset) { 1171 // We do not currently support subset decodes for image types that may have 1172 // frames (gif). 1173 SkASSERT(!frame); 1174 srcOffset = options.fSubset->left(); 1175 srcWidth = options.fSubset->width(); 1176 dstWidth = srcWidth; 1177 } else if (frame) { 1178 dstOffset = frame->left(); 1179 srcWidth = frame->width(); 1180 } 1181 1182 return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth, 1183 srcBPP, dstBPP); 1184 } 1185 1186 SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset, 1187 int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP) 1188 : fFastProc(fastProc) 1189 , fSlowProc(proc) 1190 , fActualProc(fFastProc ? fFastProc : fSlowProc) 1191 , fColorTable(ctable) 1192 , fSrcOffset(srcOffset) 1193 , fDstOffset(dstOffset) 1194 , fSrcOffsetUnits(srcOffset * srcBPP) 1195 , fDstOffsetBytes(dstOffset * dstBPP) 1196 , fSrcWidth(srcWidth) 1197 , fDstWidth(dstWidth) 1198 , fSwizzleWidth(srcWidth) 1199 , fAllocatedWidth(dstWidth) 1200 , fSampleX(1) 1201 , fSrcBPP(srcBPP) 1202 , fDstBPP(dstBPP) 1203 {} 1204 1205 int SkSwizzler::onSetSampleX(int sampleX) { 1206 SkASSERT(sampleX > 0); 1207 1208 fSampleX = sampleX; 1209 fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP; 1210 fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP; 1211 fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX); 1212 fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX); 1213 1214 // The optimized swizzler functions do not support sampling. Sampled swizzles 1215 // are already fast because they skip pixels. We haven't seen a situation 1216 // where speeding up sampling has a significant impact on total decode time. 1217 if (1 == fSampleX && fFastProc) { 1218 fActualProc = fFastProc; 1219 } else { 1220 fActualProc = fSlowProc; 1221 } 1222 1223 return fAllocatedWidth; 1224 } 1225 1226 void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) { 1227 SkASSERT(nullptr != dst && nullptr != src); 1228 fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP, 1229 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable); 1230 } 1231