private void HuffmanEncode(BitList 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.GetElementFromRunSize(0, category); _ushortToBits(bits, huffmanCode.CodeWord, huffmanCode.Length); _ushortToBits(bits, _numberEncoder(diff), category); } else { HuffmanElement EOB = huffmanDC.GetElementFromRunSize(0x00, 0x00); _ushortToBits(bits, EOB.CodeWord, EOB.Length); } int zeroesCounter = 0; for (int i = 1; i < 64; i++) { int x = QuantizationTable.RoadPoints[i, 0], y = QuantizationTable.RoadPoints[i, 1]; if (block8[x, y] == 0) { zeroesCounter++; continue; } while (zeroesCounter >= 16) { HuffmanElement ZRL = huffmanAC.GetElementFromRunSize(0x0F, 0x00); _ushortToBits(bits, ZRL.CodeWord, ZRL.Length); zeroesCounter -= 16; } byte cost = _bitCost((short)Math.Abs(block8[x, y])); HuffmanElement codeElement = huffmanAC.GetElementFromRunSize((byte)zeroesCounter, cost); zeroesCounter = 0; _ushortToBits(bits, codeElement.CodeWord, codeElement.Length); _ushortToBits(bits, _numberEncoder((short)block8[x, y]), cost); } if (zeroesCounter != 0) { //EOB HuffmanElement EOB = huffmanAC.GetElementFromRunSize(0x00, 0x00); _ushortToBits(bits, EOB.CodeWord, EOB.Length); } }
public void GetElementFromRunSize_Test() { byte runSizeInput1 = 0x00; ushort codeWordInput1 = 2; // 10 in base 2 byte lengthInput1 = 8; // 1000 in base 2 byte runSizeInput2 = 0x01; ushort codeWordInput2 = 3; // 11 in base 2 byte lengthInput2 = 8; // 1000 in base 2 HuffmanElement huffmanTestElement1 = new HuffmanElement(runSizeInput1, codeWordInput1, lengthInput1); HuffmanElement huffmanTestElement2 = new HuffmanElement(runSizeInput2, codeWordInput2, lengthInput2); HuffmanTable huffTable1 = new HuffmanTable(huffmanTestElement1, huffmanTestElement2); Assert.AreEqual(huffmanTestElement2, huffTable1.GetElementFromRunSize(0x0, 0x1)); //combines to 0x01 }