All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.j3d.utils.scenegraph.io.state.javax.media.j3d.ImageComponentState Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistribution of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistribution in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any
 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
 * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that this software is not designed, licensed or
 * intended for use in the design, construction, operation or
 * maintenance of any nuclear facility.
 *
 */

package com.sun.j3d.utils.scenegraph.io.state.javax.media.j3d;

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import javax.imageio.ImageIO;
import javax.media.j3d.ImageComponent;

import com.sun.j3d.utils.scenegraph.io.retained.Controller;
import com.sun.j3d.utils.scenegraph.io.retained.SGIORuntimeException;
import com.sun.j3d.utils.scenegraph.io.retained.SymbolTableData;

public abstract class ImageComponentState extends NodeComponentState {

    protected int format;
    protected int height;
    protected int width;
    protected boolean byReference;
    protected boolean yUp;

    private static final int DIRECT_COLOR_MODEL = 1;

    private static final int SINGLE_PIXEL_PACKED_SAMPLE_MODEL = 1;

    private static final int DATA_BUFFER_INT = 1;

    /**
     * Do not compress the images
     */
    public static final byte NO_COMPRESSION = 0;

    /**
     * Use GZIP to compress images.
     *
     * GZIP decompression is very slow
     */
    public static final byte GZIP_COMPRESSION = 1;      // GZIP is slow to decompress

    /**
     * Use JPEG compression for images
     *
     * JPEG compression is currently the default. The file format
     * supports other compression algorithms but there is currently
     * no API to select the algorithm. This feature is on hold pending
     * imageio in Java 1.4
     */
    public static final byte JPEG_COMPRESSION = 2;

    public ImageComponentState( SymbolTableData symbol, Controller control ) {
	super( symbol, control );
    }


    @Override
    protected void writeConstructorParams( DataOutput out ) throws
							IOException {
        super.writeConstructorParams( out );
	out.writeInt( ((ImageComponent)node).getFormat());
	out.writeInt( ((ImageComponent)node).getHeight());
	out.writeInt( ((ImageComponent)node).getWidth());
        out.writeBoolean( ((ImageComponent)node).isByReference() );
        out.writeBoolean( ((ImageComponent)node).isYUp() );
    }

    @Override
    protected void readConstructorParams( DataInput in ) throws
							IOException {
        super.readConstructorParams( in );
	format = in.readInt();
	height = in.readInt();
	width = in.readInt();
        byReference = in.readBoolean();
        yUp = in.readBoolean();
    }

    protected void writeBufferedImage( DataOutput out,
				       BufferedImage image ) throws IOException {

        int compressionType = control.getImageCompression();

        out.writeByte( compressionType );

        if (compressionType==NO_COMPRESSION)
            writeBufferedImageNoCompression( out, image );
        else if (compressionType==GZIP_COMPRESSION)
            writeBufferedImageGzipCompression( out, image );
        else if (compressionType==JPEG_COMPRESSION)
            writeBufferedImageJpegCompression( out, image );
    }

    private void writeBufferedImageNoCompression( DataOutput out, BufferedImage image ) throws IOException {
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        DataOutputStream dataOut = new DataOutputStream( byteStream );
        ColorModel colorModel = (ColorModel) image.getColorModel();

        if (colorModel instanceof ComponentColorModel) {
            ComponentColorModel cm = (ComponentColorModel) colorModel;
            int numComponents = cm.getNumComponents();
            int type;
            switch (numComponents) {
                case 3:
                    type = BufferedImage.TYPE_INT_RGB;
                    break;
                case 4:
                    type = BufferedImage.TYPE_INT_ARGB;
                    break;
                default:
                    throw new SGIORuntimeException("Unsupported ColorModel "+colorModel.getClass().getName() );

            }

            BufferedImage tmpBuf = new BufferedImage(image.getWidth(), image.getHeight(), type);
            WritableRaster dstRaster = tmpBuf.getRaster();
            Raster srcRaster = image.getRaster();
            dstRaster.setRect(srcRaster);
           image = tmpBuf;
        }

        writeColorModel( dataOut, image.getColorModel() );
        writeWritableRaster( dataOut, image.getRaster() );
        dataOut.writeBoolean( image.isAlphaPremultiplied() );

        dataOut.close();

        byte[] buffer = byteStream.toByteArray();
        out.writeInt( buffer.length );
        out.write( buffer );
    }

    private void writeBufferedImageGzipCompression( DataOutput out, BufferedImage image ) throws IOException {
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        GZIPOutputStream gzipStream = new GZIPOutputStream( byteStream );
        DataOutputStream dataOut = new DataOutputStream( gzipStream );

        writeColorModel( dataOut, image.getColorModel() );
        writeWritableRaster( dataOut, image.getRaster() );
        dataOut.writeBoolean( image.isAlphaPremultiplied() );

        dataOut.flush();
        gzipStream.finish();


        byte[] buffer = byteStream.toByteArray();

        out.writeInt( buffer.length );
        out.write( buffer);
        dataOut.close();
    }

    private void writeBufferedImageJpegCompression( DataOutput out, BufferedImage image ) throws IOException {
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        ImageIO.write(image, "jpeg", byteStream);
        byteStream.close();

        byte[] buffer = byteStream.toByteArray();
        out.writeInt( buffer.length );
        out.write( buffer );
    }

