LorisYounger/VPet · error · InvalidDataException

Decode APNG frame bitmap failed.

Error message

Decode APNG frame bitmap failed.

What it means

During sprite-sheet assembly, DecodeFrameBitmap failed to decode a frame's compressed image data (IDAT/fdAT payload) into an SkiaSharp bitmap, returning null. The loader throws InvalidDataException rather than compositing a corrupt frame.

Solutions

  1. Re-download or re-export the APNG from a known-good source.
  2. Validate each frame's data decodes (e.g. SKBitmap.Decode) before shipping the asset.
  3. Update SkiaSharp to a version supporting the file's color/interlace format.
  4. Regenerate the animation with apngasm/ffmpeg to rebuild frame chunks.

Example fix

// before
// asset shipped with truncated fdAT; crash at BuildSpriteSheet
// after
// rebuild:
// apngasm -o fixed.png frames/*.png
new APNGAnimation("fixed.png");
Defensive patterns

Strategy: try-catch

Try / catch

try { var anim = new APNGAnimation(path); } catch (InvalidDataException ex) when (ex.Message.Contains("Decode")) { Log.Error($"corrupt frame data in {path}"); LoadFallbackGraph(); }

Prevention

When it happens

Trigger: BuildSpriteSheet iterates parsed frames and DecodeFrameBitmap returns null for a frame whose zlib/image data is corrupt, truncated, or uses unsupported color formats.

Common situations: Partially downloaded animation files; corrupted fdAT chunks from bad hex edits; APNG variants whose frame data SkiaSharp cannot decode; assets damaged by transfer in text/FTP ASCII mode.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of LorisYounger/VPet@ffb9cc2a85 (2026-09-15). Data as JSON: /api/errors/7ad9f750ca5a87fd. Report an issue: GitHub.

Appendix: source

Thrown at VPet-Simulator.Core/Graph/APNGAnimation.cs:188

                FailMessage = $"--APNGAnimation--{GraphInfo}--\nPath: {Path}\n{e.Message}";
            }
        }

        private void BuildSpriteSheet(ParsedApng parsed)
        {
            using var canvasBitmap = new SKBitmap(parsed.CanvasWidth, parsed.CanvasHeight, SKColorType.Bgra8888, SKAlphaType.Premul);
            using var combinedBitmap = new SKBitmap(FrameWidth * parsed.Frames.Count, FrameHeight, SKColorType.Bgra8888, SKAlphaType.Premul);
            using var combinedCanvas = new SKCanvas(combinedBitmap);
            canvasBitmap.Erase(SKColors.Transparent);
            combinedBitmap.Erase(SKColors.Transparent);

            for (int i = 0; i < parsed.Frames.Count; i++)
            {
                var frameData = parsed.Frames[i];
                using var previousCanvas = frameData.DisposeOp == 2 ? canvasBitmap.Copy() : null;
                using var patchBitmap = DecodeFrameBitmap(parsed, frameData);
                if (patchBitmap == null)
                    throw new InvalidDataException("Decode APNG frame bitmap failed.");

                using (var canvas = new SKCanvas(canvasBitmap))
                {
                    if (frameData.BlendOp == 0)
                    {
                        using var clearPaint = new SKPaint { BlendMode = SKBlendMode.Src, Color = SKColors.Transparent };
                        canvas.DrawRect(new SKRect(frameData.XOffset, frameData.YOffset, frameData.XOffset + frameData.Width, frameData.YOffset + frameData.Height), clearPaint);
                    }
                    canvas.DrawBitmap(patchBitmap, frameData.XOffset, frameData.YOffset);
                }

                SKBitmap drawBitmap = canvasBitmap;
                SKBitmap? scaledBitmap = null;
                if (canvasBitmap.Width != FrameWidth || canvasBitmap.Height != FrameHeight)
                {
                    scaledBitmap = new SKBitmap(FrameWidth, FrameHeight, canvasBitmap.ColorType, canvasBitmap.AlphaType);
                    canvasBitmap.ScalePixels(scaledBitmap, SKSamplingOptions.Default);
                    drawBitmap = scaledBitmap;

View on GitHub (pinned to ffb9cc2a85)