    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/processing/raster/converter/RawData2Image.java $
    002    /*----------------------------------------------------------------------------
    003     This file is part of deegree, http://deegree.org/
    004     Copyright (C) 2001-2009 by:
    005       Department of Geography, University of Bonn
    006     and
    007       lat/lon GmbH
    008
    009     This library is free software; you can redistribute it and/or modify it under
    010     the terms of the GNU Lesser General Public License as published by the Free
    011     Software Foundation; either version 2.1 of the License, or (at your option)
    012     any later version.
    013     This library is distributed in the hope that it will be useful, but WITHOUT
    014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    016     details.
    017     You should have received a copy of the GNU Lesser General Public License
    018     along with this library; if not, write to the Free Software Foundation, Inc.,
    019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    020
    021     Contact information:
    022
    023     lat/lon GmbH
    024     Aennchenstr. 19, 53177 Bonn
    025     Germany
    026     http://lat-lon.de/
    027
    028     Department of Geography, University of Bonn
    029     Prof. Dr. Klaus Greve
    030     Postfach 1147, 53001 Bonn
    031     Germany
    032     http://www.geographie.uni-bonn.de/deegree/
    033
    034     e-mail: info@deegree.org
    035    ----------------------------------------------------------------------------*/
    036    package org.deegree.processing.raster.converter;
    037
    038    import java.awt.color.ColorSpace;
    039    import java.awt.image.BufferedImage;
    040    import java.awt.image.ColorModel;
    041    import java.awt.image.ComponentColorModel;
    042    import java.awt.image.DataBuffer;
    043    import java.awt.image.Raster;
    044    import java.awt.image.SampleModel;
    045    import java.awt.image.WritableRaster;
    046    import java.util.Hashtable;
    047
    048    /**
    049     * Offeres methods to wrap raw number data into a <code>BufferedImage</code>
    050     *
    051     *
    052     * @version $Revision: 18195 $
    053     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
    054     * @author last edited by: $Author: mschneider $
    055     *
    056     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    057     */
    058    public class RawData2Image {
    059
    060        /**
    061         *
    062         * @param type
    063         *            the desired DataBuffer type
    064         * @param width
    065         * @param height
    066         * @return a new Image
    067         */
    068        private static BufferedImage createImage( int type, int width, int height ) {
    069
    070            ColorModel ccm = new ComponentColorModel( ColorSpace.getInstance( ColorSpace.CS_GRAY ), null, false, false,
    071                                                      BufferedImage.OPAQUE, type );
    072
    073            WritableRaster wr = ccm.createCompatibleWritableRaster( width, height );
    074
    075            return new BufferedImage( ccm, wr, false, new Hashtable<Object, Object>() );
    076
    077        }
    078
    079        /**
    080         * @return result will be a <code>BufferedImage</code> with a GRAY colorspace and
    081         *         <code>DataBuffer.TYPE_BYTE</code>
    082         *
    083         * @param data
    084         *            data to wrap
    085         */
    086        public static BufferedImage rawData2Image( byte[][] data ) {
    087
    088            BufferedImage img = createImage( DataBuffer.TYPE_BYTE, data[0].length, data.length );
    089            Raster raster = img.getData();
    090            DataBuffer buffer = raster.getDataBuffer();
    091
    092            for ( int i = 0; i < data.length; i++ ) {
    093                for ( int j = 0; j < data[0].length; j++ ) {
    094                    int pos = data[0].length * i + j;
    095                    buffer.setElem( pos, data[i][j] );
    096                }
    097            }
    098            img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) );
    099            return img;
    100        }
    101
    102        /**
    103         * @return result will be a <code>BufferedImage</code> with a GRAY colorspace and
    104         *         <code>DataBuffer.TYPE_USHORT</code>
    105         *
    106         * @param data
    107         *            data to wrap
    108         */
    109        public static BufferedImage rawData2Image( short[][] data ) {
    110            BufferedImage img = createImage( DataBuffer.TYPE_USHORT, data[0].length, data.length );
    111            Raster raster = img.getData();
    112            DataBuffer buffer = raster.getDataBuffer();
    113
    114            for ( int i = 0; i < data.length; i++ ) {
    115                for ( int j = 0; j < data[0].length; j++ ) {
    116                    int pos = data[0].length * i + j;
    117                    buffer.setElem( pos, data[i][j] );
    118                }
    119            }
    120            img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) );
    121            return img;
    122        }
    123
    124        /**
    125         * @return result will be a <code>BufferedImage</code> with a GRAY colorspace and
    126         *         <code>DataBuffer.TYPE_INT</code>
    127         *
    128         * @param data
    129         *            data to wrap
    130         */
    131        public static BufferedImage rawData2Image( int[][] data ) {
    132            BufferedImage img = createImage( DataBuffer.TYPE_INT, data[0].length, data.length );
    133            Raster raster = img.getData();
    134            DataBuffer buffer = raster.getDataBuffer();
    135
    136            for ( int i = 0; i < data.length; i++ ) {
    137                for ( int j = 0; j < data[0].length; j++ ) {
    138                    int pos = data[0].length * i + j;
    139                    buffer.setElem( pos, data[i][j] );
    140                }
    141            }
    142            img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) );
    143            return img;
    144        }
    145
    146        /**
    147         * Float data requires 4 Byte (32Bit) per data cell. It is common to reduce data depth by
    148         * multiplying float values with 10 and map the rounded result to an unsigned short value
    149         * (16Bit). This behavior can be controlled by the second parameter passed to this method. If
    150         * set to <code>true</code> a image with 32Bit data depth and INT Databuffer will be created.
    151         * Otherwise a 16Bit Image with an USHORT Databuffer will be created.<br>
    152         * A default scale of 10 and no offset will be used
    153         *
    154         * @return result will be a <code>BufferedImage</code> with a GRAY colorspace.
    155         *
    156         * @param data
    157         *            data to wrap
    158         * @param use32Bits
    159         */
    160        public static BufferedImage rawData2Image( float[][] data, boolean use32Bits ) {
    161            return rawData2Image( data, use32Bits, 10, 0 );
    162        }
    163
    164        /**
    165         * Float data requires 4 Byte (32Bit) per data cell. It is common to reduce data depth by
    166         * multiplying float values with 10 and map the rounded result to an unsigned short value
    167         * (16Bit). This behavior can be controlled by the second parameter passed to this method. If
    168         * set to <code>true</code> a image with 32Bit data depth and INT Databuffer will be created.
    169         * Otherwise a 16Bit Image with an USHORT Databuffer will be created.
    170         *
    171         * @param data
    172         * @param use32Bits
    173         * @param scale
    174         * @param offset
    175         * @return result will be a <code>BufferedImage</code> with a GRAY colorspace.
    176         */
    177        public static BufferedImage rawData2Image( float[][] data, boolean use32Bits, float scale, float offset ) {
    178            BufferedImage img = null;
    179            if ( use32Bits ) {
    180                img = new BufferedImage( data[0].length, data.length, BufferedImage.TYPE_INT_ARGB );
    181                Raster raster = img.getData();
    182                DataBuffer buffer = raster.getDataBuffer();
    183                for ( int i = 0; i < data.length; i++ ) {
    184                    for ( int j = 0; j < data[0].length; j++ ) {
    185                        int pos = data[0].length * i + j;
    186                        buffer.setElem( pos, Float.floatToIntBits( data[i][j] ) );
    187                    }
    188                }
    189                img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) );
    190            } else {
    191                img = createImage( DataBuffer.TYPE_USHORT, data[0].length, data.length );
    192                Raster raster = img.getData();
    193                DataBuffer buffer = raster.getDataBuffer();
    194                for ( int i = 0; i < data.length; i++ ) {
    195                    for ( int j = 0; j < data[0].length; j++ ) {
    196                        int pos = data[0].length * i + j;
    197                        buffer.setElem( pos, Math.round( ( data[i][j] + offset ) * scale ) );
    198                    }
    199                }
    200                img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) );
    201            }
    202
    203            return img;
    204        }
    205
    206        /**
    207         * Special version of the method which creates a new BufferedImage according to the models
    208         * given.
    209         *
    210         * @return result will be a <code>BufferedImage</code> with the given color model
    211         *
    212         * @param data
    213         *            data to wrap
    214         * @param use32Bits
    215         * @param colorModel
    216         * @param sampleModel
    217         */
    218        public static BufferedImage rawData2Image( float[][] data, boolean use32Bits, ColorModel colorModel,
    219                                                   SampleModel sampleModel ) {
    220
    221            BufferedImage img = null;
    222            if ( use32Bits ) {
    223                SampleModel sm = sampleModel.createCompatibleSampleModel( data[0].length, data.length );
    224
    225                WritableRaster raster = Raster.createWritableRaster( sm, null );
    226
    227                img = new BufferedImage( colorModel, raster, true, new Hashtable<Object, Object>() );
    228
    229                for ( int i = 0; i < data.length; i++ ) {
    230                    for ( int j = 0; j < data[i].length; j++ ) {
    231                        img.setRGB( j, i, Float.floatToRawIntBits( data[i][j] ) );
    232                    }
    233                }
    234
    235            } else {
    236                img = createImage( DataBuffer.TYPE_USHORT, data[0].length, data.length );
    237                Raster raster = img.getData();
    238                DataBuffer buffer = raster.getDataBuffer();
    239                for ( int i = 0; i < data.length; i++ ) {
    240                    for ( int j = 0; j < data[i].length; j++ ) {
    241                        int pos = data[i].length * i + j;
    242                        buffer.setElem( pos, Math.round( data[i][j] * 10 ) );
    243                    }
    244                }
    245                img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) );
    246            }
    247
    248            return img;
    249        }
    250    }