OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [imageio/] [png/] [PNGEncoder.java] - Blame information for rev 777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* PNGEncoder.java --
2
   Copyright (C) 2006 Free Software Foundation
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.javax.imageio.png;
39
 
40
import java.util.Vector;
41
import java.util.zip.Deflater;
42
import java.awt.color.ColorSpace;
43
import java.awt.color.ICC_ColorSpace;
44
import java.awt.image.BufferedImage;
45
import java.awt.image.ColorModel;
46
import java.awt.image.DataBuffer;
47
import java.awt.image.DataBufferByte;
48
import java.awt.image.DataBufferUShort;
49
import java.awt.image.IndexColorModel;
50
import java.awt.image.WritableRaster;
51
 
52
public class PNGEncoder
53
{
54
  /**
55
   * The default data chunk size. 8 kb.
56
   */
57
  private static final int defaultChunkSize = 8192;
58
 
59
  private PNGHeader header;
60
  private PNGPalette palette;
61
  private int stride, bpp;
62
  private byte[] rawData;
63
  private PNGICCProfile profile;
64
 
65
  public PNGEncoder( BufferedImage bi ) throws PNGException
66
  {
67
    ColorModel c = bi.getColorModel();
68
    int width = bi.getWidth();
69
    int height = bi.getHeight();
70
    int depth = 0;
71
    int colorType;
72
    boolean interlace = false;
73
 
74
    if( c instanceof IndexColorModel )
75
      {
76
        colorType = PNGHeader.INDEXED;
77
        int n = ((IndexColorModel)c).getMapSize();
78
        if( n <= 2 )
79
          depth = 1;
80
        else if( n <= 4 )
81
          depth = 2;
82
        else if( n <= 16 )
83
          depth = 4;
84
        else if( n <= 256 )
85
          depth = 8;
86
        else
87
          throw new PNGException("Depth must be <= 8 bits for indexed color.");
88
        palette = new PNGPalette( ((IndexColorModel)c) );
89
      }
90
    else
91
      {
92
        ColorSpace cs = c.getColorSpace();
93
        ColorSpace grayCS = ColorSpace.getInstance( ColorSpace.CS_GRAY );
94
        if( cs == grayCS || bi.getType() == BufferedImage.TYPE_BYTE_GRAY
95
            || bi.getType() == BufferedImage.TYPE_USHORT_GRAY )
96
          colorType = c.hasAlpha() ? PNGHeader.GRAYSCALE_WITH_ALPHA :
97
            PNGHeader.GRAYSCALE;
98
        else
99
          colorType = c.hasAlpha() ? PNGHeader.RGB_WITH_ALPHA : PNGHeader.RGB;
100
        // Figure out the depth
101
        int[] bits = c.getComponentSize();
102
        depth = bits[0];
103
        for(int i = 1; i < bits.length; i++ )
104
          if( bits[i] > depth ) depth = bits[i];
105
        if( (cs != grayCS && !cs.isCS_sRGB()) && cs instanceof ICC_ColorSpace )
106
          profile = new PNGICCProfile( ((ICC_ColorSpace)cs).getProfile() );
107
      }
108
 
109
    header = new PNGHeader(width, height, depth, colorType, interlace);
110
 
111
    stride = header.getScanlineStride(); // scanline stride
112
    bpp = header.bytesPerPixel(); // bytes per pixel
113
    getRawData( bi );
114
  }
115
 
116
  /**
117
   * Returns the generated header.
118
   */
119
  public PNGHeader getHeader()
120
  {
121
    return header;
122
  }
123
 
124
  /**
125
   * Returns the generated palette.
126
   */
127
  public PNGPalette getPalette()
128
  {
129
    return palette;
130
  }
131
 
132
  /**
133
   * Returns the associated ICC profile, if any.
134
   */
135
  public PNGICCProfile getProfile()
136
  {
137
    return profile;
138
  }
139
 
140
  /**
141
   * Encodes the raster and returns a Vector of PNGData chunks.
142
   */
143
  public Vector encodeImage()
144
  {
145
    Deflater deflater = new Deflater(); // The deflater
146
    boolean useFilter = PNGFilter.useFilter( header );
147
    byte[] lastScanline = new byte[ stride ];
148
 
149
    byte[] data = new byte[ rawData.length + header.getHeight() ];
150
 
151
    byte filterByte = PNGFilter.FILTER_NONE;
152
    for( int i = 0; i < header.getHeight(); i++)
153
      {
154
        byte[] scanline = new byte[ stride ];
155
        System.arraycopy(rawData, (i * stride), scanline, 0, stride);
156
        if( useFilter && i > 0)
157
          filterByte = PNGFilter.chooseFilter( scanline, lastScanline, bpp);
158
 
159
        byte[] filtered = PNGFilter.filterScanline( filterByte, scanline,
160
                                                    lastScanline, bpp );
161
        data[i * (stride + 1)] = filterByte;
162
        System.arraycopy(filtered, 0, data, 1 + (i * (stride + 1)), stride);
163
 
164
        lastScanline = scanline;
165
      }
166
 
167
    deflater.setInput( data );
168
    deflater.finish();
169
 
170
    PNGData chunk;
171
    Vector chunks = new Vector();
172
    do
173
      {
174
        chunk = new PNGData( defaultChunkSize );
175
        chunk.deflateToChunk( deflater );
176
        chunks.add( chunk );
177
      }
178
    while( chunk.chunkFull() );
179
    chunk.shrink(); // Shrink the last chunk.
180
    return chunks;
181
  }
182
 
183
  /**
184
   * Get the image's raw data.
185
   * FIXME: This may need improving on.
186
   */
187
  private void getRawData( BufferedImage bi ) throws PNGException
188
  {
189
    WritableRaster raster = bi.getRaster();
190
    rawData = new byte[ stride * header.getHeight() ];
191
    if( header.isIndexed() )
192
      {
193
        DataBuffer db = raster.getDataBuffer();
194
        if( !( db instanceof DataBufferByte ) )
195
          throw new PNGException("Unexpected DataBuffer for an IndexColorModel.");
196
        byte[] data = ((DataBufferByte)db).getData();
197
        for(int i = 0; i < header.getHeight(); i++ )
198
          System.arraycopy( data, i * stride, rawData, i * stride, stride );
199
        return;
200
      }
201
 
202
    if( header.getDepth() == 16 )
203
      {
204
        DataBuffer db = raster.getDataBuffer();
205
        if( !( db instanceof DataBufferUShort ) )
206
          throw new PNGException("Unexpected DataBuffer for 16-bit.");
207
        short[] data = ((DataBufferUShort)db).getData();
208
        for(int i = 0; i < header.getHeight(); i++ )
209
          for(int j = 0; j < ( stride >> 1); j++)
210
            {
211
              rawData[ j * 2 + i * stride ] = (byte)((data[j + i * (stride >> 1 )] & 0xFF00) >> 8);
212
              rawData[ j * 2 + i * stride + 1 ] = (byte)(data[j + i * (stride >> 1 )] & 0xFF);
213
            }
214
        return;
215
      }
216
 
217
    int size = ( header.getColorType() == PNGHeader.RGB_WITH_ALPHA ) ? 4 : 3;
218
    int width = header.getWidth();
219
    int height = header.getHeight();
220
    int[] pixels = bi.getRGB( 0, 0, width, height, null, 0, width );
221
 
222
    for( int i = 0; i < width * height; i++ )
223
      {
224
        rawData[ i * size ] = (byte)((pixels[i] & 0xFF0000) >> 16);
225
        rawData[ i * size + 1 ] = (byte)((pixels[i] & 0xFF00) >> 8);
226
        rawData[ i * size + 2 ] = (byte)(pixels[i] & 0xFF);
227
      }
228
 
229
    if( size == 4 )
230
      for( int i = 0; i < width * height; i++ )
231
        rawData[ i * size + 3 ] = (byte)((pixels[i] & 0xFF000000) >> 24);
232
  }
233
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.