internal static void ConvertToCanonicalCode(ref HuffmanTable huffmanTable) { int newCode = -1; // Para compensar con el incremento inicial dentro del for debajo uint prevLength = 1; uint newCodeIndex = 0; huffmanTable.table = new List<CodeInfo>(); for (uint i = 0; i < huffmanTable.numSymbols.Length; i++) { uint codeLength = i + 1; for (uint j = 0; j < huffmanTable.numSymbols[i]; j++) { CodeInfo code = new CodeInfo(); int difLengths = (int)(codeLength - prevLength); newCode = (newCode + 1) << difLengths; prevLength = codeLength; code.code = (uint)newCode; code.length = (byte)codeLength; code.number = (ushort)huffmanTable.codes[newCodeIndex++]; huffmanTable.table.Add(code); } } huffmanTable.maxCodeLength = (byte)prevLength; }
internal static ushort ReadRunAmplitude(BitReader bReader, HuffmanTable table) { ushort code = bReader.Peek(table.maxCodeLength); CodeInfo currentCode = table.preIndexTable[code]; bReader.Read(currentCode.length); return currentCode.number; }
public static int ReadTable(BinaryReader reader, ImgInfo imgInfo) { byte tableInfo = reader.ReadByte(); byte tableId = (byte)(tableInfo & 0x7); // Low 3 bits of tableInfo int numCodes = 0; if (tableId > 3) { throw new Exception("Invalid ID for huffman table"); } if ((tableInfo & 0xe0) != 0) // High 3 bits of tableInfo must be zero { throw new Exception("Invalid huffman table"); } var huffmanTable = new HuffmanTable { id = tableId, type = (byte)((tableInfo >> 4) & 0x1), // Bit 4 of tableInfo valid = true, numSymbols = new byte[16] }; for (int i = 0; i < 16; i++) { huffmanTable.numSymbols[i] = reader.ReadByte(); numCodes += huffmanTable.numSymbols[i]; } huffmanTable.codes = new byte[numCodes]; for (int i = 0; i < numCodes; i++) { huffmanTable.codes[i] = reader.ReadByte(); } Huffman.CreateTable(ref huffmanTable); imgInfo.huffmanTables[huffmanTable.type, huffmanTable.id] = huffmanTable; return(1 + 16 + numCodes); }
public static int ReadTable(BinaryReader reader, ImgInfo imgInfo) { byte tableInfo = reader.ReadByte(); byte tableId = (byte)(tableInfo & 0x7); // Low 3 bits of tableInfo int numCodes = 0; if (tableId > 3) throw new Exception("Invalid ID for huffman table"); if ((tableInfo & 0xe0) != 0) // High 3 bits of tableInfo must be zero throw new Exception("Invalid huffman table"); var huffmanTable = new HuffmanTable(); huffmanTable.id = tableId; huffmanTable.type = (byte)((tableInfo >> 4) & 0x1); // Bit 4 of tableInfo huffmanTable.valid = true; huffmanTable.numSymbols = new byte[16]; for (int i = 0; i < 16; i++) { huffmanTable.numSymbols[i] = reader.ReadByte(); numCodes += huffmanTable.numSymbols[i]; } huffmanTable.codes = new byte[numCodes]; for (int i = 0; i < numCodes; i++) { huffmanTable.codes[i] = reader.ReadByte(); } Huffman.CreateTable(ref huffmanTable); imgInfo.huffmanTables[huffmanTable.type, huffmanTable.id] = huffmanTable; Log(reader, huffmanTable); return 1 + 16 + numCodes; }
internal static void PreparePreindexedTables(ref HuffmanTable huffmanTable) { // Codigo de datos preindizados // En esta parte, se construye una tabla de a que simbolos corresponden a cada codigo // tomando en cuenta los bits posteriores del codigo siguiente, ya que se lee del stream // un numero fijo de bits, esta misma tabla nos va a decir despues cuantos bits se van a extraer // de la lectura hecha anteriormente huffmanTable.preIndexTable = new CodeInfo[1U << huffmanTable.maxCodeLength]; foreach (var codeWord in huffmanTable.table) { int shift = huffmanTable.maxCodeLength - (int)codeWord.length; uint numCodes = 1U << shift; uint initialCode = codeWord.code << shift; for (uint nextCode = initialCode; nextCode < (numCodes + initialCode); nextCode++) { huffmanTable.preIndexTable[nextCode] = codeWord; } } }
internal static void CreateTable(ref HuffmanTable huffmanTable) { ConvertToCanonicalCode(ref huffmanTable); PreparePreindexedTables(ref huffmanTable); }
static void Log(BinaryReader reader, HuffmanTable huffmanTable) { Logger.WriteLine("Table ID: " + huffmanTable.id); Logger.WriteLine("Type: " + huffmanTable.type); Logger.WriteLine("Max code length: " + huffmanTable.maxCodeLength); Logger.WriteLine("The table itself"); Common.PrintHuffmanTable(huffmanTable.table); Logger.WriteLine("Total: " + huffmanTable.table.Count); Logger.WriteLine(); }