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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* PNGDecoder.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.zip.Inflater;
41
import java.util.zip.DataFormatException;
42
import java.awt.image.ColorModel;
43
import java.awt.image.ComponentColorModel;
44
import java.awt.image.ComponentSampleModel;
45
import java.awt.image.DataBuffer;
46
import java.awt.image.DataBufferByte;
47
import java.awt.image.DataBufferUShort;
48
import java.awt.image.IndexColorModel;
49
import java.awt.image.MultiPixelPackedSampleModel;
50
import java.awt.image.Raster;
51
import java.awt.image.SampleModel;
52
import java.awt.image.SinglePixelPackedSampleModel;
53
import java.awt.image.WritableRaster;
54
import java.awt.color.ColorSpace;
55
 
56
public class PNGDecoder
57
{
58
  private PNGHeader header;
59
  private byte[] raster;
60
  private byte[] scanline, lastScanline;
61
  private byte[] filterType;
62
  private int offset, length;
63
  private int currentScanline;
64
  private final int stride;
65
  private Inflater inflater;
66
  private boolean readFilter;
67
  private int bpp; // bytes per pixel
68
 
69
  /**
70
   * Constructs a filter object for
71
   */
72
  public PNGDecoder(PNGHeader header)
73
  {
74
    this.header = header;
75
    offset = 0;
76
    inflater = new Inflater();
77
    stride = header.getScanlineStride();
78
    length = stride * header.getHeight();
79
 
80
    // Allocate the output raster
81
    raster = new byte[ length ];
82
    scanline = new byte[ stride ];
83
    lastScanline = new byte[ stride ];
84
    currentScanline = 0;
85
    readFilter = true;
86
    bpp = header.bytesPerPixel();
87
    filterType = new byte[1];
88
    inflater = new Inflater();
89
  }
90
 
91
  private int getBytes( byte[] buf, int offset ) throws PNGException
92
  {
93
    try
94
      {
95
        return inflater.inflate( buf, offset, buf.length - offset);
96
      }
97
    catch(DataFormatException dfe)
98
      {
99
        throw new PNGException("Error inflating data.");
100
      }
101
  }
102
 
103
  /**
104
   * Decodes a data chunk.
105
   */
106
  public void addData( PNGData chunk ) throws PNGException
107
  {
108
    int n = 0;
109
    if( isFinished() )
110
      return;
111
    chunk.feedToInflater( inflater );
112
    do
113
      {
114
        if( readFilter )
115
          if( getBytes( filterType, 0 ) < 1 )
116
            return;
117
 
118
        n = getBytes( scanline, offset );
119
 
120
        if( offset + n < stride )
121
          {
122
            offset += n;
123
            readFilter = false;
124
          }
125
        else
126
          {
127
            scanline = PNGFilter.unFilterScanline( filterType[0], scanline,
128
                                                   lastScanline, bpp );
129
            System.arraycopy( scanline, 0,
130
                              raster, currentScanline * stride, stride );
131
            lastScanline = scanline;
132
            scanline = new byte[scanline.length];
133
            currentScanline++;
134
            readFilter = true;
135
            offset = 0;
136
          }
137
      }
138
    while( n > 0 && currentScanline < header.getHeight() );
139
  }
140
 
141
  /**
142
   * Parse the appropriate color type and create an AWT raster for it.
143
   * @param header - the file header.
144
   */
145
  public WritableRaster getRaster( PNGHeader header )
146
  {
147
    SampleModel sm = null;
148
    DataBuffer db = null;
149
    int t;
150
    int width = header.getWidth();
151
    int height = header.getHeight();
152
    int depth = header.getDepth();
153
 
154
    switch( header.getColorType() )
155
      {
156
      case PNGHeader.GRAYSCALE_WITH_ALPHA:
157
        if( depth == 8 )
158
          {
159
            t = DataBuffer.TYPE_BYTE;
160
            db = getByteBuffer();
161
          }
162
        else
163
          {
164
            t = DataBuffer.TYPE_USHORT;
165
            db = getShortBuffer();
166
          }
167
        sm = new ComponentSampleModel(t, width, height, 2, width * 2,
168
                                      new int[]{0, 1});
169
        break;
170
 
171
      case PNGHeader.GRAYSCALE:
172
        switch( depth )
173
          {
174
          case 16:
175
            sm = new ComponentSampleModel(DataBuffer.TYPE_USHORT,
176
                                          width, height, 1, width,
177
                                          new int[]{ 0 });
178
            db = getShortBuffer();
179
            break;
180
 
181
          case 8:
182
            sm = new ComponentSampleModel(DataBuffer.TYPE_BYTE,
183
                                          width, height, 1, width,
184
                                          new int[]{ 0 });
185
            db = getByteBuffer();
186
            break;
187
 
188
          default:
189
            sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
190
                                                 width, height, depth);
191
            db = getByteBuffer();
192
            break;
193
          }
194
        break;
195
 
196
      case PNGHeader.RGB:
197
        if( depth == 8 )
198
          {
199
            t = DataBuffer.TYPE_BYTE;
200
            db = getByteBuffer();
201
          }
202
        else
203
          {
204
            t = DataBuffer.TYPE_USHORT;
205
            db = getShortBuffer();
206
          }
207
        sm = new ComponentSampleModel(t, width, height, 3, 3 * width,
208
                                      new int[]{0, 1, 2});
209
        break;
210
 
211
      case PNGHeader.RGB_WITH_ALPHA:
212
        if( depth == 8 )
213
          {
214
            t = DataBuffer.TYPE_BYTE;
215
            db = getByteBuffer();
216
          }
217
        else
218
          {
219
            t = DataBuffer.TYPE_USHORT;
220
            db = getShortBuffer();
221
          }
222
 
223
        sm = new ComponentSampleModel(t, width, height, 4, width * 4,
224
                                      new int[]{0, 1, 2, 3});
225
        break;
226
 
227
      case PNGHeader.INDEXED:
228
        if( depth == 8 )
229
          sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE,
230
                                                width, height,
231
                                                new int[] {0xFF});
232
        else
233
          sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
234
                                               width, height, depth);
