void DoHuffmanEncoding(Int16[] DU, ref Int16 DC, Tables.BitString[] HTDC, Tables.BitString[] HTAC, BinaryWriter bw) { Tables.BitString EOB = HTAC[0x00]; Tables.BitString M16zeroes = HTAC[0xF0]; Byte i; Byte startpos; Byte end0pos; Byte nrzeroes; Byte nrmarker; Int16 Diff; // Encode DC Diff = (Int16)(DU[0] - DC); DC = DU[0]; if (Diff == 0) WriteBits(HTDC[0],bw); else { WriteBits(HTDC[Tables.Category[32767 + Diff]], bw); WriteBits(Tables.BitCode[32767 + Diff], bw); } // Encode ACs for (end0pos = 63; (end0pos > 0) && (DU[end0pos] == 0); end0pos--) ; //end0pos = first element in reverse order != 0 i = 1; while (i <= end0pos) { startpos = i; for (; (DU[i] == 0) && (i <= end0pos); i++) ; nrzeroes = (byte) (i - startpos); if (nrzeroes >= 16) { for (nrmarker = 1; nrmarker <= nrzeroes / 16; nrmarker++) WriteBits(M16zeroes,bw); nrzeroes = (byte) (nrzeroes % 16); } WriteBits(HTAC[nrzeroes * 16 + Tables.Category[32767 + DU[i]]], bw); WriteBits(Tables.BitCode[32767 + DU[i]], bw); i++; } if (end0pos != 63) WriteBits(EOB,bw); }
void WriteBits(Tables.BitString bs, BinaryWriter bw) { UInt16 value; SByte posval; value = bs.value; posval = (SByte)(bs.length - 1); while (posval >= 0) { if ((value & mask[posval]) != 0) { bytenew = (Byte)(bytenew | mask[bytepos]); } posval--; bytepos--; if (bytepos < 0) { // Write to stream if (bytenew == 0xFF) { // Handle special case bw.Write((byte)(0xFF)); bw.Write((byte)(0x00)); } else bw.Write((byte)(bytenew)); // Reinitialize bytepos = 7; bytenew = 0; } } }
static void Compute_Huffman_Table(Byte[] nrCodes, Byte[] std_table, ref Tables.BitString[] Huffman_Table) { Byte k, j; Byte pos_in_table; UInt16 code_value; code_value = 0; pos_in_table = 0; for (k = 1; k <= 16; k++) { for (j = 1; j <= nrCodes[k]; j++) { Huffman_Table[std_table[pos_in_table]].value = code_value; Huffman_Table[std_table[pos_in_table]].length = k; pos_in_table++; code_value++; } code_value <<= 1; } }