private void HuffmanEncode(ref List<byte> bits, int[,] block8, HuffmanTable huffmanDC, HuffmanTable huffmanAC, int DCIndex) { short diff = (short)(block8[0, 0] - LastDC[DCIndex]); LastDC[DCIndex] += diff; if (diff != 0) { byte category = bitCost(diff); huffmanElement huffmanCode = huffmanDC.getHuffmanCode(0, category); ushortToBits(ref bits, huffmanCode.codeWord, huffmanCode.length); ushortToBits(ref bits, negativeNumberEncoder(diff), category); } else { huffmanElement EOB = huffmanDC.getHuffmanCode(0x00, 0x00); ushortToBits(ref bits, EOB.codeWord, EOB.length); } int zeroesCounter = 0; for (int i = 1; i < 64; i++) { int x = _roadPoints[i, 0], y = _roadPoints[i, 1]; if (block8[x, y] == 0) { zeroesCounter++; continue; } while (zeroesCounter >= 16) { huffmanElement ZRL = huffmanAC.getHuffmanCode(0x0F, 0x00); ushortToBits(ref bits, ZRL.codeWord, ZRL.length); zeroesCounter -= 16; } byte cost = bitCost((short)Math.Abs(block8[x, y])); huffmanElement codeElement = huffmanAC.getHuffmanCode((byte)zeroesCounter, cost); zeroesCounter = 0; ushortToBits(ref bits, codeElement.codeWord, codeElement.length); ushortToBits(ref bits, negativeNumberEncoder((short)block8[x, y]), cost); } if (zeroesCounter != 0) { //EOB huffmanElement EOB = huffmanAC.getHuffmanCode(0x00, 0x00); ushortToBits(ref bits, EOB.codeWord, EOB.length); } }
private void addHuffmanTable(HuffmanTable huffman, byte id, bool dc) { writeBytesToStream(0xff, 0xc4); //DHT marker ushort len = (ushort)(huffman.combinationsInTable + 19); writeBytesToStream((byte)(len >> 8), (byte)(len & 0xff)); byte combined; if (!dc) { combined = (byte)((1 << 4) + id); } else { combined = id; } writeBytesToStream(combined); for (int i = 0; i < 16; i++) { writeBytesToStream(huffman.bitLengths[i]); } for (int i = 0; i < 16; i++) { for (int j = 0; j < huffman.combinationsInTable; j++) { if (huffman.elements[j].length == i + 1) { writeBytesToStream(huffman.elements[j].runSize); } } } }