private static void storeTree(ref EncodeNode node, Symbol[] sym, ref BitStream stream, uint code, uint bits) { uint symbolIndex; if (node.Symbol >= 0) { writeBits(ref stream, 1, 1); writeBits(ref stream, (uint)node.Symbol, 8); for (symbolIndex = 0; symbolIndex < 256; ++symbolIndex) { if (sym[symbolIndex].Sym == node.Symbol) { break; } } sym[symbolIndex].Code = code; sym[symbolIndex].Bits = bits; return; } else { writeBits(ref stream, 0, 1); } storeTree(ref node.ChildA, sym, ref stream, (code << 1) + 0, bits + 1); storeTree(ref node.ChildB, sym, ref stream, (code << 1) + 1, bits + 1); }
private static void makeTree(Symbol[] sym, ref BitStream stream) { EncodeNode[] nodes = new EncodeNode[MAX_TREE_NODES]; for (int counter = 0; counter < nodes.Length; ++counter) { nodes[counter] = new EncodeNode(); } EncodeNode node1, node2, root; uint i, numSymbols = 0, nodesLeft, nextIndex; for (i = 0; i < 256; ++i) { if (sym[i].Count > 0) { nodes[numSymbols].Symbol = sym[i].Sym; nodes[numSymbols].Count = (int)sym[i].Count; nodes[numSymbols].ChildA = null; nodes[numSymbols].ChildB = null; ++numSymbols; } } root = null; nodesLeft = numSymbols; nextIndex = numSymbols; while (nodesLeft > 1) { node1 = null; node2 = null; for (i = 0; i < nextIndex; ++i) { if (nodes[i].Count > 0) { if (node1 == null || (nodes[i].Count <= node1.Count)) { node2 = node1; node1 = nodes[i]; } else if (node2 == null || (nodes[i].Count <= node2.Count)) { node2 = nodes[i]; } } } root = nodes[nextIndex]; root.ChildA = node1; root.ChildB = node2; root.Count = node1.Count + node2.Count; root.Symbol = -1; node1.Count = 0; node2.Count = 0; ++nextIndex; --nodesLeft; } if (root != null) { storeTree(ref root, sym, ref stream, 0, 0); } else { root = nodes[0]; storeTree(ref root, sym, ref stream, 0, 1); } }