diff --git a/Quantum/Decompressor.cs b/Quantum/Decompressor.cs
index ea68503..2db8a9a 100644
--- a/Quantum/Decompressor.cs
+++ b/Quantum/Decompressor.cs
@@ -1,6 +1,8 @@
using System;
+using System.Collections.Generic;
using System.IO;
using SabreTools.Models.Compression.Quantum;
+using static SabreTools.Models.Compression.Quantum.Constants;
namespace SabreTools.Compression.Quantum
{
@@ -177,6 +179,80 @@ namespace SabreTools.Compression.Quantum
/// Byte array representing the decompressed data, null on error
public byte[] Process()
{
+ // Initialize the coding state
+ CS_H = 0xffff;
+ CS_L = 0x0000;
+ CS_C = (ushort)(_bitStream.ReadBitsMSB(16) ?? 0);
+
+ // Loop until the end of the stream
+ var bytes = new List();
+ while (true)
+ {
+ // Determine the selector to use
+ int selector = GetSymbol(_selector);
+
+ // Handle literal selectors
+ if (selector < 4)
+ {
+ switch (selector)
+ {
+ case 0:
+ bytes.Add((byte)GetSymbol(_model0));
+ break;
+ case 1:
+ bytes.Add((byte)GetSymbol(_model1));
+ break;
+ case 2:
+ bytes.Add((byte)GetSymbol(_model2));
+ break;
+ case 3:
+ bytes.Add((byte)GetSymbol(_model3));
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ // Handle LZ selectors
+ else
+ {
+ int offset, length;
+ switch (selector)
+ {
+ case 4:
+ int model4sym = GetSymbol(_model4);
+ int model4extra = _bitStream.ReadBitsMSB(PositionExtraBits[model4sym]);
+ offset = PositionSlot[model4sym] + model4extra + 1;
+ length = 3;
+ break;
+
+ case 5:
+ int model5sym = GetSymbol(_model5);
+ int model5extra = _bitStream.ReadBitsMSB(PositionExtraBits[model5sym]);
+ offset = PositionSlot[model5sym] + model5extra + 1;
+ length = 4;
+ break;
+
+ case 6:
+ int lengthSym = GetSymbol(_model6len);
+ int lengthExtra = _bitStream.ReadBitsMSB(LengthExtraBits[lengthSym]);
+ length = LengthSlot[lengthSym] + lengthExtra + 5;
+
+ int model6sym = GetSymbol(_model6);
+ int model6extra = _bitStream.ReadBitsMSB(PositionExtraBits[model6sym]);
+ offset = PositionSlot[model6sym] + model6extra + 1;
+ break;
+
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ // TODO: Finish implementation:
+ // - Copy data from the offsets to the lengths
+ // - Return the decoded byte array
+ }
+ }
+
throw new NotImplementedException();
}