public static void Initialize() { if (ht != null) return; ht = new Huffman[HTN]; ht[0] = new Huffman("0 ", 0, 0, 0, 0, -1, null, null, ValTab0, 0); ht[1] = new Huffman("1 ", 2, 2, 0, 0, -1, null, null, ValTab1, 7); ht[2] = new Huffman("2 ", 3, 3, 0, 0, -1, null, null, ValTab2, 17); ht[3] = new Huffman("3 ", 3, 3, 0, 0, -1, null, null, ValTab3, 17); ht[4] = new Huffman("4 ", 0, 0, 0, 0, -1, null, null, ValTab4, 0); ht[5] = new Huffman("5 ", 4, 4, 0, 0, -1, null, null, ValTab5, 31); ht[6] = new Huffman("6 ", 4, 4, 0, 0, -1, null, null, ValTab6, 31); ht[7] = new Huffman("7 ", 6, 6, 0, 0, -1, null, null, ValTab7, 71); ht[8] = new Huffman("8 ", 6, 6, 0, 0, -1, null, null, ValTab8, 71); ht[9] = new Huffman("9 ", 6, 6, 0, 0, -1, null, null, ValTab9, 71); ht[10] = new Huffman("10 ", 8, 8, 0, 0, -1, null, null, ValTab10, 127); ht[11] = new Huffman("11 ", 8, 8, 0, 0, -1, null, null, ValTab11, 127); ht[12] = new Huffman("12 ", 8, 8, 0, 0, -1, null, null, ValTab12, 127); ht[13] = new Huffman("13 ", 16, 16, 0, 0, -1, null, null, ValTab13, 511); ht[14] = new Huffman("14 ", 0, 0, 0, 0, -1, null, null, ValTab14, 0); ht[15] = new Huffman("15 ", 16, 16, 0, 0, -1, null, null, ValTab15, 511); ht[16] = new Huffman("16 ", 16, 16, 1, 1, -1, null, null, ValTab16, 511); ht[17] = new Huffman("17 ", 16, 16, 2, 3, 16, null, null, ValTab16, 511); ht[18] = new Huffman("18 ", 16, 16, 3, 7, 16, null, null, ValTab16, 511); ht[19] = new Huffman("19 ", 16, 16, 4, 15, 16, null, null, ValTab16, 511); ht[20] = new Huffman("20 ", 16, 16, 6, 63, 16, null, null, ValTab16, 511); ht[21] = new Huffman("21 ", 16, 16, 8, 255, 16, null, null, ValTab16, 511); ht[22] = new Huffman("22 ", 16, 16, 10, 1023, 16, null, null, ValTab16, 511); ht[23] = new Huffman("23 ", 16, 16, 13, 8191, 16, null, null, ValTab16, 511); ht[24] = new Huffman("24 ", 16, 16, 4, 15, -1, null, null, ValTab24, 512); ht[25] = new Huffman("25 ", 16, 16, 5, 31, 24, null, null, ValTab24, 512); ht[26] = new Huffman("26 ", 16, 16, 6, 63, 24, null, null, ValTab24, 512); ht[27] = new Huffman("27 ", 16, 16, 7, 127, 24, null, null, ValTab24, 512); ht[28] = new Huffman("28 ", 16, 16, 8, 255, 24, null, null, ValTab24, 512); ht[29] = new Huffman("29 ", 16, 16, 9, 511, 24, null, null, ValTab24, 512); ht[30] = new Huffman("30 ", 16, 16, 11, 2047, 24, null, null, ValTab24, 512); ht[31] = new Huffman("31 ", 16, 16, 13, 8191, 24, null, null, ValTab24, 512); ht[32] = new Huffman("32 ", 1, 16, 0, 0, -1, null, null, ValTab32, 31); ht[33] = new Huffman("33 ", 1, 16, 0, 0, -1, null, null, ValTab33, 31); }
/// <summary> /// Do the huffman-decoding. /// NOTE: for counta, countb -the 4 bit value is returned in y, discard x. /// </summary> public static int Decode(Huffman h, int[] x, int[] y, int[] v, int[] w, BitReserve br) { // array of all huffcodtable headers // 0..31 Huffman code table 0..31 // 32,33 count1-tables int dmask = 1 << ((4*8) - 1); int point = 0; int error = 1; int level = dmask; if (h.val == null) return 2; /* table 0 needs no bits */ if (h.treelen == 0) { x[0] = y[0] = 0; return 0; } /* Lookup in Huffman table. */ /*int bitsAvailable = 0; int bitIndex = 0; int bits[] = bitbuf;*/ do { if (h.val[point][0] == 0) { /*end of tree*/ x[0] = SupportClass.URShift(h.val[point][1], 4); y[0] = h.val[point][1] & 0xf; error = 0; break; } // hget1bit() is called thousands of times, and so needs to be // ultra fast. /* if (bitIndex==bitsAvailable) { bitsAvailable = br.readBits(bits, 32); bitIndex = 0; } */ //if (bits[bitIndex++]!=0) if (br.ReadOneBit() != 0) { while (h.val[point][1] >= MXOFF) point += h.val[point][1]; point += h.val[point][1]; } else { while (h.val[point][0] >= MXOFF) point += h.val[point][0]; point += h.val[point][0]; } level = SupportClass.URShift(level, 1); // MDM: ht[0] is always 0; } while ((level != 0) || (point < 0)); // put back any bits not consumed /* int unread = (bitsAvailable-bitIndex); if (unread>0) br.rewindNbits(unread); */ /* Process sign encodings for quadruples tables. */ // System.out.println(h.tablename); if (h.tablename0 == '3' && (h.tablename1 == '2' || h.tablename1 == '3')) { v[0] = (y[0] >> 3) & 1; w[0] = (y[0] >> 2) & 1; x[0] = (y[0] >> 1) & 1; y[0] = y[0] & 1; /* v, w, x and y are reversed in the bitstream. switch them around to make test bistream work. */ if (v[0] != 0) if (br.ReadOneBit() != 0) v[0] = -v[0]; if (w[0] != 0) if (br.ReadOneBit() != 0) w[0] = -w[0]; if (x[0] != 0) if (br.ReadOneBit() != 0) x[0] = -x[0]; if (y[0] != 0) if (br.ReadOneBit() != 0) y[0] = -y[0]; } else { // Process sign and escape encodings for dual tables. // x and y are reversed in the test bitstream. // Reverse x and y here to make test bitstream work. if (h.linbits != 0) if ((h.xlen - 1) == x[0]) x[0] += br.ReadBits(h.linbits); if (x[0] != 0) if (br.ReadOneBit() != 0) x[0] = -x[0]; if (h.linbits != 0) if ((h.ylen - 1) == y[0]) y[0] += br.ReadBits(h.linbits); if (y[0] != 0) if (br.ReadOneBit() != 0) y[0] = -y[0]; } return error; }