Graphics: Move Gal/Texture to Texture

This commit is contained in:
ReinUsesLisp 2018-09-02 23:57:01 -03:00
commit 85ad59c40e
5 changed files with 1913 additions and 1912 deletions

View file

@ -1,5 +1,5 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.Gal.Texture; using Ryujinx.Graphics.Texture;
using System; using System;
namespace Ryujinx.Graphics.Gal.OpenGL namespace Ryujinx.Graphics.Gal.OpenGL

View file

@ -1,138 +1,138 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
namespace Ryujinx.Graphics.Gal.Texture namespace Ryujinx.Graphics.Texture
{ {
class ASTCPixel class ASTCPixel
{ {
public short R { get; set; } public short R { get; set; }
public short G { get; set; } public short G { get; set; }
public short B { get; set; } public short B { get; set; }
public short A { get; set; } public short A { get; set; }
byte[] BitDepth = new byte[4]; byte[] BitDepth = new byte[4];
public ASTCPixel(short _A, short _R, short _G, short _B) public ASTCPixel(short _A, short _R, short _G, short _B)
{ {
A = _A; A = _A;
R = _R; R = _R;
G = _G; G = _G;
B = _B; B = _B;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
BitDepth[i] = 8; BitDepth[i] = 8;
} }
public void ClampByte() public void ClampByte()
{ {
R = Math.Min(Math.Max(R, (short)0), (short)255); R = Math.Min(Math.Max(R, (short)0), (short)255);
G = Math.Min(Math.Max(G, (short)0), (short)255); G = Math.Min(Math.Max(G, (short)0), (short)255);
B = Math.Min(Math.Max(B, (short)0), (short)255); B = Math.Min(Math.Max(B, (short)0), (short)255);
A = Math.Min(Math.Max(A, (short)0), (short)255); A = Math.Min(Math.Max(A, (short)0), (short)255);
} }
public short GetComponent(int Index) public short GetComponent(int Index)
{ {
switch(Index) switch(Index)
{ {
case 0: return A; case 0: return A;
case 1: return R; case 1: return R;
case 2: return G; case 2: return G;
case 3: return B; case 3: return B;
} }
return 0; return 0;
} }
public void SetComponent(int Index, int Value) public void SetComponent(int Index, int Value)
{ {
switch (Index) switch (Index)
{ {
case 0: case 0:
A = (short)Value; A = (short)Value;
break; break;
case 1: case 1:
R = (short)Value; R = (short)Value;
break; break;
case 2: case 2:
G = (short)Value; G = (short)Value;
break; break;
case 3: case 3:
B = (short)Value; B = (short)Value;
break; break;
} }
} }
public void ChangeBitDepth(byte[] Depth) public void ChangeBitDepth(byte[] Depth)
{ {
for(int i = 0; i< 4; i++) for(int i = 0; i< 4; i++)
{ {
int Value = ChangeBitDepth(GetComponent(i), BitDepth[i], Depth[i]); int Value = ChangeBitDepth(GetComponent(i), BitDepth[i], Depth[i]);
SetComponent(i, Value); SetComponent(i, Value);
BitDepth[i] = Depth[i]; BitDepth[i] = Depth[i];
} }
} }
short ChangeBitDepth(short Value, byte OldDepth, byte NewDepth) short ChangeBitDepth(short Value, byte OldDepth, byte NewDepth)
{ {
Debug.Assert(NewDepth <= 8); Debug.Assert(NewDepth <= 8);
Debug.Assert(OldDepth <= 8); Debug.Assert(OldDepth <= 8);
if (OldDepth == NewDepth) if (OldDepth == NewDepth)
{ {
// Do nothing // Do nothing
return Value; return Value;
} }
else if (OldDepth == 0 && NewDepth != 0) else if (OldDepth == 0 && NewDepth != 0)
{ {
return (short)((1 << NewDepth) - 1); return (short)((1 << NewDepth) - 1);
} }
else if (NewDepth > OldDepth) else if (NewDepth > OldDepth)
{ {
return (short)BitArrayStream.Replicate(Value, OldDepth, NewDepth); return (short)BitArrayStream.Replicate(Value, OldDepth, NewDepth);
} }
else else
{ {
// oldDepth > newDepth // oldDepth > newDepth
if (NewDepth == 0) if (NewDepth == 0)
{ {
return 0xFF; return 0xFF;
} }
else else
{ {
byte BitsWasted = (byte)(OldDepth - NewDepth); byte BitsWasted = (byte)(OldDepth - NewDepth);
short TempValue = Value; short TempValue = Value;
TempValue = (short)((TempValue + (1 << (BitsWasted - 1))) >> BitsWasted); TempValue = (short)((TempValue + (1 << (BitsWasted - 1))) >> BitsWasted);
TempValue = Math.Min(Math.Max((short)0, TempValue), (short)((1 << NewDepth) - 1)); TempValue = Math.Min(Math.Max((short)0, TempValue), (short)((1 << NewDepth) - 1));
return (byte)(TempValue); return (byte)(TempValue);
} }
} }
} }
public int Pack() public int Pack()
{ {
ASTCPixel NewPixel = new ASTCPixel(A, R, G, B); ASTCPixel NewPixel = new ASTCPixel(A, R, G, B);
byte[] eightBitDepth = { 8, 8, 8, 8 }; byte[] eightBitDepth = { 8, 8, 8, 8 };
NewPixel.ChangeBitDepth(eightBitDepth); NewPixel.ChangeBitDepth(eightBitDepth);
return (byte)NewPixel.A << 24 | return (byte)NewPixel.A << 24 |
(byte)NewPixel.B << 16 | (byte)NewPixel.B << 16 |
(byte)NewPixel.G << 8 | (byte)NewPixel.G << 8 |
(byte)NewPixel.R << 0; (byte)NewPixel.R << 0;
} }
// Adds more precision to the blue channel as described // Adds more precision to the blue channel as described
// in C.2.14 // in C.2.14
public static ASTCPixel BlueContract(int a, int r, int g, int b) public static ASTCPixel BlueContract(int a, int r, int g, int b)
{ {
return new ASTCPixel((short)(a), return new ASTCPixel((short)(a),
(short)((r + b) >> 1), (short)((r + b) >> 1),
(short)((g + b) >> 1), (short)((g + b) >> 1),
(short)(b)); (short)(b));
} }
} }
} }

