public void HuffmanBlockEncoder(final BufferedOutputStream outStream, final int zigzag[], final int prec,
            final int DCcode, final int ACcode) {
        int temp, temp2, nbits, k, r, i;

        this.NumOfDCTables = 2;
        this.NumOfACTables = 2;

        // The DC portion

        temp = temp2 = zigzag[0] - prec;
        if (temp < 0) {
            temp = -temp;
            temp2--;
        }
        nbits = 0;
        while (temp != 0) {
            nbits++;
            temp >>= 1;
        }
        // if (nbits > 11) nbits = 11;
        bufferIt(outStream, ((int[][]) this.DC_matrix[DCcode])[nbits][0], ((int[][]) this.DC_matrix[DCcode])[nbits][1]);
        // The arguments in bufferIt are code and size.
        if (nbits != 0) {
            bufferIt(outStream, temp2, nbits);
        }

        // The AC portion

        r = 0;

        for (k = 1; k < 64; k++) {
            if ((temp = zigzag[jpegNaturalOrder[k]]) == 0) {
                r++;
            } else {
                while (r > 15) {
                    bufferIt(outStream, ((int[][]) this.AC_matrix[ACcode])[0xF0][0],
                            ((int[][]) this.AC_matrix[ACcode])[0xF0][1]);
                    r -= 16;
                }
                temp2 = temp;
                if (temp < 0) {
                    temp = -temp;
                    temp2--;
                }
                nbits = 1;
                while ((temp >>= 1) != 0) {
                    nbits++;
                }
                i = (r << 4) + nbits;
                bufferIt(outStream, ((int[][]) this.AC_matrix[ACcode])[i][0], ((int[][]) this.AC_matrix[ACcode])[i][1]);
                bufferIt(outStream, temp2, nbits);

                r = 0;
            }
        }

        if (r > 0) {
            bufferIt(outStream, ((int[][]) this.AC_matrix[ACcode])[0][0], ((int[][]) this.AC_matrix[ACcode])[0][1]);
        }

    }