474 {
476 if (!encoded) {
478 }
479
481 if (nullptr == codec) {
483 }
484
487 fDstAlphaType)) {
489 }
490
491
493
494 std::unique_ptr<SkAndroidCodec> androidCodec;
497 size = androidCodec->getSampledDimensions(1 / fScale);
498 }
499
501 return Result::Skip(
"Test without scaling is uninteresting.");
502 }
503
504
505
507 return Result::Skip(
"Scaling very small images is uninteresting.");
508 }
510
512 const size_t rowBytes =
size.
width() * bpp;
515
518 memset(pixels.get(), 0,
size.
height() * rowBytes);
520 }
521
527 }
528
529 switch (fMode) {
532 if (fScale != 1.0f) {
535 auto dims = androidCodec->getSampledDimensions(androidOptions.
fSampleSize);
537 }
538
539 std::vector<SkCodec::FrameInfo> frameInfos = androidCodec
540 ? androidCodec->codec()->getFrameInfo() : codec->getFrameInfo();
541 if (frameInfos.size() <= 1) {
543 }
544
545
546
547
548 const float root =
sqrt((
float) frameInfos.size());
550
551
554 for (
int i = 0;
static_cast<size_t>(
i) < frameInfos.size();
i++) {
556
557 const int reqFrame = frameInfos[
i].fRequiredFrame;
559 && priorFramePixels.
get()) {
560
561 memcpy(pixels.get(), priorFramePixels.
get(), safeSize);
563 } else {
565 }
567 ? androidCodec->getAndroidPixels(decodeInfo, pixels.get(), rowBytes,
568 &androidOptions)
569 : codec->getPixels(decodeInfo, pixels.get(), rowBytes, &androidOptions);
571
572
574 }
579
580
581
582
583
584
585 if (
static_cast<size_t>(
i+1) < frameInfos.size()
586 && frameInfos[
i+1].fRequiredFrame ==
i) {
587 memcpy(priorFramePixels.
reset(safeSize), pixels.get(), safeSize);
589 }
590
592 const int xTranslate = (
i % factor) * decodeInfo.
width();
593 const int yTranslate = (
i / factor) * decodeInfo.
height();
595 draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, fDstColorType);
598 }
599 break;
600 }
604 "Cannot decode frame %i to 565 (%s).",
i, fPath.
c_str());
605 }
606 [[fallthrough]];
607 default:
609 "Couldn't getPixels for frame %i in %s.",
i, fPath.
c_str());
610 }
611 }
612 break;
613 }
616 switch (codec->getPixels(decodeInfo, pixels.get(), rowBytes, &
options)) {
618
619
622 break;
623 default:
624
626 }
627
628 draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, fDstColorType);
629 break;
630 }
632 void*
dst = pixels.get();
634 const bool useIncremental = [this]() {
635 auto exts = { "png", "PNG", "gif", "GIF" };
636 for (
auto ext : exts) {
638 return true;
639 }
640 }
641 return false;
642 }();
643
644
645 const bool ico = fPath.
endsWith(
"ico");
646 bool useOldScanlineMethod = !useIncremental && !ico;
647 if (useIncremental || ico) {
650 int rowsDecoded;
651 auto result = codec->incrementalDecode(&rowsDecoded);
653 codec->fillIncompleteImage(decodeInfo,
dst, rowBytes,
655 rowsDecoded);
656 }
657 } else {
658 if (useIncremental) {
659
661 }
662
663
664 useOldScanlineMethod = true;
665 }
666 }
667
668 if (useOldScanlineMethod) {
671 }
672
673
674
675 codec->getScanlines(
dst,
height, rowBytes);
676 }
677
679 break;
680 }
683
684
685 const int stripeHeight = 37;
686 const int numStripes = (
height + stripeHeight - 1) / stripeHeight;
687 void*
dst = pixels.get();
688
689
692 }
693
694
695
696
697
699
700 for (
int i = 0;
i < numStripes;
i += 2) {
701
702 const int linesToSkip =
std::min(stripeHeight,
height -
i * stripeHeight);
703 codec->skipScanlines(linesToSkip);
704
705
706 const int startY = (
i + 1) * stripeHeight;
708 if (linesToRead > 0) {
709 codec->getScanlines(SkTAddOffset<void>(
dst, rowBytes * startY), linesToRead,
710 rowBytes);
711 }
712 }
713
714
715 const SkCodec::Result startResult = codec->startScanlineDecode(decodeInfo);
717 return Result::Fatal(
"Failed to restart scanline decoder with same parameters.");
718 }
719 for (
int i = 0;
i < numStripes;
i += 2) {
720
721 const int startY =
i * stripeHeight;
723 codec->getScanlines(SkTAddOffset<void>(
dst, rowBytes * startY), linesToRead,
724 rowBytes);
725
726
727 const int linesToSkip =
std::min(stripeHeight,
height - (
i + 1) * stripeHeight);
728 if (linesToSkip > 0) {
729 codec->skipScanlines(linesToSkip);
730 }
731 }
732
734 break;
735 }
739
740
741
742 const int tileSize = 36;
744 for (
int x = 0;
x <
width;
x += tileSize) {
749 }
750
751 codec->getScanlines(SkTAddOffset<void>(pixels.get(),
x * bpp),
height, rowBytes);
752 }
753
754 draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, fDstColorType);
755 break;
756 }
758
759 int divisor = 2;
760
761 const int W = codec->getInfo().width();
762 const int H = codec->getInfo().height();
763 if (divisor >
W || divisor >
H) {
764 return Result::Skip(
"Cannot codec subset: divisor %d is too big "
765 "for %s with dimensions (%d x %d)", divisor,
767 }
768
769
775
776 void*
dst = pixels.get();
777
778
779
781 for (
int x = 0;
x <
W;
x +=
w) {
782 int top = 0;
783 for (
int y = 0;
y <
H;
y+=
h) {
784
787 subset.
setXYWH(
x,
y, preScaleW, preScaleH);
788
789
790
793 decodeInfo = decodeInfo.
makeWH(scaledW, scaledH);
795 size_t subsetRowBytes = subsetBitmapInfo.
minRowBytes();
802 break;
803 default:
804 return Result::Fatal(
"subset codec failed to decode (%d, %d, %d, %d) "
805 "from %s with dimensions (%d x %d)\t error %d",
808 }
811
812
813 top += decodeInfo.
height();
814 }
815
817 }
819 }
820 default:
823 }
825}
static constexpr T SkAlign2(T x)
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
#define sk_float_ceil2int(x)
#define SkScalarRoundToInt(x)
SkISize size() const override
static Result Skip(const char *fmt,...) SK_PRINTF_LIKE(1
static Result Fatal(const char *fmt,...) SK_PRINTF_LIKE(1
static std::unique_ptr< SkAndroidCodec > MakeFromData(sk_sp< SkData >, SkPngChunkReader *=nullptr)
void * reset(size_t size=0, OnShrink shrink=kAlloc_OnShrink)
void translate(SkScalar dx, SkScalar dy)
SkImageInfo imageInfo() const
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
@ kTopDown_SkScanlineOrder
static constexpr int kNoFrame
static sk_sp< SkData > MakeFromFileName(const char path[])
bool endsWith(const char suffixStr[]) const
const char * c_str() const
static float max(float r, float g, float b)
static float min(float r, float g, float b)
static void draw_to_canvas(SkCanvas *canvas, const SkImageInfo &info, void *pixels, size_t rowBytes, CodecSrc::DstColorType dstColorType, SkScalar left=0, SkScalar top=0)
static void set_bitmap_color_space(SkImageInfo *info)
static bool get_decode_info(SkImageInfo *decodeInfo, SkColorType canvasColorType, CodecSrc::DstColorType dstColorType, SkAlphaType dstAlphaType)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height)
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
constexpr int32_t width() const
constexpr int32_t height() const
SkImageInfo makeWH(int newWidth, int newHeight) const
size_t minRowBytes() const
size_t computeByteSize(size_t rowBytes) const
SkImageInfo makeDimensions(SkISize newSize) const
int bytesPerPixel() const
SkISize dimensions() const
SkColorType colorType() const
SkImageInfo makeColorType(SkColorType newColorType) const