View file

@ -1,120 +1,121 @@
using System; using System;
using System.Collections; using System.Collections;
namespace Ryujinx.Graphics.Gal.Texture namespace Ryujinx.Graphics.Texture
{ {
public class BitArrayStream public class BitArrayStream
{ {
public BitArray BitsArray; public BitArray BitsArray;
public int Position { get; private set; }
public int Position { get; private set; }
public BitArrayStream(BitArray BitArray)
{ public BitArrayStream(BitArray BitArray)
BitsArray = BitArray; {
Position = 0; BitsArray = BitArray;
} Position = 0;
}
public short ReadBits(int Length)
{ public short ReadBits(int Length)
int RetValue = 0; {
for (int i = Position; i < Position + Length; i++) int RetValue = 0;
{ for (int i = Position; i < Position + Length; i++)
if (BitsArray[i]) {
{ if (BitsArray[i])
RetValue |= 1 << (i - Position); {
} RetValue |= 1 << (i - Position);
} }
}
Position += Length;
return (short)RetValue; Position += Length;
} return (short)RetValue;
}
public int ReadBits(int Start, int End)
{ public int ReadBits(int Start, int End)
int RetValue = 0; {
for (int i = Start; i <= End; i++) int RetValue = 0;
{ for (int i = Start; i <= End; i++)
if (BitsArray[i]) {
{ if (BitsArray[i])
RetValue |= 1 << (i - Start); {
} RetValue |= 1 << (i - Start);
} }
}
return RetValue;
} return RetValue;
}
public int ReadBit(int Index)
{ public int ReadBit(int Index)
return Convert.ToInt32(BitsArray[Index]); {
} return Convert.ToInt32(BitsArray[Index]);
}
public void WriteBits(int Value, int Length)
{ public void WriteBits(int Value, int Length)
for (int i = Position; i < Position + Length; i++) {
{ for (int i = Position; i < Position + Length; i++)
BitsArray[i] = ((Value >> (i - Position)) & 1) != 0; {
} BitsArray[i] = ((Value >> (i - Position)) & 1) != 0;
}
Position += Length;
} Position += Length;
}
public byte[] ToByteArray()
{ public byte[] ToByteArray()
byte[] RetArray = new byte[(BitsArray.Length + 7) / 8]; {
BitsArray.CopyTo(RetArray, 0); byte[] RetArray = new byte[(BitsArray.Length + 7) / 8];
return RetArray; BitsArray.CopyTo(RetArray, 0);
} return RetArray;
}
public static int Replicate(int Value, int NumberBits, int ToBit)
{ public static int Replicate(int Value, int NumberBits, int ToBit)
if (NumberBits == 0) return 0; {
if (ToBit == 0) return 0; if (NumberBits == 0) return 0;
if (ToBit == 0) return 0;
int TempValue = Value & ((1 << NumberBits) - 1);
int RetValue = TempValue; int TempValue = Value & ((1 << NumberBits) - 1);
int ResLength = NumberBits; int RetValue = TempValue;
int ResLength = NumberBits;
while (ResLength < ToBit)
{ while (ResLength < ToBit)
int Comp = 0; {
if (NumberBits > ToBit - ResLength) int Comp = 0;
{ if (NumberBits > ToBit - ResLength)
int NewShift = ToBit - ResLength; {
Comp = NumberBits - NewShift; int NewShift = ToBit - ResLength;
NumberBits = NewShift; Comp = NumberBits - NewShift;
} NumberBits = NewShift;
RetValue <<= NumberBits; }
RetValue |= TempValue >> Comp; RetValue <<= NumberBits;
ResLength += NumberBits; RetValue |= TempValue >> Comp;
} ResLength += NumberBits;
return RetValue; }
} return RetValue;
}
public static int PopCnt(int Number)
{ public static int PopCnt(int Number)
int Counter; {
for (Counter = 0; Number != 0; Counter++) int Counter;
{ for (Counter = 0; Number != 0; Counter++)
Number &= Number - 1; {
} Number &= Number - 1;
return Counter; }
} return Counter;
}
public static void Swap<T>(ref T lhs, ref T rhs)
{ public static void Swap<T>(ref T lhs, ref T rhs)
T Temp = lhs; {
lhs = rhs; T Temp = lhs;
rhs = Temp; lhs = rhs;
} rhs = Temp;
}
// Transfers a bit as described in C.2.14
public static void BitTransferSigned(ref int a, ref int b) // Transfers a bit as described in C.2.14
{ public static void BitTransferSigned(ref int a, ref int b)
b >>= 1; {
b |= a & 0x80; b >>= 1;
a >>= 1; b |= a & 0x80;
a &= 0x3F; a >>= 1;
if ((a & 0x20) != 0) a -= 0x40; a &= 0x3F;
} if ((a & 0x20) != 0) a -= 0x40;
} }
} }
}

