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