235
        db = getByteBuffer();
236
        break;
237
      }
238
 
239
    return Raster.createWritableRaster(sm, db, null);
240
  }
241
 
242
  /**
243
   * Wrap the raster with a DataBufferUShort,
244
   * conversion is big-endian (PNG native).
245
   */
246
  private DataBuffer getShortBuffer()
247
  {
248
    short[] data = new short[(raster.length >> 1)];
249
    for( int i = 0; i < data.length; i++ )
250
      data[i] = (short)(((raster[i * 2] & 0xFF) << 8) |
251
                        (raster[i * 2 + 1] & 0xFF));
252
    return new DataBufferUShort( data, data.length );
253
  }
254
 
255
  /**
256
   * Wrap the raster with a DataBufferByte
257
   */
258
  private DataBuffer getByteBuffer()
259
  {
260
    return new DataBufferByte( raster, raster.length );
261
  }
262
 
263
  public ColorModel getColorModel( ColorSpace cs,
264
                                   int colorType, int depth )
265
  {
266
    int[] bits;
267
    boolean hasAlpha = false;
268
    int transferType;
269
 
270
    switch( colorType )
271
      {
272
      case PNGHeader.GRAYSCALE_WITH_ALPHA:
273
        if( cs == null )
274
          cs = ColorSpace.getInstance( ColorSpace.CS_GRAY );
275
        hasAlpha = true;
276
        bits = new int[]{ depth, depth };
277
        break;
278
 
279
      case PNGHeader.RGB:
280
        bits = new int[]{ depth, depth, depth };
281
        break;
282
 
283
      case PNGHeader.RGB_WITH_ALPHA:
284
        hasAlpha = true;
285
        bits = new int[]{ depth, depth, depth, depth };
286
        break;
287
 
288
      case PNGHeader.GRAYSCALE:
289
        if( depth < 8 )
290
          return grayPalette( depth );
291
 
292
        if( cs == null )
293
          cs = ColorSpace.getInstance( ColorSpace.CS_GRAY );
294
        bits = new int[]{ depth };
295
        break;
296
 
297
      default:
298
      case PNGHeader.INDEXED:
299
        return null; // Handled by the palette chunk.
300
      }
301
 
302
    if( cs == null )
303
      cs = ColorSpace.getInstance( ColorSpace.CS_sRGB );
304
 
305
 
306
    return new ComponentColorModel(cs, bits, hasAlpha, false,
307
                                   (hasAlpha ?
308
                                    ComponentColorModel.TRANSLUCENT :
309
                                    ComponentColorModel.OPAQUE),
310
                                   ((depth == 16) ? DataBuffer.TYPE_USHORT :
311
                                    DataBuffer.TYPE_BYTE));
312
  }
313
 
314
  private IndexColorModel grayPalette(int depth)
315
  {
316
    byte[] c = new byte[ (1 << depth) ];
317
    for(int i = 0; i < c.length; i++)
318
      c[i] = (byte)(255.0 * (((double)i) / ((double)c.length - 1.0)));
319
    return new IndexColorModel(8, c.length, c, c, c);
320
  }
321
 
322
  public byte[] getRaster()
323
  {
324
    return raster;
325
  }
326
 
327
  public boolean isFinished()
328
  {
329
    return currentScanline >= header.getHeight();
330
  }
331
}

powered by: WebSVN 2.1.0

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