jdk/src/share/classes/sun/awt/image/PNGImageDecoder.java
author ohair
Tue, 28 Dec 2010 15:53:50 -0800
changeset 7668 d4a77089c587
parent 5820 4f5e99470724
child 22636 5bb85dc6771b
permissions -rw-r--r--
6962318: Update copyright year Reviewed-by: xdono
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
7668
d4a77089c587 6962318: Update copyright year
ohair
parents: 5820
diff changeset
     2
 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.awt.image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.zip.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.awt.image.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.awt.Color;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
/** PNG - Portable Network Graphics - image file reader.
5820
4f5e99470724 6967036: Need to fix links with // in Javadoc comments
ohair
parents: 5506
diff changeset
    35
    See <a href=http://www.ietf.org/rfc/rfc2083.txt>RFC2083</a> for details. */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
/* this is changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
public class PNGImageDecoder extends FilterInputStream implements Runnable
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
{ */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
public class PNGImageDecoder extends ImageDecoder
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
    private static final int GRAY=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
    private static final int PALETTE=1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    private static final int COLOR=2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    private static final int ALPHA=4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    private static final int bKGDChunk = 0x624B4744;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    private static final int cHRMChunk = 0x6348524D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    private static final int gAMAChunk = 0x67414D41;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    private static final int hISTChunk = 0x68495354;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    private static final int IDATChunk = 0x49444154;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    private static final int IENDChunk = 0x49454E44;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    private static final int IHDRChunk = 0x49484452;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    private static final int PLTEChunk = 0x504C5445;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    private static final int pHYsChunk = 0x70485973;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    private static final int sBITChunk = 0x73424954;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    private static final int tEXtChunk = 0x74455874;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    private static final int tIMEChunk = 0x74494D45;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    private static final int tRNSChunk = 0x74524E53;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    private static final int zTXtChunk = 0x7A545874;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    private int width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    private int height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    private int bitDepth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    private int colorType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    private int compressionMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    private int filterMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    private int interlaceMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    private int gamma = 100000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    private java.util.Hashtable properties;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
  /* this is not needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    ImageConsumer target;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    private ColorModel cm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    private byte[] red_map, green_map, blue_map, alpha_map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    private int transparentPixel = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    private byte[]  transparentPixel_16 = null; // we need 6 bytes to store 16bpp value
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    private static ColorModel greyModels[] = new ColorModel[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
  /* this is not needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     PNGImageDecoder next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    private void property(String key,Object value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        if(value==null) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        if(properties==null) properties=new java.util.Hashtable();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        properties.put(key,value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    private void property(String key,float value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        property(key,new Float(value));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    private final void pngassert(boolean b) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        if(!b) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            PNGException e = new PNGException("Broken file");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
            e.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
            throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    protected boolean handleChunk(int key, byte[] buf, int st, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        switch(key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
            case bKGDChunk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                Color c = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                switch(colorType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                    case COLOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
                    case COLOR|ALPHA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
                        pngassert(len==6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                        c = new Color(buf[st]&0xff,buf[st+2]&0xff,buf[st+4]&0xff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
                    case COLOR|PALETTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
                    case COLOR|PALETTE|ALPHA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
                        pngassert(len==1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                        int ix = buf[st]&0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                        pngassert(red_map!=null && ix<red_map.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                        c = new Color(red_map[ix]&0xff,green_map[ix]&0xff,blue_map[ix]&0xff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                    case GRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                    case GRAY|ALPHA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                        pngassert(len==2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                        int t = buf[st]&0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
                        c = new Color(t,t,t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
                if(c!=null) property("background",c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
            case cHRMChunk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                property("chromaticities",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                    new Chromaticities(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                        getInt(st),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                        getInt(st+4),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
                        getInt(st+8),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
                        getInt(st+12),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                        getInt(st+16),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                        getInt(st+20),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
                        getInt(st+24),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                        getInt(st+28)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
            case gAMAChunk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                if(len!=4) throw new PNGException("bogus gAMA");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                gamma = getInt(st);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                if(gamma!=100000) property("gamma",gamma/100000.0f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            case hISTChunk: break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            case IDATChunk: return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            case IENDChunk: break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            case IHDRChunk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
                if(len!=13
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                    ||(width = getInt(st))==0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                    ||(height = getInt(st+4))==0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                    ) throw new PNGException("bogus IHDR");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                bitDepth = getByte(st+8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                colorType = getByte(st+9);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
                compressionMethod = getByte(st+10);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                filterMethod = getByte(st+11);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                interlaceMethod = getByte(st+12);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                /* this is not needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                  if(target!=null) target.setDimensions(width,height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            case PLTEChunk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                {   int tsize = len/3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                    red_map = new byte[tsize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                    green_map = new byte[tsize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                    blue_map = new byte[tsize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                    for(int i=0,j=st; i<tsize; i++, j+=3) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                        red_map[i] = buf[j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
                        green_map[i] = buf[j+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
                        blue_map[i] = buf[j+2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            case pHYsChunk: break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
            case sBITChunk: break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            case tEXtChunk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                int klen = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                while(klen<len && buf[st+klen]!=0) klen++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                if(klen<len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
                    String tkey = new String(buf,st,klen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                    String tvalue = new String(buf,st+klen+1,len-klen-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                    property(tkey,tvalue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            case tIMEChunk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
                property("modtime",new GregorianCalendar(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                    getShort(st+0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
                    getByte(st+2)-1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
                    getByte(st+3),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
                    getByte(st+4),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                    getByte(st+5),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                    getByte(st+6)).getTime());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            case tRNSChunk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                switch(colorType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                    case PALETTE|COLOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                    case PALETTE|COLOR|ALPHA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                        int alen = len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                        if(red_map!=null) alen = red_map.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                        alpha_map = new byte[alen];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                        System.arraycopy(buf,st,alpha_map,0,len<alen ? len : alen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                        while (--alen>=len) alpha_map[alen] = (byte)0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                    case COLOR: // doesn't deal with 16 bit colors properly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                    case COLOR|ALPHA: // doesn't deal with 16 bit colors properly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                        pngassert(len==6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                        if (bitDepth == 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                            transparentPixel_16 = new byte[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                            for (int i = 0; i < 6; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                                transparentPixel_16[i] = (byte)getByte(st + i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                            transparentPixel =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                                      ((getShort(st + 0)&0xFF)<<16)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                                    | ((getShort(st + 2)&0xFF)<< 8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                                    | ((getShort(st + 4)&0xFF)    );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                    case GRAY:  // doesn't deal with 16 bit colors properly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                    case GRAY|ALPHA:  // doesn't deal with 16 bit colors properly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                        pngassert(len==2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                        /* REMIND: Discarding the LSB for 16 bit depth here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                         * means that the all pixels which match the MSB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                         * will be treated as transparent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                        int t = getShort(st);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                        t = 0xFF & ((bitDepth == 16) ? (t >> 8) : t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                        transparentPixel = (t<<16) | (t<< 8) | t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            case zTXtChunk: break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    public class PNGException extends IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        PNGException(String s) { super(s); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
  /* this is changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
  public void produceImage() throws IOException, ImageFormatException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    /* this is not needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
       ImageConsumer t = target;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
       if(t!=null) try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
       */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            for(int i=0; i<signature.length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
              if((signature[i]&0xFF)!=underlyingInputStream.read())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                throw new PNGException("Chunk signature mismatch");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            InputStream is = new BufferedInputStream(new InflaterInputStream(inputStream,new Inflater()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            byte[] bPixels = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            int[] wPixels = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            int pixSize = width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            int rowStride;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            int logDepth = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            switch(bitDepth) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                case  1: logDepth = 0; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                case  2: logDepth = 1; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                case  4: logDepth = 2; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                case  8: logDepth = 3; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                case 16: logDepth = 4; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                default: throw new PNGException("invalid depth");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            if(interlaceMethod!=0) {pixSize *= height;rowStride=width;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            else rowStride = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            int combinedType = colorType|(bitDepth<<3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            int bitMask = (1<<(bitDepth>=8?8:bitDepth))-1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            //Figure out the color model
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            switch(colorType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                case COLOR|PALETTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                case COLOR|PALETTE|ALPHA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                    if(red_map==null) throw new PNGException("palette expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                    if(alpha_map==null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
                        cm = new IndexColorModel(bitDepth,red_map.length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                            red_map,green_map,blue_map);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                        cm = new IndexColorModel(bitDepth,red_map.length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                            red_map,green_map,blue_map,alpha_map);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                    bPixels = new byte[pixSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                case GRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                    {   int llog = logDepth>=4 ? 3 : logDepth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                        if((cm=greyModels[llog]) == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                            int size = 1<<(1<<llog);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                            byte ramp[] = new byte[size];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                            for(int i = 0; i<size; i++) ramp[i] = (byte)(255*i/(size-1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                            if (transparentPixel == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                                cm = new IndexColorModel(bitDepth,ramp.length,ramp,ramp,ramp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                                cm = new IndexColorModel(bitDepth,ramp.length,ramp,ramp,ramp,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                                                         (transparentPixel & 0xFF));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                            greyModels[llog] = cm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                    bPixels = new byte[pixSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                case COLOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                case COLOR|ALPHA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                case GRAY|ALPHA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                    cm = ColorModel.getRGBdefault();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                    wPixels = new int[pixSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                    throw new PNGException("invalid color type");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            /* this is going to be set in the pixel store
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
              t.setColorModel(cm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            t.setHints(interlaceMethod !=0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                       ? ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                       : ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                         ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            // code added to make it work with ImageDecoder architecture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            setDimensions(width, height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            setColorModel(cm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            int flags = (interlaceMethod !=0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                       ? ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                       : ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                         ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            setHints(flags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            headerComplete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
            // end of adding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            int samplesPerPixel = ((colorType&PALETTE)!=0 ? 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                                 : ((colorType&COLOR)!=0 ? 3 : 1)+((colorType&ALPHA)!=0?1:0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            int bitsPerPixel = samplesPerPixel*bitDepth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            int bytesPerPixel = (bitsPerPixel+7)>>3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
            int pass, passLimit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            if(interlaceMethod==0) { pass = -1; passLimit = 0; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            else { pass = 0; passLimit = 7; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            // These loops are far from being tuned.  They're this way to make them easy to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            // debug.  Tuning comes later.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            /* code changed. target not needed here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
               while(++pass<=passLimit && (t=target)!=null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
               */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            while(++pass<=passLimit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                int row = startingRow[pass];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                int rowInc = rowIncrement[pass];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                int colInc = colIncrement[pass];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                int bWidth = blockWidth[pass];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                int bHeight = blockHeight[pass];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                int sCol = startingCol[pass];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                int rowPixelWidth = (width-sCol+(colInc-1))/colInc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                int rowByteWidth = ((rowPixelWidth*bitsPerPixel)+7)>>3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                if(rowByteWidth==0) continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                int pixelBufferInc = interlaceMethod==0 ? rowInc*width : 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                int rowOffset = rowStride*row;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                boolean firstRow = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                byte[] rowByteBuffer = new byte[rowByteWidth];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                byte[] prevRowByteBuffer = new byte[rowByteWidth];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                /* code changed. target not needed here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                   while (row < height && (t=target)!=null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                   */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                while (row < height) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                    int rowFilter = is.read();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                    for (int rowFillPos=0;rowFillPos<rowByteWidth; ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                        int n = is.read(rowByteBuffer,rowFillPos,rowByteWidth-rowFillPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                        if(n<=0) throw new PNGException("missing data");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                        rowFillPos+=n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                    filterRow(rowByteBuffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                              firstRow ? null : prevRowByteBuffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                              rowFilter, rowByteWidth, bytesPerPixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                    int col = sCol;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                    int spos=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                    int pixel = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                    while (col < width) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                        if(wPixels !=null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                            switch(combinedType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                                case COLOR|ALPHA|(8<<3):
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                                    wPixels[col+rowOffset] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                                          ((rowByteBuffer[spos  ]&0xFF)<<16)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                                        | ((rowByteBuffer[spos+1]&0xFF)<< 8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                                        | ((rowByteBuffer[spos+2]&0xFF)    )
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                                        | ((rowByteBuffer[spos+3]&0xFF)<<24);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                                    spos+=4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                                case COLOR|ALPHA|(16<<3):
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                                    wPixels[col+rowOffset] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                                          ((rowByteBuffer[spos  ]&0xFF)<<16)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                                        | ((rowByteBuffer[spos+2]&0xFF)<< 8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                                        | ((rowByteBuffer[spos+4]&0xFF)    )
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                                        | ((rowByteBuffer[spos+6]&0xFF)<<24);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
                                    spos+=8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                                case COLOR|(8<<3):
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
                                    pixel =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                                          ((rowByteBuffer[spos  ]&0xFF)<<16)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                                        | ((rowByteBuffer[spos+1]&0xFF)<< 8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                                        | ((rowByteBuffer[spos+2]&0xFF)    );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                                    if (pixel != transparentPixel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                                        pixel |= 0xff000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                                    wPixels[col+rowOffset] = pixel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                                    spos+=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                                case COLOR|(16<<3):
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                                    pixel =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                                              ((rowByteBuffer[spos  ]&0xFF)<<16)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                                            | ((rowByteBuffer[spos+2]&0xFF)<< 8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                                            | ((rowByteBuffer[spos+4]&0xFF)    );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                                    boolean isTransparent = (transparentPixel_16 != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                                    for (int i = 0; isTransparent && (i < 6); i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                                        isTransparent &=
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                                                (rowByteBuffer[spos + i] & 0xFF) == (transparentPixel_16[i] & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                                    if (!isTransparent)  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                                        pixel |= 0xff000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                                    wPixels[col+rowOffset] = pixel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                                    spos+=6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                                case GRAY|ALPHA|(8<<3):
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                                    { int tx = rowByteBuffer[spos]&0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                                      wPixels[col+rowOffset] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                                          (tx<<16)|(tx<<8)|tx
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
                                        |((rowByteBuffer[spos+1]&0xFF)<<24); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
                                    spos+=2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
                                case GRAY|ALPHA|(16<<3):
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
                                    { int tx = rowByteBuffer[spos]&0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
                                      wPixels[col+rowOffset] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                                          (tx<<16)|(tx<<8)|tx
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                                        |((rowByteBuffer[spos+2]&0xFF)<<24); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
                                    spos+=4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                                default: throw new PNGException("illegal type/depth");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                        } else switch(bitDepth) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                            case 1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                                bPixels[col+rowOffset] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                                    (byte)((rowByteBuffer[spos>>3]>>(7-(spos&7)))&1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                                spos++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                            case 2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                                bPixels[col+rowOffset] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                                    (byte)((rowByteBuffer[spos>>2]>>((3-(spos&3))*2))&3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                                spos++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                            case 4:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                                bPixels[col+rowOffset] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                                    (byte)((rowByteBuffer[spos>>1]>>((1-(spos&1))*4))&15);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                                spos++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                            case 8: bPixels[col+rowOffset] = rowByteBuffer[spos++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                            case 16: bPixels[col+rowOffset] = rowByteBuffer[spos]; spos+=2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                            default: throw new PNGException("illegal type/depth");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                        /*visit (row, col,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                            min (bHeight, height - row),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                            min (bWidth, width - col)); */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                        col += colInc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                    if(interlaceMethod==0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                      if(wPixels!=null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                        /* code changed. target not needed here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                          t.setPixels(0,row,width,1,cm,wPixels,0,width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                          */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                       // code added to make it work with ImageDecoder arch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                        sendPixels(0,row,width,1,wPixels,0,width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                        // end of adding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                      else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                        /* code changed. target not needed here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                           t.setPixels(0,row,width,1,cm,bPixels,0,width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                           */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                        // code added to make it work with ImageDecoder arch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                        sendPixels(0,row,width,1,bPixels,0,width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                        //end of adding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                    row += rowInc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                    rowOffset += rowInc*rowStride;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                    byte[] T = rowByteBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                    rowByteBuffer = prevRowByteBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                    prevRowByteBuffer = T;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                    firstRow = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                if(interlaceMethod!=0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                  if(wPixels!=null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                    /* code changed. target not needed here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                       t.setPixels(0,0,width,height,cm,wPixels,0,width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                       */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                    // code added to make it work with ImageDecoder arch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                      sendPixels(0,0,width,height,wPixels,0,width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                      //end of adding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                  else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                     /* code changed. target not needed here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                        t.setPixels(0,0,width,height,cm,bPixels,0,width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                    // code added to make it work with ImageDecoder arch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                      sendPixels(0,0,width,height,bPixels,0,width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                      //end of adding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
   /* Here, the function "visit(row,column,height,width)" obtains the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
      next transmitted pixel and paints a rectangle of the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
      height and width, whose upper-left corner is at the specified row
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
      and column, using the color indicated by the pixel.  Note that row
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
      and column are measured from 0,0 at the upper left corner. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            /* code not needed, don't deal with target
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
             if((t=target)!=null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
               if(properties!=null) t.setProperties(properties);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                 t.imageComplete(ImageConsumer.STATICIMAGEDONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
              imageComplete(ImageConsumer.STATICIMAGEDONE, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
              /* code not needed }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
               is.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
               */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        } catch(IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            if(!aborted) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                /* code not needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                   if((t=target)!=null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                   PNGEncoder.prChunk(e.toString(),inbuf,pos,limit-pos,true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                property("error", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
                /* code not needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                   t.setProperties(properties);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                   t.imageComplete(ImageConsumer.IMAGEERROR|ImageConsumer.STATICIMAGEDONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                imageComplete(ImageConsumer.IMAGEERROR|ImageConsumer.STATICIMAGEDONE, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
          try { close(); } catch(Throwable e){}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
          /* code not needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
             target = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
             endTurn();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    private boolean sendPixels(int x, int y, int w, int h, int[] pixels,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                               int offset, int pixlength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        int count = setPixels(x, y, w, h, cm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                              pixels, offset, pixlength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        if (count <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            aborted = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
        return !aborted;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
    private boolean sendPixels(int x, int y, int w, int h, byte[] pixels,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                               int offset, int pixlength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        int count = setPixels(x, y, w, h, cm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                              pixels, offset, pixlength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
        if (count <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
            aborted = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
        return !aborted;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    private void filterRow(byte rowByteBuffer[], byte[] prevRow,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                           int rowFilter, int rowByteWidth, int bytesPerSample)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        int x = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
        switch (rowFilter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
          case 0:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
          case 1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            for (x = bytesPerSample; x < rowByteWidth; x++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                rowByteBuffer[x] += rowByteBuffer[x - bytesPerSample];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
          case 2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
            if (prevRow != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
                for ( ; x < rowByteWidth; x++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                    rowByteBuffer[x] += prevRow[x];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
          case 3:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            if (prevRow != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                for ( ; x < bytesPerSample; x++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                    rowByteBuffer[x] += (0xff & prevRow[x])>>1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                for ( ; x < rowByteWidth; x++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                    rowByteBuffer[x] += ((prevRow[x]&0xFF) + (rowByteBuffer[x - bytesPerSample]&0xFF))>>1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            } else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                for (x = bytesPerSample; x < rowByteWidth; x++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                    rowByteBuffer[x] += (rowByteBuffer[x - bytesPerSample]&0xFF)>>1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
          case 4:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            if (prevRow != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                for ( ; x < bytesPerSample; x++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
                    rowByteBuffer[x] += prevRow[x];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                for ( ; x < rowByteWidth; x++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                    int a, b, c, p, pa, pb, pc, rval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
                    a = rowByteBuffer[x - bytesPerSample]&0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                    b = prevRow[x]&0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                    c = prevRow[x - bytesPerSample]&0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                    p = a + b - c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                    pa = p > a ? p - a : a - p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                    pb = p > b ? p - b : b - p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
                    pc = p > c ? p - c : c - p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                    rowByteBuffer[x] += (pa <= pb) && (pa <= pc) ? a : pb <= pc ? b : c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            } else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                for (x = bytesPerSample; x < rowByteWidth; x++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                    rowByteBuffer[x] += rowByteBuffer[x - bytesPerSample];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            throw new PNGException("Illegal filter");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
    private static final byte[] startingRow =  { 0, 0, 0, 4, 0, 2, 0, 1 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    private static final byte[] startingCol =  { 0, 0, 4, 0, 2, 0, 1, 0 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    private static final byte[] rowIncrement = { 1, 8, 8, 8, 4, 4, 2, 2 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    private static final byte[] colIncrement = { 1, 8, 8, 4, 4, 2, 2, 1 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    private static final byte[] blockHeight =  { 1, 8, 8, 4, 4, 2, 2, 1 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    private static final byte[] blockWidth =   { 1, 8, 4, 4, 2, 2, 1, 1 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    //abstract public class ChunkReader extends FilterInputStream {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
  int pos, limit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    int chunkStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
   int chunkKey, chunkLength, chunkCRC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    boolean seenEOF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    private static final byte[] signature = { (byte) 137, (byte) 80, (byte) 78,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        (byte) 71, (byte) 13, (byte) 10, (byte) 26, (byte) 10 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
  PNGFilterInputStream inputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
  InputStream underlyingInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
  /* code changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    public PNGImageDecoder(InputStream in, ImageConsumer t) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
  public PNGImageDecoder(InputStreamImageSource src, InputStream input) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
    // code added
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    super(src, input);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
    inputStream = new PNGFilterInputStream(this, input);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
    underlyingInputStream = inputStream.underlyingInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    // end of adding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    /* code changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
       super(in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
       target = t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
       waitTurn();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
       new Thread(this).start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
       */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
  /* code changed to make it work with ImageDecoder architecture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
    static int ThreadLimit = 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    private synchronized static void waitTurn() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            while(ThreadLimit<=0) PNGImageDecoder.class.wait(1000);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
        } catch(InterruptedException e){}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
        ThreadLimit--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
    private synchronized static void endTurn() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        if(ThreadLimit<=0) PNGImageDecoder.class.notify();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        ThreadLimit++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    byte[] inbuf = new byte[4096];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
    private void fill() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        if(!seenEOF) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
            if(pos>0 && pos<limit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                System.arraycopy(inbuf,pos,inbuf,0,limit-pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                limit = limit-pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
                pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
            } else if(pos>=limit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                pos = 0; limit = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
            int bsize = inbuf.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
            while(limit<bsize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
                int n = underlyingInputStream.read(inbuf,limit,bsize-limit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                if(n<=0) { seenEOF=true; break; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                limit += n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    private boolean need(int n) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        if(limit-pos>=n) return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        fill();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
        if(limit-pos>=n) return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
        if(seenEOF) return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        byte nin[] = new byte[n+100];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
        System.arraycopy(inbuf,pos,nin,0,limit-pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
        limit = limit-pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
        pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        inbuf = nin;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        fill();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
        return limit-pos>=n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    private final int getInt(int pos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
        return ((inbuf[pos  ]&0xFF)<<24)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
             | ((inbuf[pos+1]&0xFF)<<16)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
             | ((inbuf[pos+2]&0xFF)<< 8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
             | ((inbuf[pos+3]&0xFF)    );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
    private final int getShort(int pos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        return (short)(((inbuf[pos  ]&0xFF)<<8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                     | ((inbuf[pos+1]&0xFF)   ));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
    private final int getByte(int pos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        return inbuf[pos]&0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
    private final boolean getChunk() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
        chunkLength = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        if (!need(8)) return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        chunkLength = getInt(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        chunkKey = getInt(pos+4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        if(chunkLength<0) throw new PNGException("bogus length: "+chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        if (!need(chunkLength+12)) return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        chunkCRC = getInt(pos+8+chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        chunkStart = pos+8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        int calcCRC = crc(inbuf,pos+4,chunkLength+4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        if(chunkCRC!=calcCRC && checkCRC) throw new PNGException("crc corruption");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        pos+=chunkLength+12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
    private void readAll() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        while(getChunk()) handleChunk(chunkKey,inbuf,chunkStart,chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
    boolean getData() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        while(chunkLength==0 && getChunk())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
            if(handleChunk(chunkKey,inbuf,chunkStart,chunkLength))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
                chunkLength = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        return chunkLength>0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
    //abstract protected boolean handleChunk(int key, byte[] buf, int st, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
    //    throws IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
    private static boolean checkCRC = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    public static boolean getCheckCRC() { return checkCRC; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
    public static void setCheckCRC(boolean c) { checkCRC = c; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
    protected void wrc(int c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        c = c&0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        if(c<=' '||c>'z') c = '?';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        System.out.write(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
    protected void wrk(int n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        wrc(n>>24);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        wrc(n>>16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        wrc(n>>8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
        wrc(n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    public void print() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        wrk(chunkKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        System.out.print(" "+chunkLength+"\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    /* Table of CRCs of all 8-bit messages. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
    private static final int[] crc_table = new int[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    /* Make the table for a fast CRC. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        for (int n = 0; n < 256; n++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
            int c = n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
            for (int k = 0; k < 8; k++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                if ((c & 1) != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                    c = 0xedb88320 ^ (c >>> 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                    c = c >>> 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            crc_table[n] = c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
    /* Update a running CRC with the bytes buf[0..len-1]--the CRC
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
    should be initialized to all 1's, and the transmitted value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    is the 1's complement of the final running CRC (see the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    crc() routine below)). */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
    static private int update_crc(int crc, byte[] buf, int offset, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        int c = crc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        while (--len>=0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
            c = crc_table[(c ^ buf[offset++]) & 0xff] ^ (c >>> 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
        return c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    /* Return the CRC of the bytes buf[0..len-1]. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
    static private int crc(byte[] buf, int offset, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        return update_crc(0xffffffff, buf, offset, len) ^ 0xffffffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
    public static class Chromaticities {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
        public float whiteX, whiteY, redX, redY, greenX, greenY, blueX, blueY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        Chromaticities(int wx, int wy, int rx, int ry, int gx, int gy, int bx, int by) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
            whiteX = wx/100000.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
            whiteY = wy/100000.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
            redX = rx/100000.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
            redY = ry/100000.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
            greenX = gx/100000.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
            greenY = gy/100000.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
            blueX = bx/100000.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
            blueY = by/100000.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
            return "Chromaticities(white="+whiteX+","+whiteY+";red="+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
                redX+","+redY+";green="+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                greenX+","+greenY+";blue="+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                blueX+","+blueY+")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
// the following class are added to make it work with ImageDecoder architecture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
class PNGFilterInputStream extends FilterInputStream {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
  PNGImageDecoder owner;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
  public InputStream underlyingInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
  public PNGFilterInputStream(PNGImageDecoder owner, InputStream is) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
    super(is);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
    underlyingInputStream = in;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
    this.owner = owner;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
    public int available() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
        return owner.limit-owner.pos+in.available();}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
    public boolean markSupported() { return false; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
    public int read() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        if(owner.chunkLength<=0) if(!owner.getData()) return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
        owner.chunkLength--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
        return owner.inbuf[owner.chunkStart++]&0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
    public int read(byte[] b) throws IOException{return read(b,0,b.length);}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
    public int read(byte[] b, int st, int len) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        if(owner.chunkLength<=0) if(!owner.getData()) return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
        if(owner.chunkLength<len) len = owner.chunkLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
        System.arraycopy(owner.inbuf,owner.chunkStart,b,st,len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        owner.chunkLength-=len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
        owner.chunkStart+=len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
        return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
  public long skip(long n) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        for(i = 0; i<n && read()>=0; i++);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        return i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
}