| ImageWriter |

    package ij.io;
    import java.io.*;
    import ij.*;  //??

    /** Writes a raw image described by a FileInfo object to an OutputStream. */
    public class ImageWriter {
        private FileInfo fi;
        private boolean showProgressBar=true;

        public ImageWriter (FileInfo fi) {
            this.fi = fi;
        }

        private void showProgress(double progress) {
            if (showProgressBar)
                IJ.showProgress(progress);
        }

        void write8BitImage(OutputStream out, byte[] pixels)  throws IOException {
            int bytesWritten = 0;
            int size = fi.width*fi.height;
            int count = 8192;

            while (bytesWritten<size) {
                if ((bytesWritten + count)>size)
                    count = size - bytesWritten;
                //System.out.println(bytesWritten + " " + count + " " + size);
                out.write(pixels, bytesWritten, count);
                bytesWritten += count;
                showProgress((double)bytesWritten/size);
            }
        }

        void write8BitStack(OutputStream out, Object[] stack)  throws IOException {
            showProgressBar = false;
            for (int i=0; i<fi.nImages; i++) {
                IJ.showStatus("Writing: " + (i+1) + "/" + fi.nImages);
                write8BitImage(out, (byte[])stack[i]);
                IJ.showProgress((double)(i+1)/fi.nImages);
            }
        }

        void write16BitImage(OutputStream out, short[] pixels)  throws IOException {
            int bytesWritten = 0;
            int size = fi.width*fi.height*2;
            int count = 8192;
            byte[] buffer = new byte[count];

            while (bytesWritten<size) {
                if ((bytesWritten + count)>size)
                    count = size - bytesWritten;
                int j = bytesWritten/2;
                int value;
                if (fi.intelByteOrder)
                    for (int i=0; i < count; i+=2) {
                        value = pixels[j];
                        buffer[i] = (byte)value;
                        buffer[i+1] = (byte)(value>>>8);
                        j++;
                    }
                else
                    for (int i=0; i < count; i+=2) {
                        value = pixels[j];
                        buffer[i] = (byte)(value>>>8);
                        buffer[i+1] = (byte)value;
                        j++;
                    }
                out.write(buffer, 0, count);
                bytesWritten += count;
                showProgress((double)bytesWritten/size);
            }
        }

        void write16BitStack(OutputStream out, Object[] stack)  throws IOException {
            showProgressBar = false;
            for (int i=0; i<fi.nImages; i++) {
                IJ.showStatus("Writing: " + (i+1) + "/" + fi.nImages);
                write16BitImage(out, (short[])stack[i]);
                IJ.showProgress((double)(i+1)/fi.nImages);
            }
        }

        void writeRGB48Image(OutputStream out, Object[] stack)  throws IOException {
            short[] r = (short[])stack[0];
            short[] g = (short[])stack[1];
            short[] b = (short[])stack[2];
            int size = fi.width*fi.height;
            int count = fi.width*6;
            byte[] buffer = new byte[count];
            for (int line=0; line<fi.height; line++) {
                int index2 = 0;
                int index1 = line*fi.width;
                int value;
                for (int i=0; i<fi.width; i++) {
                    value = r[index1];
                    buffer[index2++] = (byte)(value>>>8);
                    buffer[index2++] = (byte)value;
                    value = g[index1];
                    buffer[index2++] = (byte)(value>>>8);
                    buffer[index2++] = (byte)value;
                    value = b[index1];
                    buffer[index2++] = (byte)(value>>>8);
                    buffer[index2++] = (byte)value;
                    index1++;
                }
                out.write(buffer, 0, count);
            }
        }

        void writeFloatImage(OutputStream out, float[] pixels)  throws IOException {
            int bytesWritten = 0;
            int size = fi.width*fi.height*4;
            int count = 8192;
            byte[] buffer = new byte[count];
            int tmp;
            boolean java2 = IJ.isJava2();

            while (bytesWritten<size) {
                if ((bytesWritten + count)>size)
                    count = size - bytesWritten;
                int j = bytesWritten/4;
                if (fi.intelByteOrder)
                    for (int i=0; i < count; i+=4) {
                        if (java2)
                            tmp = Float.floatToRawIntBits(pixels[j]);
                        else
                            tmp = Float.floatToIntBits(pixels[j]);
                        buffer[i]   = (byte)tmp;
                        buffer[i+1] = (byte)(tmp>>8);
                        buffer[i+2] = (byte)(tmp>>16);
                        buffer[i+3] = (byte)(tmp>>24);
                        j++;
                    }
                else
                    for (int i=0; i < count; i+=4) {
                        if (java2)
                            tmp = Float.floatToRawIntBits(pixels[j]);
                        else
                            tmp = Float.floatToIntBits(pixels[j]);
                        buffer[i]   = (byte)(tmp>>24);
                        buffer[i+1] = (byte)(tmp>>16);
                        buffer[i+2] = (byte)(tmp>>8);
                        buffer[i+3] = (byte)tmp;
                        j++;
                    }
                out.write(buffer, 0, count);
                bytesWritten += count;
                showProgress((double)bytesWritten/size);
            }
        }

        void writeFloatStack(OutputStream out, Object[] stack)  throws IOException {
            showProgressBar = false;
            for (int i=0; i<fi.nImages; i++) {
                IJ.showStatus("Writing: " + (i+1) + "/" + fi.nImages);
                writeFloatImage(out, (float[])stack[i]);
                IJ.showProgress((double)(i+1)/fi.nImages);
            }
        }

        void writeRGBImage(OutputStream out, int[] pixels)  throws IOException {
            int bytesWritten = 0;
            int size = fi.width*fi.height*3;
            int count = fi.width*24;
            byte[] buffer = new byte[count];
            while (bytesWritten<size) {
                if ((bytesWritten + count)>size)
                    count = size - bytesWritten;
                int j = bytesWritten/3;
                for (int i=0; i < count; i+=3) {
                    buffer[i]   = (byte)(pixels[j]>>16);    //red
                    buffer[i+1] = (byte)(pixels[j]>>8); //green
                    buffer[i+2] = (byte)pixels[j];      //blue
                    j++;
                }
                out.write(buffer, 0, count);
                bytesWritten += count;
                showProgress((double)bytesWritten/size);
            }
        }

        void writeRGBStack(OutputStream out, Object[] stack)  throws IOException {
            showProgressBar = false;
            for (int i=0; i<fi.nImages; i++) {
                IJ.showStatus("Writing: " + (i+1) + "/" + fi.nImages);
                writeRGBImage(out, (int[])stack[i]);
                IJ.showProgress((double)(i+1)/fi.nImages);
            }
        }

        /** Writes the image to the specified OutputStream.
            The OutputStream is not closed. The fi.pixels field
            must contain the image data. If fi.nImages>1
            then fi.pixels must be a 2D array, for example an
            array of images returned by ImageStack.getImageArray()).
            The fi.offset field is ignored. */
        public void write(OutputStream out) throws IOException {
            if (fi.pixels==null)
                    throw new IOException("ImageWriter: fi.pixels==null");
            if (fi.nImages>1 && !(fi.pixels instanceof Object[]))
                    throw new IOException("ImageWriter: fi.pixels not a stack");
            switch (fi.fileType) {
                case FileInfo.GRAY8:
                case FileInfo.COLOR8:
                    if (fi.nImages>1)
                        write8BitStack(out, (Object[])fi.pixels);
                    else
                        write8BitImage(out, (byte[])fi.pixels);
                    break;
                case FileInfo.GRAY16_SIGNED:
                case FileInfo.GRAY16_UNSIGNED:
                    if (fi.nImages>1)
                        write16BitStack(out, (Object[])fi.pixels);
                    else
                        write16BitImage(out, (short[])fi.pixels);
                    break;
                case FileInfo.RGB48:
                    writeRGB48Image(out, (Object[])fi.pixels);
                    break;
                case FileInfo.GRAY32_FLOAT:
                    if (fi.nImages>1)
                        writeFloatStack(out, (Object[])fi.pixels);
                    else
                        writeFloatImage(out, (float[])fi.pixels);
                    break;
                case FileInfo.RGB:
                    if (fi.nImages>1)
                        writeRGBStack(out, (Object[])fi.pixels);
                    else
                        writeRGBImage(out, (int[])fi.pixels);
                    break;
                default:
            }
        }

    }

| ImageWriter |