diff --git a/BurnOutSharp.Compression/Quantum/Decompressor.cs b/BurnOutSharp.Compression/Quantum/Decompressor.cs
index 312b48b6..5fbec73f 100644
--- a/BurnOutSharp.Compression/Quantum/Decompressor.cs
+++ b/BurnOutSharp.Compression/Quantum/Decompressor.cs
@@ -402,8 +402,7 @@ namespace BurnOutSharp.Compression.Quantum
///
private static ushort GET_SYMBOL(Model model, ref ushort H, ref ushort L, ref ushort C, byte[] inbuf, ref int inpos, ref int bitsleft, ref uint bitbuf)
{
- uint range = (uint)(((H - L) & 0xFFFF) + 1);
- ushort symf = (ushort)(((((C - L + 1) * model.Symbols[0].CumulativeFrequency) - 1) / range) & 0xFFFF);
+ ushort symf = GetFrequency(model.Symbols[0].CumulativeFrequency, H, L, C);
int i;
for (i = 1; i < model.Entries; i++)
@@ -413,39 +412,63 @@ namespace BurnOutSharp.Compression.Quantum
}
ushort symbol = model.Symbols[i - 1].Symbol;
-
- range = (uint)(H - L + 1);
- H = (ushort)(L + ((model.Symbols[i - 1].CumulativeFrequency * range) / model.Symbols[0].CumulativeFrequency) - 1);
- L = (ushort)(L + ((model.Symbols[i].CumulativeFrequency * range) / model.Symbols[0].CumulativeFrequency));
-
- while (true)
- {
- if ((L & 0x8000) != (H & 0x8000))
- {
- // Underflow case
- if ((L & 0x4000) != 0 && (H & 0x4000) == 0)
- {
- C ^= 0x4000;
- L &= 0x3FFF;
- H |= 0x4000;
- }
- else
- {
- break;
- }
- }
-
- L <<= 1;
- H = (ushort)((H << 1) | 1);
- Q_FILL_BUFFER(inbuf, ref inpos, ref bitsleft, ref bitbuf);
- C = (ushort)((C << 1) | Q_PEEK_BITS(1, bitbuf));
- Q_REMOVE_BITS(1, ref bitsleft, ref bitbuf);
- }
+ GetCode(model.Symbols[i - 1].CumulativeFrequency,
+ model.Symbols[i].CumulativeFrequency,
+ model.Symbols[0].CumulativeFrequency,
+ ref H, ref L, ref C,
+ inbuf, ref inpos, ref bitsleft, ref bitbuf);
UpdateModel(model, i);
return symbol;
}
+ ///
+ /// Get the frequency for a given range and total frequency
+ ///
+ private static ushort GetFrequency(ushort totalFrequency, ushort H, ushort L, ushort C)
+ {
+ uint range = (uint)(((H - L) & 0xFFFF) + 1);
+ uint freq = (uint)(((C - L + 1) * totalFrequency - 1) / range);
+ return (ushort)(freq & 0xFFFF);
+ }
+
+ ///
+ /// The decoder renormalization loop
+ ///
+ private static void GetCode(int previousFrequency,
+ int cumulativeFrequency,
+ int totalFrequency,
+ ref ushort H,
+ ref ushort L,
+ ref ushort C,
+ byte[] inbuf,
+ ref int inpos,
+ ref int bitsleft,
+ ref uint bitbuf)
+ {
+ uint range = (uint)((H - L) + 1);
+ H = (ushort)(L + ((previousFrequency * range) / totalFrequency) - 1);
+ L = (ushort)(L + (cumulativeFrequency * range) / totalFrequency);
+
+ while (true)
+ {
+ if ((L & 0x8000) != (H & 0x8000))
+ {
+ if ((L & 0x4000) == 0 || (H & 0x4000) != 0)
+ break;
+
+ // Underflow case
+ C ^= 0x4000;
+ L &= 0x3FFF;
+ H |= 0x4000;
+ }
+
+ L <<= 1;
+ H = (ushort)((H << 1) | 1);
+ C = (ushort)((C << 1) | Q_READ_BITS(1, inbuf, ref inpos, ref bitsleft, ref bitbuf));
+ }
+ }
+
#endregion
}
}
\ No newline at end of file