public DecodeTable BD; // Decode bit lengths in Huffman table. public void Init() { this.LD = new DecodeTable(); this.DD = new DecodeTable(); this.LDD = new DecodeTable(); this.RD = new DecodeTable(); this.BD = new DecodeTable(); }
public DecodeTable BD; // Decode bit lengths in Huffman table. public void Init() { LD = new DecodeTable(); DD = new DecodeTable(); LDD = new DecodeTable(); RD = new DecodeTable(); BD = new DecodeTable(); }
private uint DecodeNumber(BitInput Inp, DecodeTable Dec) { // Left aligned 15 bit length raw bit field. uint BitField = Inp.getbits() & 0xfffe; if (BitField < Dec.DecodeLen[Dec.QuickBits]) { uint Code = BitField >> (int)(16 - Dec.QuickBits); Inp.addbits(Dec.QuickLen[Code]); return(Dec.QuickNum[Code]); } // Detect the real bit length for current code. uint Bits = 15; for (uint I = Dec.QuickBits + 1; I < 15; I++) { if (BitField < Dec.DecodeLen[I]) { Bits = I; break; } } Inp.addbits(Bits); // Calculate the distance from the start code for current bit length. uint Dist = BitField - Dec.DecodeLen[Bits - 1]; // Start codes are left aligned, but we need the normal right aligned // number. So we shift the distance to the right. Dist >>= (int)(16 - Bits); // Now we can calculate the position in the code list. It is the sum // of first position for current bit length and right aligned distance // between our bit field and start code for current bit length. uint Pos = Dec.DecodePos[Bits] + Dist; // Out of bounds safety check required for damaged archives. if (Pos >= Dec.MaxNum) { Pos = 0; } // Convert the position in the code list to position in alphabet // and return it. return(Dec.DecodeNum[Pos]); }
void UnpInitData20(bool Solid) { if (!Solid) { TablesRead2 = false; UnpAudioBlock = false; UnpChannelDelta = 0; UnpCurChannel = 0; UnpChannels = 1; //memset(AudV,0,sizeof(AudV)); AudV = new AudioVariables[4]; Utility.Memset(UnpOldTable20, 0, UnpOldTable20.Length); //memset(MD,0,sizeof(MD)); MD = new DecodeTable[4]; } }
private void UnpInitData20(bool Solid) { if (!Solid) { TablesRead2 = false; UnpAudioBlock = false; UnpChannelDelta = 0; UnpCurChannel = 0; UnpChannels = 1; //memset(AudV,0,sizeof(AudV)); AudV = new AudioVariables[4]; new Span <byte>(UnpOldTable20).Clear(); //memset(MD,0,sizeof(MD)); MD = new DecodeTable[4]; } }
// LengthTable contains the length in bits for every element of alphabet. // Dec is the structure to decode Huffman code/ // Size is size of length table and DecodeNum field in Dec structure, private void MakeDecodeTables(byte[] LengthTable, int offset, DecodeTable Dec, uint Size) { // Size of alphabet and DecodePos array. Dec.MaxNum = Size; // Calculate how many entries for every bit length in LengthTable we have. uint[] LengthCount = new uint[16]; //memset(LengthCount,0,sizeof(LengthCount)); for (size_t I = 0; I < Size; I++) { LengthCount[LengthTable[offset + I] & 0xf]++; } // We must not calculate the number of zero length codes. LengthCount[0] = 0; // Set the entire DecodeNum to zero. //memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum)); Utility.FillFast <ushort>(Dec.DecodeNum, 0); // Initialize not really used entry for zero length code. Dec.DecodePos[0] = 0; // Start code for bit length 1 is 0. Dec.DecodeLen[0] = 0; // Right aligned upper limit code for current bit length. uint UpperLimit = 0; for (int I = 1; I < 16; I++) { // Adjust the upper limit code. UpperLimit += LengthCount[I]; // Left aligned upper limit code. uint LeftAligned = UpperLimit << (16 - I); // Prepare the upper limit code for next bit length. UpperLimit *= 2; // Store the left aligned upper limit code. Dec.DecodeLen[I] = (uint)LeftAligned; // Every item of this array contains the sum of all preceding items. // So it contains the start position in code list for every bit length. Dec.DecodePos[I] = Dec.DecodePos[I - 1] + LengthCount[I - 1]; } // Prepare the copy of DecodePos. We'll modify this copy below, // so we cannot use the original DecodePos. uint[] CopyDecodePos = new uint[Dec.DecodePos.Length]; //memcpy(CopyDecodePos,Dec->DecodePos,sizeof(CopyDecodePos)); Array.Copy(Dec.DecodePos, 0, CopyDecodePos, 0, CopyDecodePos.Length); // For every bit length in the bit length table and so for every item // of alphabet. for (uint I = 0; I < Size; I++) { // Get the current bit length. byte _CurBitLength = (byte)(LengthTable[offset + I] & 0xf); if (_CurBitLength != 0) { // Last position in code list for current bit length. uint LastPos = CopyDecodePos[_CurBitLength]; // Prepare the decode table, so this position in code list will be // decoded to current alphabet item number. Dec.DecodeNum[LastPos] = (ushort)I; // We'll use next position number for this bit length next time. // So we pass through the entire range of positions available // for every bit length. CopyDecodePos[_CurBitLength]++; } } // Define the number of bits to process in quick mode. We use more bits // for larger alphabets. More bits means that more codes will be processed // in quick mode, but also that more time will be spent to preparation // of tables for quick decode. switch (Size) { case NC: case NC20: case NC30: Dec.QuickBits = MAX_QUICK_DECODE_BITS; break; default: Dec.QuickBits = MAX_QUICK_DECODE_BITS - 3; break; } // Size of tables for quick mode. uint QuickDataSize = 1U << (int)Dec.QuickBits; // Bit length for current code, start from 1 bit codes. It is important // to use 1 bit instead of 0 for minimum code length, so we are moving // forward even when processing a corrupt archive. //uint CurBitLength=1; byte CurBitLength = 1; // For every right aligned bit string which supports the quick decoding. for (uint Code = 0; Code < QuickDataSize; Code++) { // Left align the current code, so it will be in usual bit field format. uint BitField = Code << (int)(16 - Dec.QuickBits); // Prepare the table for quick decoding of bit lengths. // Find the upper limit for current bit field and adjust the bit length // accordingly if necessary. while (CurBitLength < Dec.DecodeLen.Length && BitField >= Dec.DecodeLen[CurBitLength]) { CurBitLength++; } // Translation of right aligned bit string to bit length. Dec.QuickLen[Code] = CurBitLength; // Prepare the table for quick translation of position in code list // to position in alphabet. // Calculate the distance from the start code for current bit length. uint Dist = BitField - Dec.DecodeLen[CurBitLength - 1]; // Right align the distance. Dist >>= (16 - CurBitLength); // Now we can calculate the position in the code list. It is the sum // of first position for current bit length and right aligned distance // between our bit field and start code for current bit length. uint Pos; if (CurBitLength < Dec.DecodePos.Length && (Pos = Dec.DecodePos[CurBitLength] + Dist) < Size) { // Define the code to alphabet number translation. Dec.QuickNum[Code] = Dec.DecodeNum[Pos]; } else { // Can be here for length table filled with zeroes only (empty). Dec.QuickNum[Code] = 0; } } }