diff --git a/src/ImageSharp/Formats/WebP/AlphaDecoder.cs b/src/ImageSharp/Formats/WebP/AlphaDecoder.cs
new file mode 100644
index 000000000..92a2c0156
--- /dev/null
+++ b/src/ImageSharp/Formats/WebP/AlphaDecoder.cs
@@ -0,0 +1,63 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+
+namespace SixLabors.ImageSharp.Formats.WebP
+{
+ internal ref struct AlphaDecoder
+ {
+ public int Width { get; set; }
+
+ public int Height { get; set; }
+
+ public int Method { get; set; }
+
+ public WebPFilterBase Filter { get; set; }
+
+ public int PreProcessing { get; set; }
+
+ public Vp8LDecoder Vp8LDec { get; set; }
+
+ public Vp8Io Io { get; set; }
+
+ ///
+ /// Although Alpha Channel requires only 1 byte per pixel,
+ /// sometimes Vp8LDecoder may need to allocate
+ /// 4 bytes per pixel internally during decode.
+ ///
+ public bool Use8BDecode { get; set; }
+
+ // last output row (or null)
+ private Span PrevLine { get; set; }
+
+ private int PrevLineOffset { get; set; }
+
+ // Taken from vp8l_dec.c AlphaApplyFilter
+ public void AlphaApplyFilter(
+ int firstRow, int lastRow,
+ Span output, int outputOffset,
+ int stride)
+ {
+ if (!(this.Filter is WebPFilterNone))
+ {
+ Span prevLine = this.PrevLine;
+ int prevLineOffset = this.PrevLineOffset;
+
+ for (int y = firstRow; y < lastRow; y++)
+ {
+ this.Filter
+ .Unfilter(
+ prevLine, prevLineOffset,
+ output, outputOffset,
+ output, outputOffset,
+ stride);
+ prevLineOffset = outputOffset;
+ outputOffset += stride;
+ }
+
+ this.PrevLine = prevLine;
+ }
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/WebP/Vp8Io.cs b/src/ImageSharp/Formats/WebP/Vp8Io.cs
new file mode 100644
index 000000000..f1ab5c749
--- /dev/null
+++ b/src/ImageSharp/Formats/WebP/Vp8Io.cs
@@ -0,0 +1,70 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+
+namespace SixLabors.ImageSharp.Formats.WebP
+{
+ // from
+ public ref struct Vp8Io
+ {
+ ///
+ /// Picture Width in pixels (invariable).
+ /// Original, uncropped dimensions.
+ /// The actual area passed to put() is stored in /> field.
+ ///
+ public int Width { get; set; }
+
+ ///
+ /// Picture Width in pixels (invariable).
+ /// Original, uncropped dimensions.
+ /// The actual area passed to put() is stored in /> field.
+ ///
+ public int Height { get; set; }
+
+ ///
+ /// Position of the current Rows (in pixels)
+ ///
+ public int MbY { get; set; }
+
+ ///
+ /// number of columns in the sample
+ ///
+ public int MbW { get; set; }
+
+ ///
+ /// Number of Rows in the sample
+ ///
+ public int MbH { get; set; }
+
+ ///
+ /// Rows to copy (in YUV format)
+ ///
+ private Span Y { get; set; }
+
+ ///
+ /// Rows to copy (in YUV format)
+ ///
+ private Span U { get; set; }
+
+ ///
+ /// Rows to copy (in YUV format)
+ ///
+ private Span V { get; set; }
+
+ ///
+ /// Row stride for luma
+ ///
+ public int YStride { get; set; }
+
+ ///
+ /// Row stride for chroma
+ ///
+ public int UvStride { get; set; }
+
+ ///
+ /// User data
+ ///
+ private object Opaque { get; set; }
+ }
+}