public void WriteHeaders(final BufferedOutputStream out) {
        int i, j, index, offset, length;
        int tempArray[];

        // the SOI marker
        final byte[] SOI = {
                (byte) 0xFF, (byte) 0xD8 };
        WriteMarker(SOI, out);

        // The order of the following headers is quiet inconsequential.
        // the JFIF header
        final byte JFIF[] = new byte[18];
        JFIF[0] = (byte) 0xff; // app0 marker
        JFIF[1] = (byte) 0xe0;
        JFIF[2] = (byte) 0x00; // length
        JFIF[3] = (byte) 0x10;
        JFIF[4] = (byte) 0x4a; // "JFIF"
        JFIF[5] = (byte) 0x46;
        JFIF[6] = (byte) 0x49;
        JFIF[7] = (byte) 0x46;
        JFIF[8] = (byte) 0x00;
        JFIF[9] = (byte) 0x01; // 1.01
        JFIF[10] = (byte) 0x01;
        JFIF[11] = (byte) 0x00;
        JFIF[12] = (byte) 0x00;
        JFIF[13] = (byte) 0x01;
        JFIF[14] = (byte) 0x00;
        JFIF[15] = (byte) 0x01;
        JFIF[16] = (byte) 0x00;
        JFIF[17] = (byte) 0x00;

        if (this.JpegObj.getComment().equals("JPEG Encoder Copyright 1998, James R. Weeks and BioElectroMech.  ")) {
            JFIF[10] = (byte) 0x00; // 1.00
        }
        WriteArray(JFIF, out);

        // Comment Header
        String comment = new String();
        comment = this.JpegObj.getComment();
        length = comment.length();
        if (length != 0) {
            final byte COM[] = new byte[length + 4];
            COM[0] = (byte) 0xFF;
            COM[1] = (byte) 0xFE;
            COM[2] = (byte) (length >> 8 & 0xFF);
            COM[3] = (byte) (length & 0xFF);
            java.lang.System.arraycopy(this.JpegObj.Comment.getBytes(), 0, COM, 4, this.JpegObj.Comment.length());
            WriteArray(COM, out);
        }

        // The DQT header
        // 0 is the luminance index and 1 is the chrominance index
        final byte DQT[] = new byte[134];
        DQT[0] = (byte) 0xFF;
        DQT[1] = (byte) 0xDB;
        DQT[2] = (byte) 0x00;
        DQT[3] = (byte) 0x84;
        offset = 4;
        for (i = 0; i < 2; i++) {
            DQT[offset++] = (byte) ((0 << 4) + i);
            tempArray = (int[]) this.dct.quantum[i];
            for (j = 0; j < 64; j++) {
                DQT[offset++] = (byte) tempArray[jpegNaturalOrder[j]];
            }
        }
        WriteArray(DQT, out);

        // Start of Frame Header
        final byte SOF[] = new byte[19];
        SOF[0] = (byte) 0xFF;
        SOF[1] = (byte) 0xC0;
        SOF[2] = (byte) 0x00;
        SOF[3] = (byte) 17;
        SOF[4] = (byte) this.JpegObj.Precision;
        SOF[5] = (byte) (this.JpegObj.imageHeight >> 8 & 0xFF);
        SOF[6] = (byte) (this.JpegObj.imageHeight & 0xFF);
        SOF[7] = (byte) (this.JpegObj.imageWidth >> 8 & 0xFF);
        SOF[8] = (byte) (this.JpegObj.imageWidth & 0xFF);
        SOF[9] = (byte) this.JpegObj.NumberOfComponents;
        index = 10;
        for (i = 0; i < SOF[9]; i++) {
            SOF[index++] = (byte) this.JpegObj.CompID[i];
            SOF[index++] = (byte) ((this.JpegObj.HsampFactor[i] << 4) + this.JpegObj.VsampFactor[i]);
            SOF[index++] = (byte) this.JpegObj.QtableNumber[i];
        }
        WriteArray(SOF, out);

        // The DHT Header
        byte DHT1[], DHT2[], DHT3[], DHT4[];
        int bytes, temp, oldindex, intermediateindex;
        length = 2;
        index = 4;
        oldindex = 4;
        DHT1 = new byte[17];
        DHT4 = new byte[4];
        DHT4[0] = (byte) 0xFF;
        DHT4[1] = (byte) 0xC4;
        for (i = 0; i < 4; i++) {
            bytes = 0;
            DHT1[index++ - oldindex] = (byte) this.Huf.bits.elementAt(i)[0];
            for (j = 1; j < 17; j++) {
                temp = this.Huf.bits.elementAt(i)[j];
                DHT1[index++ - oldindex] = (byte) temp;
                bytes += temp;
            }
            intermediateindex = index;
            DHT2 = new byte[bytes];
            for (j = 0; j < bytes; j++) {
                DHT2[index++ - intermediateindex] = (byte) this.Huf.val.elementAt(i)[j];
            }
            DHT3 = new byte[index];
            java.lang.System.arraycopy(DHT4, 0, DHT3, 0, oldindex);
            java.lang.System.arraycopy(DHT1, 0, DHT3, oldindex, 17);
            java.lang.System.arraycopy(DHT2, 0, DHT3, oldindex + 17, bytes);
            DHT4 = DHT3;
            oldindex = index;
        }
        DHT4[2] = (byte) (index - 2 >> 8 & 0xFF);
        DHT4[3] = (byte) (index - 2 & 0xFF);
        WriteArray(DHT4, out);

        // Start of Scan Header
        final byte SOS[] = new byte[14];
        SOS[0] = (byte) 0xFF;
        SOS[1] = (byte) 0xDA;
        SOS[2] = (byte) 0x00;
        SOS[3] = (byte) 12;
        SOS[4] = (byte) this.JpegObj.NumberOfComponents;
        index = 5;
        for (i = 0; i < SOS[4]; i++) {
            SOS[index++] = (byte) this.JpegObj.CompID[i];
            SOS[index++] = (byte) ((this.JpegObj.DCtableNumber[i] << 4) + this.JpegObj.ACtableNumber[i]);
        }
        SOS[index++] = (byte) this.JpegObj.Ss;
        SOS[index++] = (byte) this.JpegObj.Se;
        SOS[index++] = (byte) ((this.JpegObj.Ah << 4) + this.JpegObj.Al);
        WriteArray(SOS, out);

    }