369 {
371 SkASSERT(0 == index || index < fFrameHolder.size());
373
374 WebPDecoderConfig config;
375 if (0 == WebPInitDecoderConfig(&config)) {
376
377
379 }
380
381
383
386
388
390 (fFrameHolder.frame(index)->getRequiredFrame() ==
kNoFrame);
391
392
395 const bool frameIsSubset = frameRect != this->
bounds();
396 if (independent && frameIsSubset) {
398 }
399
400 int dstX = frameRect.x();
401 int dstY = frameRect.y();
402 int subsetWidth = frameRect.width();
403 int subsetHeight = frameRect.height();
409
412 }
413
414 int minXOffset =
std::min(dstX, subset.
x());
415 int minYOffset =
std::min(dstY, subset.
y());
416 dstX -= minXOffset;
417 dstY -= minYOffset;
418 frameRect.offset(-minXOffset, -minYOffset);
419 subset.
offset(-minXOffset, -minYOffset);
420
421
422
423
425
428 subsetWidth = intersection.
width();
429 subsetHeight = intersection.
height();
430
431 config.options.use_cropping = 1;
432 config.options.crop_left = subset.
x();
433 config.options.crop_top = subset.
y();
434 config.options.crop_width = subsetWidth;
435 config.options.crop_height = subsetHeight;
436 }
437
438
439 int scaledWidth = subsetWidth;
440 int scaledHeight = subsetHeight;
443 config.options.use_scaling = 1;
444
445 if (frameIsSubset) {
448
449
450
451 dstX = scaleX * dstX;
452 scaledWidth = scaleX * scaledWidth;
453 dstY = scaleY * dstY;
454 scaledHeight = scaleY * scaledHeight;
455 if (0 == scaledWidth || 0 == scaledHeight) {
457 }
458 } else {
461 }
462
463 config.options.scaled_width = scaledWidth;
464 config.options.scaled_height = scaledHeight;
465 }
466
467 const bool blendWithPrevFrame = !
independent &&
frame.blend_method == WEBP_MUX_BLEND
469
471 if (!
frame.has_alpha) {
473 }
else if (this->
colorXform() || blendWithPrevFrame) {
474
476 }
478
479
480
481
482
484 }
485
488
489
490
492 } else {
493
495 }
496
499 config.output.is_external_memory = 1;
500
501 config.output.u.RGBA.rgba =
reinterpret_cast<uint8_t*
>(webpDst.
getAddr(dstX, dstY));
502 config.output.u.RGBA.stride =
static_cast<int>(webpDst.
rowBytes());
504
506 if (!idec) {
508 }
509
510 int rowsDecoded = 0;
512 switch (WebPIUpdate(idec,
frame.fragment.bytes,
frame.fragment.size)) {
513 case VP8_STATUS_OK:
514 rowsDecoded = scaledHeight;
516 break;
517 case VP8_STATUS_SUSPENDED:
518 if (!WebPIDecGetRGB(idec, &rowsDecoded, nullptr, nullptr, nullptr)
519 || rowsDecoded <= 0) {
521 }
522 *rowsDecodedPtr = rowsDecoded + dstY;
524 break;
525 default:
527 }
528
530 dst = SkTAddOffset<void>(
dst, dstBpp * dstX + rowBytes * dstY);
531 const size_t srcRowBytes = config.output.u.RGBA.stride;
532
535 uint32_t* xformSrc = (uint32_t*) config.output.u.RGBA.rgba;
537 void* xformDst;
538
539 if (blendWithPrevFrame) {
540
542 xformDst = tmp.getPixels();
543 } else {
545 }
546
547 for (
int y = 0;
y < rowsDecoded;
y++) {
549 if (blendWithPrevFrame) {
552 dst = SkTAddOffset<void>(
dst, rowBytes);
553 } else {
554 xformDst = SkTAddOffset<void>(xformDst, rowBytes);
555 }
556 xformSrc = SkTAddOffset<uint32_t>(xformSrc, srcRowBytes);
557 }
558 } else if (blendWithPrevFrame) {
559 const uint8_t*
src = config.output.u.RGBA.rgba;
560
561 for (
int y = 0;
y < rowsDecoded;
y++) {
564 src = SkTAddOffset<const uint8_t>(
src, srcRowBytes);
565 dst = SkTAddOffset<void>(
dst, rowBytes);
566 }
567 }
568
570}
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
static constexpr bool SkIsAlign2(T x)
@ kOpaque_SkAlphaType
pixel is opaque
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
static bool independent(const SkFrame &frame)
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
static bool is_8888(SkColorType colorType)
static WEBP_CSP_MODE webp_decode_mode(SkColorType dstCT, bool premultiply)
static void blend_line(SkColorType dstCT, void *dst, SkColorType srcCT, const void *src, SkAlphaType dstAt, bool srcHasAlpha, int width)
void allocPixels(const SkImageInfo &info, size_t rowBytes)
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, void(*releaseProc)(void *addr, void *context), void *context)
size_t computeByteSize() const
void * getAddr(int x, int y) const
SkColorType colorType() const
bool getValidSubset(SkIRect *desiredSubset) const
SkISize dimensions() const
const SkImageInfo & dstInfo() const
void applyColorXform(void *dst, const void *src, int count) const
static constexpr int kNoFrame
const Options & options() const
static void Fill(const SkImageInfo &info, void *dst, size_t rowBytes, SkCodec::ZeroInitialized zeroInit)
static float min(float r, float g, float b)
constexpr bool contains(std::string_view str, std::string_view needle)
ZeroInitialized fZeroInitialized
constexpr int32_t x() const
constexpr int32_t y() const
bool intersect(const SkIRect &r)
static bool Intersects(const SkIRect &a, const SkIRect &b)
constexpr SkISize size() const
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
void offset(int32_t dx, int32_t dy)
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
int32_t fLeft
smaller x-axis bounds
constexpr int32_t width() const
constexpr int32_t height() const
SkImageInfo makeWH(int newWidth, int newHeight) const
SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const
int bytesPerPixel() const
SkISize dimensions() const
SkAlphaType alphaType() const
SkColorType colorType() const
SkImageInfo makeColorType(SkColorType newColorType) const