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;
                }
            }
        }
Example #3
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;
            }
        }