    protected BufferedImage readBufferedImage( DataInput in ) throws IOException {
        byte compression = in.readByte();

        if (compression==NO_COMPRESSION)
            return readBufferedImageNoCompression( in );
        else if (compression==GZIP_COMPRESSION)
            return readBufferedImageGzipCompression( in );
        else if (compression==JPEG_COMPRESSION)
            return readBufferedImageJpegCompression( in );
	throw new SGIORuntimeException("Unknown Image Compression");
    }

    private BufferedImage readBufferedImageNoCompression( DataInput in ) throws IOException {
        int size = in.readInt();
        byte[] buffer = new byte[ size ];
        in.readFully( buffer );
        ByteArrayInputStream byteIn = new ByteArrayInputStream( buffer );
        DataInputStream dataIn = new DataInputStream( byteIn );

        ColorModel colorModel = readColorModel( dataIn );
        WritableRaster raster = readWritableRaster( dataIn );
        boolean alphaPreMult = dataIn.readBoolean();
        dataIn.close();

        return new BufferedImage( colorModel, raster, alphaPreMult, null );
    }

    private BufferedImage readBufferedImageGzipCompression( DataInput in ) throws IOException {
        int size = in.readInt();
        byte[] buffer = new byte[ size ];
        in.readFully( buffer );
        ByteArrayInputStream byteIn = new ByteArrayInputStream( buffer );
        GZIPInputStream gzipIn = new GZIPInputStream( byteIn );
        DataInputStream dataIn = new DataInputStream( gzipIn );

        ColorModel colorModel = readColorModel( dataIn );
        WritableRaster raster = readWritableRaster( dataIn );
        boolean alphaPremult = dataIn.readBoolean();
        dataIn.close();

        return new BufferedImage( colorModel, raster, alphaPremult, null );
    }

    private BufferedImage readBufferedImageJpegCompression( DataInput in ) throws IOException {
        int size = in.readInt();
        byte[] buffer = new byte[ size ];
        in.readFully( buffer );
        ByteArrayInputStream byteStream = new ByteArrayInputStream( buffer );

        return ImageIO.read(byteStream);
    }

    private void writeColorModel( DataOutput out, ColorModel colorModel ) throws IOException {
        if (colorModel instanceof DirectColorModel) {
            out.writeInt( DIRECT_COLOR_MODEL );
            writeDirectColorModel( out, (DirectColorModel)colorModel );
        }
        else
            throw new SGIORuntimeException("Unsupported ColorModel "+colorModel.getClass().getName() );
    }

    private ColorModel readColorModel( DataInput in ) throws IOException {
        switch( in.readInt() ) {
            case DIRECT_COLOR_MODEL:
                return readDirectColorModel( in );
        }

        throw new SGIORuntimeException( "Invalid ColorModel - File corrupt" );
    }

    private void writeDirectColorModel( DataOutput out,
					DirectColorModel colorModel ) throws IOException {
        out.writeInt( colorModel.getPixelSize() );
        out.writeInt( colorModel.getRedMask() );
        out.writeInt( colorModel.getGreenMask() );
        out.writeInt( colorModel.getBlueMask() );
        out.writeInt( colorModel.getAlphaMask() );
    }

    private DirectColorModel readDirectColorModel( DataInput in ) throws IOException {
        return new DirectColorModel( in.readInt(),
                                     in.readInt(),
                                     in.readInt(),
                                     in.readInt(),
                                     in.readInt() );
    }

    private void writeWritableRaster( DataOutput out, WritableRaster raster ) throws IOException{
        writeSampleModel( out, raster.getSampleModel() );
        writeDataBuffer( out, raster.getDataBuffer() );
        Point origin = new Point();
        // TODO Get the origin of the raster - seems to be missing from the raster API
        out.writeInt( origin.x );
        out.writeInt( origin.y );
    }

    private WritableRaster readWritableRaster( DataInput in ) throws IOException {
        return Raster.createWritableRaster( readSampleModel( in ),
                                   readDataBuffer( in ),
                                   new Point( in.readInt(), in.readInt() ));
    }

    private void writeSampleModel( DataOutput out, SampleModel model ) throws IOException {
        if (model instanceof SinglePixelPackedSampleModel) {
            out.writeInt( SINGLE_PIXEL_PACKED_SAMPLE_MODEL );
            writeSinglePixelPackedSampleModel( out, (SinglePixelPackedSampleModel)model );
        } else
            throw new SGIORuntimeException("Unsupported SampleModel "+model.getClass().getName() );
    }

    private SampleModel readSampleModel( DataInput in ) throws IOException {
        switch( in.readInt() ) {
            case SINGLE_PIXEL_PACKED_SAMPLE_MODEL:
                return readSinglePixelPackedSampleModel( in );
        }

        throw new SGIORuntimeException("Invalid SampleModel - file corrupt");
    }

    private void writeSinglePixelPackedSampleModel( DataOutput out,
        SinglePixelPackedSampleModel model ) throws IOException {

        int[] masks = model.getBitMasks();
        out.writeInt( masks.length );
        for(int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy