public override HuffLeafNode Insert(int code, int desiredDepth) { if (desiredDepth > 1) { if (Zero == null) Zero = new HuffInternalNode() { Parent = this }; HuffLeafNode h = Zero.Insert(code, desiredDepth-1); if (h != null) return h; if (One == null) One = new HuffInternalNode() { Parent = this }; h = One.Insert(code, desiredDepth-1); if (h != null) return h; return null; } else if (desiredDepth == 1) { if (Zero != null && One != null) return null; HuffLeafNode leaf = new HuffLeafNode() { Parent=this, Code = code }; if (Zero == null) Zero = leaf; else One = leaf; return leaf; } else throw new ArgumentOutOfRangeException("desiredDepth"); }
private HuffInternalNode ReadHuffman(int entries, BitReader r) { bool ordered = r.ReadBit(); //Console.WriteLine(" Ordered: {0}", ordered ? 1 : 0); int[] codewordLengths = new int[entries]; bool[] codewordUsed = new bool[entries]; if (!ordered) { bool sparse = r.ReadBit(); //Console.WriteLine(" Sparse: {0}", sparse ? 1 : 0); for (int i = 0; i < entries; ++i) { if (sparse) { if (r.ReadBit()) { codewordLengths[i] = (int)r.ReadUnsigned(5) + 1; codewordUsed[i] = true; } } else { codewordLengths[i] = (int)r.ReadUnsigned(5) + 1; codewordUsed[i] = true; } } } else { int currentEntry = 0; int currentLength = (int)r.ReadUnsigned(5) + 1; while (currentEntry < entries) { uint number = r.ReadUnsigned(VorbisUtil.InverseLog(entries - currentEntry)); for (int i = 0; i < number; ++i) { codewordUsed[currentEntry] = true; codewordLengths[currentEntry++] = currentLength; } ++currentLength; } } HuffInternalNode root = new HuffInternalNode(); for (int i = 0; i < entries; ++i) { if (codewordUsed[i]) { HuffLeafNode leaf = root.Insert(i, (int)codewordLengths[i]); if (leaf == null) { throw new VorbisReadException("Failed to reserve codeword of length {0} for entry #{1}. Possibly malformed codebook.", codewordLengths[i], i); } //Console.WriteLine(" Entry[{0}]: {1}", i, leaf.Codeword()); } } return root; }