View file

@ -1,269 +1,269 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
namespace Ryujinx.Graphics.Gal.Texture namespace Ryujinx.Graphics.Texture
{ {
public struct IntegerEncoded public struct IntegerEncoded
{ {
public enum EIntegerEncoding public enum EIntegerEncoding
{ {
JustBits, JustBits,
Quint, Quint,
Trit Trit
} }
EIntegerEncoding Encoding; EIntegerEncoding Encoding;
public int NumberBits { get; private set; } public int NumberBits { get; private set; }
public int BitValue { get; private set; } public int BitValue { get; private set; }
public int TritValue { get; private set; } public int TritValue { get; private set; }
public int QuintValue { get; private set; } public int QuintValue { get; private set; }
public IntegerEncoded(EIntegerEncoding _Encoding, int NumBits) public IntegerEncoded(EIntegerEncoding _Encoding, int NumBits)
{ {
Encoding = _Encoding; Encoding = _Encoding;
NumberBits = NumBits; NumberBits = NumBits;
BitValue = 0; BitValue = 0;
TritValue = 0; TritValue = 0;
QuintValue = 0; QuintValue = 0;
} }
public bool MatchesEncoding(IntegerEncoded Other) public bool MatchesEncoding(IntegerEncoded Other)
{ {
return Encoding == Other.Encoding && NumberBits == Other.NumberBits; return Encoding == Other.Encoding && NumberBits == Other.NumberBits;
} }
public EIntegerEncoding GetEncoding() public EIntegerEncoding GetEncoding()
{ {
return Encoding; return Encoding;
} }
public int GetBitLength(int NumberVals) public int GetBitLength(int NumberVals)
{ {
int TotalBits = NumberBits * NumberVals; int TotalBits = NumberBits * NumberVals;
if (Encoding == EIntegerEncoding.Trit) if (Encoding == EIntegerEncoding.Trit)
{ {
TotalBits += (NumberVals * 8 + 4) / 5; TotalBits += (NumberVals * 8 + 4) / 5;
} }
else if (Encoding == EIntegerEncoding.Quint) else if (Encoding == EIntegerEncoding.Quint)
{ {
TotalBits += (NumberVals * 7 + 2) / 3; TotalBits += (NumberVals * 7 + 2) / 3;
} }
return TotalBits; return TotalBits;
} }
public static IntegerEncoded CreateEncoding(int MaxVal) public static IntegerEncoded CreateEncoding(int MaxVal)
{ {
while (MaxVal > 0) while (MaxVal > 0)
{ {
int Check = MaxVal + 1; int Check = MaxVal + 1;
// Is maxVal a power of two? // Is maxVal a power of two?
if ((Check & (Check - 1)) == 0) if ((Check & (Check - 1)) == 0)
{ {
return new IntegerEncoded(EIntegerEncoding.JustBits, BitArrayStream.PopCnt(MaxVal)); return new IntegerEncoded(EIntegerEncoding.JustBits, BitArrayStream.PopCnt(MaxVal));
} }
// Is maxVal of the type 3*2^n - 1? // Is maxVal of the type 3*2^n - 1?
if ((Check % 3 == 0) && ((Check / 3) & ((Check / 3) - 1)) == 0) if ((Check % 3 == 0) && ((Check / 3) & ((Check / 3) - 1)) == 0)
{ {
return new IntegerEncoded(EIntegerEncoding.Trit, BitArrayStream.PopCnt(Check / 3 - 1)); return new IntegerEncoded(EIntegerEncoding.Trit, BitArrayStream.PopCnt(Check / 3 - 1));
} }
// Is maxVal of the type 5*2^n - 1? // Is maxVal of the type 5*2^n - 1?
if ((Check % 5 == 0) && ((Check / 5) & ((Check / 5) - 1)) == 0) if ((Check % 5 == 0) && ((Check / 5) & ((Check / 5) - 1)) == 0)
{ {
return new IntegerEncoded(EIntegerEncoding.Quint, BitArrayStream.PopCnt(Check / 5 - 1)); return new IntegerEncoded(EIntegerEncoding.Quint, BitArrayStream.PopCnt(Check / 5 - 1));
} }
// Apparently it can't be represented with a bounded integer sequence... // Apparently it can't be represented with a bounded integer sequence...
// just iterate. // just iterate.
MaxVal--; MaxVal--;
} }
return new IntegerEncoded(EIntegerEncoding.JustBits, 0); return new IntegerEncoded(EIntegerEncoding.JustBits, 0);
} }
public static void DecodeTritBlock( public static void DecodeTritBlock(
BitArrayStream BitStream, BitArrayStream BitStream,
List<IntegerEncoded> ListIntegerEncoded, List<IntegerEncoded> ListIntegerEncoded,
int NumberBitsPerValue) int NumberBitsPerValue)
{ {
// Implement the algorithm in section C.2.12 // Implement the algorithm in section C.2.12
int[] m = new int[5]; int[] m = new int[5];
int[] t = new int[5]; int[] t = new int[5];
int T; int T;
// Read the trit encoded block according to // Read the trit encoded block according to
// table C.2.14 // table C.2.14
m[0] = BitStream.ReadBits(NumberBitsPerValue); m[0] = BitStream.ReadBits(NumberBitsPerValue);
T = BitStream.ReadBits(2); T = BitStream.ReadBits(2);
m[1] = BitStream.ReadBits(NumberBitsPerValue); m[1] = BitStream.ReadBits(NumberBitsPerValue);
T |= BitStream.ReadBits(2) << 2; T |= BitStream.ReadBits(2) << 2;
m[2] = BitStream.ReadBits(NumberBitsPerValue); m[2] = BitStream.ReadBits(NumberBitsPerValue);
T |= BitStream.ReadBits(1) << 4; T |= BitStream.ReadBits(1) << 4;
m[3] = BitStream.ReadBits(NumberBitsPerValue); m[3] = BitStream.ReadBits(NumberBitsPerValue);
T |= BitStream.ReadBits(2) << 5; T |= BitStream.ReadBits(2) << 5;
m[4] = BitStream.ReadBits(NumberBitsPerValue); m[4] = BitStream.ReadBits(NumberBitsPerValue);
T |= BitStream.ReadBits(1) << 7; T |= BitStream.ReadBits(1) << 7;
int C = 0; int C = 0;
BitArrayStream Tb = new BitArrayStream(new BitArray(new int[] { T })); BitArrayStream Tb = new BitArrayStream(new BitArray(new int[] { T }));
if (Tb.ReadBits(2, 4) == 7) if (Tb.ReadBits(2, 4) == 7)
{ {
C = (Tb.ReadBits(5, 7) << 2) | Tb.ReadBits(0, 1); C = (Tb.ReadBits(5, 7) << 2) | Tb.ReadBits(0, 1);
t[4] = t[3] = 2; t[4] = t[3] = 2;
} }
else else
{ {
C = Tb.ReadBits(0, 4); C = Tb.ReadBits(0, 4);
if (Tb.ReadBits(5, 6) == 3) if (Tb.ReadBits(5, 6) == 3)
{ {
t[4] = 2; t[4] = 2;
t[3] = Tb.ReadBit(7); t[3] = Tb.ReadBit(7);
} }
else else
{ {
t[4] = Tb.ReadBit(7); t[4] = Tb.ReadBit(7);
t[3] = Tb.ReadBits(5, 6); t[3] = Tb.ReadBits(5, 6);
} }
} }
BitArrayStream Cb = new BitArrayStream(new BitArray(new int[] { C })); BitArrayStream Cb = new BitArrayStream(new BitArray(new int[] { C }));
if (Cb.ReadBits(0, 1) == 3) if (Cb.ReadBits(0, 1) == 3)
{ {
t[2] = 2; t[2] = 2;
t[1] = Cb.ReadBit(4); t[1] = Cb.ReadBit(4);
t[0] = (Cb.ReadBit(3) << 1) | (Cb.ReadBit(2) & ~Cb.ReadBit(3)); t[0] = (Cb.ReadBit(3) << 1) | (Cb.ReadBit(2) & ~Cb.ReadBit(3));
} }
else if (Cb.ReadBits(2, 3) == 3) else if (Cb.ReadBits(2, 3) == 3)
{ {
t[2] = 2; t[2] = 2;
t[1] = 2; t[1] = 2;
t[0] = Cb.ReadBits(0, 1); t[0] = Cb.ReadBits(0, 1);
} }
else else
{ {
t[2] = Cb.ReadBit(4); t[2] = Cb.ReadBit(4);
t[1] = Cb.ReadBits(2, 3); t[1] = Cb.ReadBits(2, 3);
t[0] = (Cb.ReadBit(1) << 1) | (Cb.ReadBit(0) & ~Cb.ReadBit(1)); t[0] = (Cb.ReadBit(1) << 1) | (Cb.ReadBit(0) & ~Cb.ReadBit(1));
} }
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
IntegerEncoded IntEncoded = new IntegerEncoded(EIntegerEncoding.Trit, NumberBitsPerValue) IntegerEncoded IntEncoded = new IntegerEncoded(EIntegerEncoding.Trit, NumberBitsPerValue)
{ {
BitValue = m[i], BitValue = m[i],
TritValue = t[i] TritValue = t[i]
}; };
ListIntegerEncoded.Add(IntEncoded); ListIntegerEncoded.Add(IntEncoded);
} }
} }
public static void DecodeQuintBlock( public static void DecodeQuintBlock(
BitArrayStream BitStream, BitArrayStream BitStream,
List<IntegerEncoded> ListIntegerEncoded, List<IntegerEncoded> ListIntegerEncoded,
int NumberBitsPerValue) int NumberBitsPerValue)
{ {
// Implement the algorithm in section C.2.12 // Implement the algorithm in section C.2.12
int[] m = new int[3]; int[] m = new int[3];
int[] q = new int[3]; int[] q = new int[3];
int Q; int Q;
// Read the trit encoded block according to // Read the trit encoded block according to
// table C.2.15 // table C.2.15
m[0] = BitStream.ReadBits(NumberBitsPerValue); m[0] = BitStream.ReadBits(NumberBitsPerValue);
Q = BitStream.ReadBits(3); Q = BitStream.ReadBits(3);
m[1] = BitStream.ReadBits(NumberBitsPerValue); m[1] = BitStream.ReadBits(NumberBitsPerValue);
Q |= BitStream.ReadBits(2) << 3; Q |= BitStream.ReadBits(2) << 3;
m[2] = BitStream.ReadBits(NumberBitsPerValue); m[2] = BitStream.ReadBits(NumberBitsPerValue);
Q |= BitStream.ReadBits(2) << 5; Q |= BitStream.ReadBits(2) << 5;
BitArrayStream Qb = new BitArrayStream(new BitArray(new int[] { Q })); BitArrayStream Qb = new BitArrayStream(new BitArray(new int[] { Q }));
if (Qb.ReadBits(1, 2) == 3 && Qb.ReadBits(5, 6) == 0) if (Qb.ReadBits(1, 2) == 3 && Qb.ReadBits(5, 6) == 0)
{ {
q[0] = q[1] = 4; q[0] = q[1] = 4;
q[2] = (Qb.ReadBit(0) << 2) | ((Qb.ReadBit(4) & ~Qb.ReadBit(0)) << 1) | (Qb.ReadBit(3) & ~Qb.ReadBit(0)); q[2] = (Qb.ReadBit(0) << 2) | ((Qb.ReadBit(4) & ~Qb.ReadBit(0)) << 1) | (Qb.ReadBit(3) & ~Qb.ReadBit(0));
} }
else else
{ {
int C = 0; int C = 0;
if (Qb.ReadBits(1, 2) == 3) if (Qb.ReadBits(1, 2) == 3)
{ {
q[2] = 4; q[2] = 4;
C = (Qb.ReadBits(3, 4) << 3) | ((~Qb.ReadBits(5, 6) & 3) << 1) | Qb.ReadBit(0); C = (Qb.ReadBits(3, 4) << 3) | ((~Qb.ReadBits(5, 6) & 3) << 1) | Qb.ReadBit(0);
} }
else else
{ {
q[2] = Qb.ReadBits(5, 6); q[2] = Qb.ReadBits(5, 6);
C = Qb.ReadBits(0, 4); C = Qb.ReadBits(0, 4);
} }
BitArrayStream Cb = new BitArrayStream(new BitArray(new int[] { C })); BitArrayStream Cb = new BitArrayStream(new BitArray(new int[] { C }));
if (Cb.ReadBits(0, 2) == 5) if (Cb.ReadBits(0, 2) == 5)
{ {
q[1] = 4; q[1] = 4;
q[0] = Cb.ReadBits(3, 4); q[0] = Cb.ReadBits(3, 4);
} }
else else
{ {
q[1] = Cb.ReadBits(3, 4); q[1] = Cb.ReadBits(3, 4);
q[0] = Cb.ReadBits(0, 2); q[0] = Cb.ReadBits(0, 2);
} }
} }
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
IntegerEncoded IntEncoded = new IntegerEncoded(EIntegerEncoding.Quint, NumberBitsPerValue) IntegerEncoded IntEncoded = new IntegerEncoded(EIntegerEncoding.Quint, NumberBitsPerValue)
{ {
BitValue = m[i], BitValue = m[i],
QuintValue = q[i] QuintValue = q[i]
}; };
ListIntegerEncoded.Add(IntEncoded); ListIntegerEncoded.Add(IntEncoded);
} }
} }
public static void DecodeIntegerSequence( public static void DecodeIntegerSequence(
List<IntegerEncoded> DecodeIntegerSequence, List<IntegerEncoded> DecodeIntegerSequence,
BitArrayStream BitStream, BitArrayStream BitStream,
int MaxRange, int MaxRange,
int NumberValues) int NumberValues)
{ {
// Determine encoding parameters // Determine encoding parameters
IntegerEncoded IntEncoded = CreateEncoding(MaxRange); IntegerEncoded IntEncoded = CreateEncoding(MaxRange);
// Start decoding // Start decoding
int NumberValuesDecoded = 0; int NumberValuesDecoded = 0;
while (NumberValuesDecoded < NumberValues) while (NumberValuesDecoded < NumberValues)
{ {
switch (IntEncoded.GetEncoding()) switch (IntEncoded.GetEncoding())
{ {
case EIntegerEncoding.Quint: case EIntegerEncoding.Quint:
{ {
DecodeQuintBlock(BitStream, DecodeIntegerSequence, IntEncoded.NumberBits); DecodeQuintBlock(BitStream, DecodeIntegerSequence, IntEncoded.NumberBits);
NumberValuesDecoded += 3; NumberValuesDecoded += 3;
break; break;
} }
case EIntegerEncoding.Trit: case EIntegerEncoding.Trit:
{ {
DecodeTritBlock(BitStream, DecodeIntegerSequence, IntEncoded.NumberBits); DecodeTritBlock(BitStream, DecodeIntegerSequence, IntEncoded.NumberBits);
NumberValuesDecoded += 5; NumberValuesDecoded += 5;
break; break;
} }
case EIntegerEncoding.JustBits: case EIntegerEncoding.JustBits:
{ {
IntEncoded.BitValue = BitStream.ReadBits(IntEncoded.NumberBits); IntEncoded.BitValue = BitStream.ReadBits(IntEncoded.NumberBits);
DecodeIntegerSequence.Add(IntEncoded); DecodeIntegerSequence.Add(IntEncoded);
NumberValuesDecoded++; NumberValuesDecoded++;
break; break;
} }
} }
} }
} }
} }
} }