src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java
author jdv
Tue, 30 Jan 2018 11:53:00 +0530
changeset 48728 fb62f481671e
parent 48645 6cfee3ad7a76
child 49995 6f595ec05539
permissions -rw-r--r--
8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size Reviewed-by: serb, pnarayanan
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
48645
6cfee3ad7a76 8191174: PngReader throws IllegalArgumentException because ScanlineStride calculation logic is not proper
jdv
parents: 48641
diff changeset
     2
 * Copyright (c) 2000, 2018, 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: 2376
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: 2376
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: 2376
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2376
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2376
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 com.sun.imageio.plugins.png;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.Point;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.Rectangle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.color.ColorSpace;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.awt.image.BufferedImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.awt.image.DataBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.awt.image.DataBufferByte;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.awt.image.DataBufferUShort;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.awt.image.Raster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.awt.image.WritableRaster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.io.BufferedInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.io.ByteArrayInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.io.DataInputStream;
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
    40
import java.io.EOFException;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.io.InputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.io.SequenceInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.util.ArrayList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import java.util.Arrays;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import java.util.Enumeration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import java.util.Iterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
import java.util.zip.Inflater;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
import java.util.zip.InflaterInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
import javax.imageio.IIOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
import javax.imageio.ImageReader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
import javax.imageio.ImageReadParam;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
import javax.imageio.ImageTypeSpecifier;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
import javax.imageio.metadata.IIOMetadata;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
import javax.imageio.spi.ImageReaderSpi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
import javax.imageio.stream.ImageInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
import com.sun.imageio.plugins.common.InputStreamAdapter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
import com.sun.imageio.plugins.common.ReaderUtil;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
import com.sun.imageio.plugins.common.SubImageInputStream;
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
    60
import java.io.ByteArrayOutputStream;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
import sun.awt.image.ByteInterleavedRaster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
    63
class PNGImageDataEnumeration implements Enumeration<InputStream> {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    boolean firstTime = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    ImageInputStream stream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    int length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    public PNGImageDataEnumeration(ImageInputStream stream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        this.stream = stream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        this.length = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        int type = stream.readInt(); // skip chunk type
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
    76
    public InputStream nextElement() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
            firstTime = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
            ImageInputStream iis = new SubImageInputStream(stream, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
            return new InputStreamAdapter(iis);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    public boolean hasMoreElements() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        if (firstTime) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
            int crc = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
            this.length = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            int type = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
            if (type == PNGImageReader.IDAT_TYPE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
public class PNGImageReader extends ImageReader {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * Note: The following chunk type constants are autogenerated.  Each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * one is derived from the ASCII values of its 4-character name.  For
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * example, IHDR_TYPE is calculated as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     *            ('I' << 24) | ('H' << 16) | ('D' << 8) | 'R'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    // Critical chunks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    static final int IHDR_TYPE = 0x49484452;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    static final int PLTE_TYPE = 0x504c5445;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    static final int IDAT_TYPE = 0x49444154;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    static final int IEND_TYPE = 0x49454e44;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    // Ancillary chunks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    static final int bKGD_TYPE = 0x624b4744;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    static final int cHRM_TYPE = 0x6348524d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    static final int gAMA_TYPE = 0x67414d41;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    static final int hIST_TYPE = 0x68495354;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    static final int iCCP_TYPE = 0x69434350;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    static final int iTXt_TYPE = 0x69545874;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    static final int pHYs_TYPE = 0x70485973;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    static final int sBIT_TYPE = 0x73424954;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    static final int sPLT_TYPE = 0x73504c54;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    static final int sRGB_TYPE = 0x73524742;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    static final int tEXt_TYPE = 0x74455874;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    static final int tIME_TYPE = 0x74494d45;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    static final int tRNS_TYPE = 0x74524e53;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    static final int zTXt_TYPE = 0x7a545874;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    static final int PNG_COLOR_GRAY = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    static final int PNG_COLOR_RGB = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    static final int PNG_COLOR_PALETTE = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    static final int PNG_COLOR_GRAY_ALPHA = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    static final int PNG_COLOR_RGB_ALPHA = 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    // The number of bands by PNG color type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    static final int[] inputBandsForColorType = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
         1, // gray
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        -1, // unused
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
         3, // rgb
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
         1, // palette
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
         2, // gray + alpha
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        -1, // unused
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
         4  // rgb + alpha
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    static final int PNG_FILTER_NONE = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    static final int PNG_FILTER_SUB = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    static final int PNG_FILTER_UP = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    static final int PNG_FILTER_AVERAGE = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    static final int PNG_FILTER_PAETH = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    static final int[] adam7XOffset = { 0, 4, 0, 2, 0, 1, 0 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    static final int[] adam7YOffset = { 0, 0, 4, 0, 2, 0, 1 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    static final int[] adam7XSubsampling = { 8, 8, 4, 4, 2, 2, 1, 1 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    static final int[] adam7YSubsampling = { 8, 8, 8, 4, 4, 2, 2, 1 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    private static final boolean debug = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    ImageInputStream stream = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    boolean gotHeader = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    boolean gotMetadata = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    ImageReadParam lastParam = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    long imageStartPosition = -1L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    Rectangle sourceRegion = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    int sourceXSubsampling = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    int sourceYSubsampling = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    int sourceMinProgressivePass = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    int sourceMaxProgressivePass = 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    int[] sourceBands = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    int[] destinationBands = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    Point destinationOffset = new Point(0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    PNGMetadata metadata = new PNGMetadata();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    DataInputStream pixelStream = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    BufferedImage theImage = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    // The number of source pixels processed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    int pixelsDone = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    // The total number of pixels in the source image
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    int totalPixels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    public PNGImageReader(ImageReaderSpi originatingProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        super(originatingProvider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    public void setInput(Object input,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                         boolean seekForwardOnly,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                         boolean ignoreMetadata) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        super.setInput(input, seekForwardOnly, ignoreMetadata);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        this.stream = (ImageInputStream)input; // Always works
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        // Clear all values based on the previous stream contents
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        resetStreamSettings();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   211
    private String readNullTerminatedString(String charset, int maxLen) throws IOException {
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   212
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   213
        int b;
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   214
        int count = 0;
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   215
        while ((maxLen > count++) && ((b = stream.read()) != 0)) {
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   216
            if (b == -1) throw new EOFException();
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   217
            baos.write(b);
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   218
        }
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   219
        return new String(baos.toByteArray(), charset);
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   220
    }
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   221
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    private void readHeader() throws IIOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        if (gotHeader) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        if (stream == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
            throw new IllegalStateException("Input source not set!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            byte[] signature = new byte[8];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            stream.readFully(signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            if (signature[0] != (byte)137 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                signature[1] != (byte)80 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                signature[2] != (byte)78 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                signature[3] != (byte)71 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                signature[4] != (byte)13 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                signature[5] != (byte)10 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                signature[6] != (byte)26 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                signature[7] != (byte)10) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                throw new IIOException("Bad PNG signature!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            int IHDR_length = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            if (IHDR_length != 13) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                throw new IIOException("Bad length for IHDR chunk!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            int IHDR_type = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            if (IHDR_type != IHDR_TYPE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                throw new IIOException("Bad type for IHDR chunk!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            this.metadata = new PNGMetadata();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            int width = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            int height = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            // Re-use signature array to bulk-read these unsigned byte values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            stream.readFully(signature, 0, 5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            int bitDepth          = signature[0] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            int colorType         = signature[1] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            int compressionMethod = signature[2] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            int filterMethod      = signature[3] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            int interlaceMethod   = signature[4] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            // Skip IHDR CRC
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            stream.skipBytes(4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            stream.flushBefore(stream.getStreamPosition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
47836
f17a797c910a 8190512: PngReader incorrectly throws IllegalArgumentException for malformed images with negative dimensions
jdv
parents: 47216
diff changeset
   272
            if (width <= 0) {
f17a797c910a 8190512: PngReader incorrectly throws IllegalArgumentException for malformed images with negative dimensions
jdv
parents: 47216
diff changeset
   273
                throw new IIOException("Image width <= 0!");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            }
47836
f17a797c910a 8190512: PngReader incorrectly throws IllegalArgumentException for malformed images with negative dimensions
jdv
parents: 47216
diff changeset
   275
            if (height <= 0) {
f17a797c910a 8190512: PngReader incorrectly throws IllegalArgumentException for malformed images with negative dimensions
jdv
parents: 47216
diff changeset
   276
                throw new IIOException("Image height <= 0!");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                bitDepth != 8 && bitDepth != 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                throw new IIOException("Bit depth must be 1, 2, 4, 8, or 16!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            if (colorType != 0 && colorType != 2 && colorType != 3 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                colorType != 4 && colorType != 6) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                throw new IIOException("Color type must be 0, 2, 3, 4, or 6!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            if (colorType == PNG_COLOR_PALETTE && bitDepth == 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                throw new IIOException("Bad color type/bit depth combination!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            if ((colorType == PNG_COLOR_RGB ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                 colorType == PNG_COLOR_RGB_ALPHA ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                 colorType == PNG_COLOR_GRAY_ALPHA) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                (bitDepth != 8 && bitDepth != 16)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                throw new IIOException("Bad color type/bit depth combination!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            if (compressionMethod != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                throw new IIOException("Unknown compression method (not 0)!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            if (filterMethod != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                throw new IIOException("Unknown filter method (not 0)!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            if (interlaceMethod != 0 && interlaceMethod != 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                throw new IIOException("Unknown interlace method (not 0 or 1)!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            metadata.IHDR_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            metadata.IHDR_width = width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            metadata.IHDR_height = height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            metadata.IHDR_bitDepth = bitDepth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            metadata.IHDR_colorType = colorType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            metadata.IHDR_compressionMethod = compressionMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            metadata.IHDR_filterMethod = filterMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            metadata.IHDR_interlaceMethod = interlaceMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            gotHeader = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            throw new IIOException("I/O error reading PNG header!", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    private void parse_PLTE_chunk(int chunkLength) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        if (metadata.PLTE_present) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            processWarningOccurred(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
"A PNG image may not contain more than one PLTE chunk.\n" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
"The chunk wil be ignored.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        } else if (metadata.IHDR_colorType == PNG_COLOR_GRAY ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                   metadata.IHDR_colorType == PNG_COLOR_GRAY_ALPHA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            processWarningOccurred(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
"A PNG gray or gray alpha image cannot have a PLTE chunk.\n" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
"The chunk wil be ignored.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        byte[] palette = new byte[chunkLength];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        stream.readFully(palette);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        int numEntries = chunkLength/3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        if (metadata.IHDR_colorType == PNG_COLOR_PALETTE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            int maxEntries = 1 << metadata.IHDR_bitDepth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            if (numEntries > maxEntries) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                processWarningOccurred(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
"PLTE chunk contains too many entries for bit depth, ignoring extras.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                numEntries = maxEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            numEntries = Math.min(numEntries, maxEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        // Round array sizes up to 2^2^n
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        int paletteEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        if (numEntries > 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            paletteEntries = 256;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        } else if (numEntries > 4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            paletteEntries = 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        } else if (numEntries > 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            paletteEntries = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            paletteEntries = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        metadata.PLTE_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        metadata.PLTE_red = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        metadata.PLTE_green = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        metadata.PLTE_blue = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        int index = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        for (int i = 0; i < numEntries; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            metadata.PLTE_red[i] = palette[index++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            metadata.PLTE_green[i] = palette[index++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            metadata.PLTE_blue[i] = palette[index++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    private void parse_bKGD_chunk() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        if (metadata.IHDR_colorType == PNG_COLOR_PALETTE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            metadata.bKGD_colorType = PNG_COLOR_PALETTE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
            metadata.bKGD_index = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        } else if (metadata.IHDR_colorType == PNG_COLOR_GRAY ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                   metadata.IHDR_colorType == PNG_COLOR_GRAY_ALPHA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            metadata.bKGD_colorType = PNG_COLOR_GRAY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            metadata.bKGD_gray = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        } else { // RGB or RGB_ALPHA
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            metadata.bKGD_colorType = PNG_COLOR_RGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            metadata.bKGD_red = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
            metadata.bKGD_green = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            metadata.bKGD_blue = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        metadata.bKGD_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    private void parse_cHRM_chunk() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        metadata.cHRM_whitePointX = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        metadata.cHRM_whitePointY = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        metadata.cHRM_redX = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        metadata.cHRM_redY = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        metadata.cHRM_greenX = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        metadata.cHRM_greenY = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        metadata.cHRM_blueX = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        metadata.cHRM_blueY = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        metadata.cHRM_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    private void parse_gAMA_chunk() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        int gamma = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        metadata.gAMA_gamma = gamma;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        metadata.gAMA_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    private void parse_hIST_chunk(int chunkLength) throws IOException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        IIOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        if (!metadata.PLTE_present) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
            throw new IIOException("hIST chunk without prior PLTE chunk!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        /* According to PNG specification length of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
         * hIST chunk is specified in bytes and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
         * hIST chunk consists of 2 byte elements
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
         * (so we expect length is even).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        metadata.hIST_histogram = new char[chunkLength/2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        stream.readFully(metadata.hIST_histogram,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                         0, metadata.hIST_histogram.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        metadata.hIST_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    private void parse_iCCP_chunk(int chunkLength) throws IOException {
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   430
        String keyword = readNullTerminatedString("ISO-8859-1", 80);
48728
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   431
        int compressedProfileLength = chunkLength - keyword.length() - 2;
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   432
        if (compressedProfileLength <= 0) {
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   433
            throw new IIOException("iCCP chunk length is not proper");
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   434
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        metadata.iCCP_profileName = keyword;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        metadata.iCCP_compressionMethod = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        byte[] compressedProfile =
48728
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   440
          new byte[compressedProfileLength];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        stream.readFully(compressedProfile);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        metadata.iCCP_compressedProfile = compressedProfile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        metadata.iCCP_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    private void parse_iTXt_chunk(int chunkLength) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        long chunkStart = stream.getStreamPosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   450
        String keyword = readNullTerminatedString("ISO-8859-1", 80);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        metadata.iTXt_keyword.add(keyword);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        int compressionFlag = stream.readUnsignedByte();
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   454
        metadata.iTXt_compressionFlag.add(Boolean.valueOf(compressionFlag == 1));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        int compressionMethod = stream.readUnsignedByte();
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   457
        metadata.iTXt_compressionMethod.add(Integer.valueOf(compressionMethod));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   459
        String languageTag = readNullTerminatedString("UTF8", 80);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        metadata.iTXt_languageTag.add(languageTag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   462
        long pos = stream.getStreamPosition();
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   463
        int maxLen = (int)(chunkStart + chunkLength - pos);
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   464
        String translatedKeyword =
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   465
            readNullTerminatedString("UTF8", maxLen);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        metadata.iTXt_translatedKeyword.add(translatedKeyword);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        String text;
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   469
        pos = stream.getStreamPosition();
48728
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   470
        int textLength = (int)(chunkStart + chunkLength - pos);
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   471
        if (textLength <= 0) {
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   472
            throw new IIOException("iTXt chunk length is not proper");
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   473
        }
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   474
        byte[] b = new byte[textLength];
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   475
        stream.readFully(b);
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   476
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        if (compressionFlag == 1) { // Decompress the text
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   478
            text = new String(inflate(b), "UTF8");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        } else {
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   480
            text = new String(b, "UTF8");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        metadata.iTXt_text.add(text);
47197
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   483
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   484
        // Check if the text chunk contains image creation time
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   485
        if (keyword.equals(PNGMetadata.tEXt_creationTimeKey)) {
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   486
            // Update Standard/Document/ImageCreationTime from text chunk
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   487
            int index = metadata.iTXt_text.size() - 1;
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   488
            metadata.decodeImageCreationTimeFromTextChunk(
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   489
                    metadata.iTXt_text.listIterator(index));
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   490
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    private void parse_pHYs_chunk() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        metadata.pHYs_pixelsPerUnitXAxis = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        metadata.pHYs_pixelsPerUnitYAxis = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        metadata.pHYs_unitSpecifier = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        metadata.pHYs_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
    private void parse_sBIT_chunk() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        int colorType = metadata.IHDR_colorType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        if (colorType == PNG_COLOR_GRAY ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            colorType == PNG_COLOR_GRAY_ALPHA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
            metadata.sBIT_grayBits = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        } else if (colorType == PNG_COLOR_RGB ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                   colorType == PNG_COLOR_PALETTE ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                   colorType == PNG_COLOR_RGB_ALPHA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            metadata.sBIT_redBits = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
            metadata.sBIT_greenBits = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            metadata.sBIT_blueBits = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        if (colorType == PNG_COLOR_GRAY_ALPHA ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            colorType == PNG_COLOR_RGB_ALPHA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
            metadata.sBIT_alphaBits = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        metadata.sBIT_colorType = colorType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        metadata.sBIT_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    private void parse_sPLT_chunk(int chunkLength)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        throws IOException, IIOException {
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   525
        metadata.sPLT_paletteName = readNullTerminatedString("ISO-8859-1", 80);
48728
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   526
        int remainingChunkLength = chunkLength -
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   527
                (metadata.sPLT_paletteName.length() + 1);
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   528
        if (remainingChunkLength <= 0) {
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   529
            throw new IIOException("sPLT chunk length is not proper");
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   530
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        int sampleDepth = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        metadata.sPLT_sampleDepth = sampleDepth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
48728
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   535
        int numEntries = remainingChunkLength/(4*(sampleDepth/8) + 2);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        metadata.sPLT_red = new int[numEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        metadata.sPLT_green = new int[numEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        metadata.sPLT_blue = new int[numEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        metadata.sPLT_alpha = new int[numEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        metadata.sPLT_frequency = new int[numEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        if (sampleDepth == 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            for (int i = 0; i < numEntries; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                metadata.sPLT_red[i] = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                metadata.sPLT_green[i] = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                metadata.sPLT_blue[i] = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                metadata.sPLT_alpha[i] = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                metadata.sPLT_frequency[i] = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
        } else if (sampleDepth == 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            for (int i = 0; i < numEntries; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                metadata.sPLT_red[i] = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                metadata.sPLT_green[i] = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
                metadata.sPLT_blue[i] = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                metadata.sPLT_alpha[i] = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                metadata.sPLT_frequency[i] = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            throw new IIOException("sPLT sample depth not 8 or 16!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        metadata.sPLT_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    private void parse_sRGB_chunk() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        metadata.sRGB_renderingIntent = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        metadata.sRGB_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    private void parse_tEXt_chunk(int chunkLength) throws IOException {
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   572
        String keyword = readNullTerminatedString("ISO-8859-1", 80);
48728
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   573
        int textLength = chunkLength - keyword.length() - 1;
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   574
        if (textLength <= 0) {
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   575
            throw new IIOException("tEXt chunk length is not proper");
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   576
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        metadata.tEXt_keyword.add(keyword);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
48728
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   579
        byte[] b = new byte[textLength];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        stream.readFully(b);
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   581
        metadata.tEXt_text.add(new String(b, "ISO-8859-1"));
47197
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   582
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   583
        // Check if the text chunk contains image creation time
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   584
        if (keyword.equals(PNGMetadata.tEXt_creationTimeKey)) {
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   585
            // Update Standard/Document/ImageCreationTime from text chunk
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   586
            int index = metadata.tEXt_text.size() - 1;
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   587
            metadata.decodeImageCreationTimeFromTextChunk(
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   588
                    metadata.tEXt_text.listIterator(index));
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   589
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    private void parse_tIME_chunk() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
        metadata.tIME_year = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        metadata.tIME_month = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        metadata.tIME_day = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        metadata.tIME_hour = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        metadata.tIME_minute = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
        metadata.tIME_second = stream.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        metadata.tIME_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    private void parse_tRNS_chunk(int chunkLength) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        int colorType = metadata.IHDR_colorType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        if (colorType == PNG_COLOR_PALETTE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            if (!metadata.PLTE_present) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                processWarningOccurred(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
"tRNS chunk without prior PLTE chunk, ignoring it.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            // Alpha table may have fewer entries than RGB palette
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
            int maxEntries = metadata.PLTE_red.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
            int numEntries = chunkLength;
48728
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   615
            if (numEntries > maxEntries && maxEntries > 0) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                processWarningOccurred(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
"tRNS chunk has more entries than prior PLTE chunk, ignoring extras.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                numEntries = maxEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
            metadata.tRNS_alpha = new byte[numEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
            metadata.tRNS_colorType = PNG_COLOR_PALETTE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
            stream.read(metadata.tRNS_alpha, 0, numEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
            stream.skipBytes(chunkLength - numEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        } else if (colorType == PNG_COLOR_GRAY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
            if (chunkLength != 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                processWarningOccurred(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
"tRNS chunk for gray image must have length 2, ignoring chunk.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                stream.skipBytes(chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
            metadata.tRNS_gray = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            metadata.tRNS_colorType = PNG_COLOR_GRAY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        } else if (colorType == PNG_COLOR_RGB) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
            if (chunkLength != 6) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                processWarningOccurred(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
"tRNS chunk for RGB image must have length 6, ignoring chunk.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                stream.skipBytes(chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            metadata.tRNS_red = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            metadata.tRNS_green = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
            metadata.tRNS_blue = stream.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            metadata.tRNS_colorType = PNG_COLOR_RGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            processWarningOccurred(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
"Gray+Alpha and RGBS images may not have a tRNS chunk, ignoring it.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        metadata.tRNS_present = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   653
    private static byte[] inflate(byte[] b) throws IOException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
        InputStream bais = new ByteArrayInputStream(b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
        InputStream iis = new InflaterInputStream(bais);
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   656
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1715
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
   657
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        int c;
1715
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
   659
        try {
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
   660
            while ((c = iis.read()) != -1) {
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   661
                baos.write(c);
1715
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
   662
            }
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
   663
        } finally {
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
   664
            iis.close();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        }
1734
861400729115 6541476: PNG imageio plugin incorrectly handles iTXt chunk
bae
parents: 1715
diff changeset
   666
        return baos.toByteArray();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
    private void parse_zTXt_chunk(int chunkLength) throws IOException {
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   670
        String keyword = readNullTerminatedString("ISO-8859-1", 80);
48728
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   671
        int textLength = chunkLength - keyword.length() - 2;
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   672
        if (textLength <= 0) {
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   673
            throw new IIOException("zTXt chunk length is not proper");
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   674
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        metadata.zTXt_keyword.add(keyword);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        int method = stream.readUnsignedByte();
25777
bb88947b6766 8049893: Replace uses of 'new Integer()' with appropriate alternative across client classes
prr
parents: 24562
diff changeset
   678
        metadata.zTXt_compressionMethod.add(method);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
48728
fb62f481671e 8191023: PngReader throws NegativeArraySizeException when keyword length exceeds chunk size
jdv
parents: 48645
diff changeset
   680
        byte[] b = new byte[textLength];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
        stream.readFully(b);
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
   682
        metadata.zTXt_text.add(new String(inflate(b), "ISO-8859-1"));
47197
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   683
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   684
        // Check if the text chunk contains image creation time
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   685
        if (keyword.equals(PNGMetadata.tEXt_creationTimeKey)) {
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   686
            // Update Standard/Document/ImageCreationTime from text chunk
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   687
            int index = metadata.zTXt_text.size() - 1;
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   688
            metadata.decodeImageCreationTimeFromTextChunk(
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   689
                    metadata.zTXt_text.listIterator(index));
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   690
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
    private void readMetadata() throws IIOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
        if (gotMetadata) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        readHeader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
         * Optimization: We can skip the remaining metadata if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
         * ignoreMetadata flag is set, and only if this is not a palette
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
         * image (in that case, we need to read the metadata to get the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
         * tRNS chunk, which is needed for the getImageTypes() method).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
        int colorType = metadata.IHDR_colorType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
        if (ignoreMetadata && colorType != PNG_COLOR_PALETTE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                    int chunkLength = stream.readInt();
24562
694f2eed1a76 6945174: IndexOutOfBoundsException calling ImageIO.read() on malformed PNG
bae
parents: 23010
diff changeset
   711
694f2eed1a76 6945174: IndexOutOfBoundsException calling ImageIO.read() on malformed PNG
bae
parents: 23010
diff changeset
   712
                    // verify the chunk length first
694f2eed1a76 6945174: IndexOutOfBoundsException calling ImageIO.read() on malformed PNG
bae
parents: 23010
diff changeset
   713
                    if (chunkLength < 0 || chunkLength + 4 < 0) {
694f2eed1a76 6945174: IndexOutOfBoundsException calling ImageIO.read() on malformed PNG
bae
parents: 23010
diff changeset
   714
                        throw new IIOException("Invalid chunk length " + chunkLength);
694f2eed1a76 6945174: IndexOutOfBoundsException calling ImageIO.read() on malformed PNG
bae
parents: 23010
diff changeset
   715
                    }
694f2eed1a76 6945174: IndexOutOfBoundsException calling ImageIO.read() on malformed PNG
bae
parents: 23010
diff changeset
   716
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                    int chunkType = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                    if (chunkType == IDAT_TYPE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                        // We've reached the image data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                        stream.skipBytes(-8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                        imageStartPosition = stream.getStreamPosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
                        // Skip the chunk plus the 4 CRC bytes that follow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                        stream.skipBytes(chunkLength + 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
                throw new IIOException("Error skipping PNG metadata", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            gotMetadata = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
            loop: while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                int chunkLength = stream.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
                int chunkType = stream.readInt();
21218
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   741
                int chunkCRC;
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   742
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   743
                // verify the chunk length
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   744
                if (chunkLength < 0) {
24562
694f2eed1a76 6945174: IndexOutOfBoundsException calling ImageIO.read() on malformed PNG
bae
parents: 23010
diff changeset
   745
                    throw new IIOException("Invalid chunk length " + chunkLength);
21218
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   746
                };
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   747
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   748
                try {
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   749
                    stream.mark();
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   750
                    stream.seek(stream.getStreamPosition() + chunkLength);
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   751
                    chunkCRC = stream.readInt();
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   752
                    stream.reset();
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   753
                } catch (IOException e) {
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   754
                    throw new IIOException("Invalid chunk length " + chunkLength);
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   755
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                switch (chunkType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                case IDAT_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                    // If chunk type is 'IDAT', we've reached the image data.
47197
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   760
                    if (imageStartPosition == -1L) {
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   761
                        /*
48641
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   762
                         * The PNG specification mandates that if colorType is
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   763
                         * PNG_COLOR_PALETTE then the PLTE chunk should appear
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   764
                         * before the first IDAT chunk.
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   765
                         */
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   766
                        if (colorType == PNG_COLOR_PALETTE &&
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   767
                            !(metadata.PLTE_present))
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   768
                        {
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   769
                            throw new IIOException("Required PLTE chunk"
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   770
                                    + " missing");
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   771
                        }
35b5da568499 8190997: PNGImageReader throws NullPointerException when PLTE section is missing
jdv
parents: 47972
diff changeset
   772
                        /*
47197
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   773
                         * PNGs may contain multiple IDAT chunks containing
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   774
                         * a portion of image data. We store the position of
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   775
                         * the first IDAT chunk and continue with iteration
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   776
                         * of other chunks that follow image data.
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   777
                         */
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   778
                        imageStartPosition = stream.getStreamPosition() - 8;
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   779
                    }
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   780
                    // Move to the CRC byte location.
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   781
                    stream.skipBytes(chunkLength);
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   782
                    break;
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   783
                case IEND_TYPE:
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   784
                    /*
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   785
                     * If the chunk type is 'IEND', we've reached end of image.
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   786
                     * Seek to the first IDAT chunk for subsequent decoding.
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   787
                     */
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   788
                    stream.seek(imageStartPosition);
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   789
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   790
                    /*
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   791
                     * flushBefore discards the portion of the stream before
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   792
                     * the indicated position. Hence this should be used after
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   793
                     * we complete iteration over available chunks including
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   794
                     * those that appear after the IDAT.
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   795
                     */
a7033867ee20 8164971: PNG metadata does not handle ImageCreationTime
pnarayanan
parents: 43209
diff changeset
   796
                    stream.flushBefore(stream.getStreamPosition());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
                    break loop;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
                case PLTE_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                    parse_PLTE_chunk(chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                case bKGD_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                    parse_bKGD_chunk();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
                case cHRM_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                    parse_cHRM_chunk();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
                case gAMA_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                    parse_gAMA_chunk();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
                case hIST_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                    parse_hIST_chunk(chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                case iCCP_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
                    parse_iCCP_chunk(chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
                case iTXt_TYPE:
43209
98dd38700c36 8166988: Improve image processing performance
prr
parents: 41010
diff changeset
   817
                    if (ignoreMetadata) {
98dd38700c36 8166988: Improve image processing performance
prr
parents: 41010
diff changeset
   818
                        stream.skipBytes(chunkLength);
98dd38700c36 8166988: Improve image processing performance
prr
parents: 41010
diff changeset
   819
                    } else {
98dd38700c36 8166988: Improve image processing performance
prr
parents: 41010
diff changeset
   820
                        parse_iTXt_chunk(chunkLength);
98dd38700c36 8166988: Improve image processing performance
prr
parents: 41010
diff changeset
   821
                    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                case pHYs_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                    parse_pHYs_chunk();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
                case sBIT_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
                    parse_sBIT_chunk();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
                case sPLT_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
                    parse_sPLT_chunk(chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
                case sRGB_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
                    parse_sRGB_chunk();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
                case tEXt_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                    parse_tEXt_chunk(chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                case tIME_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
                    parse_tIME_chunk();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                case tRNS_TYPE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                    parse_tRNS_chunk(chunkLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                case zTXt_TYPE:
43209
98dd38700c36 8166988: Improve image processing performance
prr
parents: 41010
diff changeset
   845
                    if (ignoreMetadata) {
98dd38700c36 8166988: Improve image processing performance
prr
parents: 41010
diff changeset
   846
                        stream.skipBytes(chunkLength);
98dd38700c36 8166988: Improve image processing performance
prr
parents: 41010
diff changeset
   847
                    } else {
98dd38700c36 8166988: Improve image processing performance
prr
parents: 41010
diff changeset
   848
                        parse_zTXt_chunk(chunkLength);
98dd38700c36 8166988: Improve image processing performance
prr
parents: 41010
diff changeset
   849
                    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
                default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                    // Read an unknown chunk
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                    byte[] b = new byte[chunkLength];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
                    stream.readFully(b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                    StringBuilder chunkName = new StringBuilder(4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
                    chunkName.append((char)(chunkType >>> 24));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                    chunkName.append((char)((chunkType >> 16) & 0xff));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                    chunkName.append((char)((chunkType >> 8) & 0xff));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                    chunkName.append((char)(chunkType & 0xff));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                    int ancillaryBit = chunkType >>> 28;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    if (ancillaryBit == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                        processWarningOccurred(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
"Encountered unknown chunk with critical bit set!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                    metadata.unknownChunkType.add(chunkName.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
                    metadata.unknownChunkData.add(b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
21218
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   873
                // double check whether all chunk data were consumed
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   874
                if (chunkCRC != stream.readInt()) {
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   875
                    throw new IIOException("Failed to read a chunk of type " +
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   876
                            chunkType);
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
   877
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
            throw new IIOException("Error reading PNG metadata", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
        gotMetadata = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
    // Data filtering methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
    private static void decodeSubFilter(byte[] curr, int coff, int count,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
                                        int bpp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
        for (int i = bpp; i < count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
            int val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
            val = curr[i + coff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
            val += curr[i + coff - bpp] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
            curr[i + coff] = (byte)val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    private static void decodeUpFilter(byte[] curr, int coff,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
                                       byte[] prev, int poff,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
                                       int count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
        for (int i = 0; i < count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
            int raw = curr[i + coff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
            int prior = prev[i + poff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
            curr[i + coff] = (byte)(raw + prior);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
    private static void decodeAverageFilter(byte[] curr, int coff,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
                                            byte[] prev, int poff,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
                                            int count, int bpp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
        int raw, priorPixel, priorRow;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
        for (int i = 0; i < bpp; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
            raw = curr[i + coff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
            priorRow = prev[i + poff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
            curr[i + coff] = (byte)(raw + priorRow/2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
        for (int i = bpp; i < count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
            raw = curr[i + coff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
            priorPixel = curr[i + coff - bpp] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
            priorRow = prev[i + poff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
            curr[i + coff] = (byte)(raw + (priorPixel + priorRow)/2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
    private static int paethPredictor(int a, int b, int c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
        int p = a + b - c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
        int pa = Math.abs(p - a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
        int pb = Math.abs(p - b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
        int pc = Math.abs(p - c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
        if ((pa <= pb) && (pa <= pc)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
            return a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
        } else if (pb <= pc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
            return b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
            return c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
    private static void decodePaethFilter(byte[] curr, int coff,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
                                          byte[] prev, int poff,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
                                          int count, int bpp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
        int raw, priorPixel, priorRow, priorRowPixel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
        for (int i = 0; i < bpp; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
            raw = curr[i + coff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
            priorRow = prev[i + poff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
            curr[i + coff] = (byte)(raw + priorRow);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
        for (int i = bpp; i < count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
            raw = curr[i + coff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
            priorPixel = curr[i + coff - bpp] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
            priorRow = prev[i + poff] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
            priorRowPixel = prev[i + poff - bpp] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
            curr[i + coff] = (byte)(raw + paethPredictor(priorPixel,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
                                                         priorRow,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
                                                         priorRowPixel));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
    private static final int[][] bandOffsets = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
        null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
        { 0 }, // G
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
        { 0, 1 }, // GA in GA order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
        { 0, 1, 2 }, // RGB in RGB order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
        { 0, 1, 2, 3 } // RGBA in RGBA order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
    private WritableRaster createRaster(int width, int height, int bands,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
                                        int scanlineStride,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
                                        int bitDepth) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
        DataBuffer dataBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
        WritableRaster ras = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
        Point origin = new Point(0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
        if ((bitDepth < 8) && (bands == 1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
            dataBuffer = new DataBufferByte(height*scanlineStride);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
            ras = Raster.createPackedRaster(dataBuffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
                                            width, height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
                                            bitDepth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
                                            origin);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
        } else if (bitDepth <= 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
            dataBuffer = new DataBufferByte(height*scanlineStride);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
            ras = Raster.createInterleavedRaster(dataBuffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                                                 width, height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
                                                 scanlineStride,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
                                                 bands,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
                                                 bandOffsets[bands],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
                                                 origin);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
            dataBuffer = new DataBufferUShort(height*scanlineStride);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
            ras = Raster.createInterleavedRaster(dataBuffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
                                                 width, height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
                                                 scanlineStride,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
                                                 bands,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
                                                 bandOffsets[bands],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
                                                 origin);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
        return ras;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
    private void skipPass(int passWidth, int passHeight)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
        throws IOException, IIOException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
        if ((passWidth == 0) || (passHeight == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
        int inputBands = inputBandsForColorType[metadata.IHDR_colorType];
48645
6cfee3ad7a76 8191174: PngReader throws IllegalArgumentException because ScanlineStride calculation logic is not proper
jdv
parents: 48641
diff changeset
  1020
        int bitsPerRow = Math.
6cfee3ad7a76 8191174: PngReader throws IllegalArgumentException because ScanlineStride calculation logic is not proper
jdv
parents: 48641
diff changeset
  1021
                multiplyExact((inputBands * metadata.IHDR_bitDepth), passWidth);
6cfee3ad7a76 8191174: PngReader throws IllegalArgumentException because ScanlineStride calculation logic is not proper
jdv
parents: 48641
diff changeset
  1022
        int bytesPerRow = (bitsPerRow + 7) / 8;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
        // Read the image row-by-row
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        for (int srcY = 0; srcY < passHeight; srcY++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
            // Skip filter byte and the remaining row bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
            pixelStream.skipBytes(1 + bytesPerRow);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
    private void updateImageProgress(int newPixels) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
        pixelsDone += newPixels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
        processImageProgress(100.0F*pixelsDone/totalPixels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
    private void decodePass(int passNum,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
                            int xStart, int yStart,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
                            int xStep, int yStep,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
                            int passWidth, int passHeight) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
        if ((passWidth == 0) || (passHeight == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
        WritableRaster imRas = theImage.getWritableTile(0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
        int dstMinX = imRas.getMinX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
        int dstMaxX = dstMinX + imRas.getWidth() - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
        int dstMinY = imRas.getMinY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
        int dstMaxY = dstMinY + imRas.getHeight() - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
        // Determine which pixels will be updated in this pass
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
        int[] vals =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
          ReaderUtil.computeUpdatedPixels(sourceRegion,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
                                          destinationOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
                                          dstMinX, dstMinY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
                                          dstMaxX, dstMaxY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
                                          sourceXSubsampling,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
                                          sourceYSubsampling,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
                                          xStart, yStart,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
                                          passWidth, passHeight,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
                                          xStep, yStep);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
        int updateMinX = vals[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
        int updateMinY = vals[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
        int updateWidth = vals[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
        int updateXStep = vals[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
        int updateYStep = vals[5];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
        int bitDepth = metadata.IHDR_bitDepth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
        int inputBands = inputBandsForColorType[metadata.IHDR_colorType];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
        int bytesPerPixel = (bitDepth == 16) ? 2 : 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
        bytesPerPixel *= inputBands;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
48645
6cfee3ad7a76 8191174: PngReader throws IllegalArgumentException because ScanlineStride calculation logic is not proper
jdv
parents: 48641
diff changeset
  1073
        int bitsPerRow = Math.multiplyExact((inputBands * bitDepth), passWidth);
6cfee3ad7a76 8191174: PngReader throws IllegalArgumentException because ScanlineStride calculation logic is not proper
jdv
parents: 48641
diff changeset
  1074
        int bytesPerRow = (bitsPerRow + 7) / 8;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
        int eltsPerRow = (bitDepth == 16) ? bytesPerRow/2 : bytesPerRow;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
        // If no pixels need updating, just skip the input data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
        if (updateWidth == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
            for (int srcY = 0; srcY < passHeight; srcY++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
                // Update count of pixels read
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
                updateImageProgress(passWidth);
41010
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1082
                /*
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1083
                 * If read has been aborted, just return
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1084
                 * processReadAborted will be called later
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1085
                 */
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1086
                if (abortRequested()) {
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1087
                    return;
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1088
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
                // Skip filter byte and the remaining row bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
                pixelStream.skipBytes(1 + bytesPerRow);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
        // Backwards map from destination pixels
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
        // (dstX = updateMinX + k*updateXStep)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
        // to source pixels (sourceX), and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
        // to offset and skip in passRow (srcX and srcXStep)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
        int sourceX =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
            (updateMinX - destinationOffset.x)*sourceXSubsampling +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
            sourceRegion.x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
        int srcX = (sourceX - xStart)/xStep;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
        // Compute the step factor in the source
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
        int srcXStep = updateXStep*sourceXSubsampling/xStep;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
        byte[] byteData = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
        short[] shortData = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
        byte[] curr = new byte[bytesPerRow];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
        byte[] prior = new byte[bytesPerRow];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
        // Create a 1-row tall Raster to hold the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
        WritableRaster passRow = createRaster(passWidth, 1, inputBands,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
                                              eltsPerRow,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
                                              bitDepth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
        // Create an array suitable for holding one pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
        int[] ps = passRow.getPixel(0, 0, (int[])null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
        DataBuffer dataBuffer = passRow.getDataBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
        int type = dataBuffer.getDataType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
        if (type == DataBuffer.TYPE_BYTE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
            byteData = ((DataBufferByte)dataBuffer).getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
            shortData = ((DataBufferUShort)dataBuffer).getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
        processPassStarted(theImage,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
                           passNum,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
                           sourceMinProgressivePass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
                           sourceMaxProgressivePass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
                           updateMinX, updateMinY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
                           updateXStep, updateYStep,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
                           destinationBands);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
        // Handle source and destination bands
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
        if (sourceBands != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
            passRow = passRow.createWritableChild(0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
                                                  passRow.getWidth(), 1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
                                                  0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
                                                  sourceBands);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
        if (destinationBands != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
            imRas = imRas.createWritableChild(0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
                                              imRas.getWidth(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
                                              imRas.getHeight(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
                                              0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
                                              destinationBands);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
        // Determine if all of the relevant output bands have the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
        // same bit depth as the source data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
        boolean adjustBitDepths = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
        int[] outputSampleSize = imRas.getSampleModel().getSampleSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
        int numBands = outputSampleSize.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
        for (int b = 0; b < numBands; b++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
            if (outputSampleSize[b] != bitDepth) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
                adjustBitDepths = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
        // If the bit depths differ, create a lookup table per band to perform
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
        // the conversion
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
        int[][] scale = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
        if (adjustBitDepths) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
            int maxInSample = (1 << bitDepth) - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
            int halfMaxInSample = maxInSample/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
            scale = new int[numBands][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
            for (int b = 0; b < numBands; b++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
                int maxOutSample = (1 << outputSampleSize[b]) - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
                scale[b] = new int[maxInSample + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
                for (int s = 0; s <= maxInSample; s++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
                    scale[b][s] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
                        (s*maxOutSample + halfMaxInSample)/maxInSample;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
        // Limit passRow to relevant area for the case where we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
        // will can setRect to copy a contiguous span
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
        boolean useSetRect = srcXStep == 1 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
            updateXStep == 1 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
            !adjustBitDepths &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
            (imRas instanceof ByteInterleavedRaster);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
        if (useSetRect) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
            passRow = passRow.createWritableChild(srcX, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
                                                  updateWidth, 1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
                                                  0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
                                                  null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
        // Decode the (sub)image row-by-row
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
        for (int srcY = 0; srcY < passHeight; srcY++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
            // Update count of pixels read
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
            updateImageProgress(passWidth);
41010
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1198
            /*
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1199
             * If read has been aborted, just return
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1200
             * processReadAborted will be called later
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1201
             */
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1202
            if (abortRequested()) {
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1203
                return;
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1204
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
            // Read the filter type byte and a row of data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
            int filter = pixelStream.read();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
                // Swap curr and prior
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
                byte[] tmp = prior;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
                prior = curr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
                curr = tmp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
                pixelStream.readFully(curr, 0, bytesPerRow);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
            } catch (java.util.zip.ZipException ze) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
                // TODO - throw a more meaningful exception
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
                throw ze;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
            switch (filter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
            case PNG_FILTER_NONE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
            case PNG_FILTER_SUB:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
                decodeSubFilter(curr, 0, bytesPerRow, bytesPerPixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
            case PNG_FILTER_UP:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
                decodeUpFilter(curr, 0, prior, 0, bytesPerRow);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
            case PNG_FILTER_AVERAGE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
                decodeAverageFilter(curr, 0, prior, 0, bytesPerRow,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
                                    bytesPerPixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
            case PNG_FILTER_PAETH:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
                decodePaethFilter(curr, 0, prior, 0, bytesPerRow,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
                                  bytesPerPixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
                throw new IIOException("Unknown row filter type (= " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
                                       filter + ")!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
            // Copy data into passRow byte by byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
            if (bitDepth < 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
                System.arraycopy(curr, 0, byteData, 0, bytesPerRow);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
                int idx = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
                for (int j = 0; j < eltsPerRow; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
                    shortData[j] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
                        (short)((curr[idx] << 8) | (curr[idx + 1] & 0xff));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
                    idx += 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
            // True Y position in source
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
            int sourceY = srcY*yStep + yStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
            if ((sourceY >= sourceRegion.y) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
                (sourceY < sourceRegion.y + sourceRegion.height) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
                (((sourceY - sourceRegion.y) %
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
                  sourceYSubsampling) == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
                int dstY = destinationOffset.y +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
                    (sourceY - sourceRegion.y)/sourceYSubsampling;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
                if (dstY < dstMinY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
                if (dstY > dstMaxY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
                if (useSetRect) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
                    imRas.setRect(updateMinX, dstY, passRow);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
                    int newSrcX = srcX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
                    for (int dstX = updateMinX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
                         dstX < updateMinX + updateWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
                         dstX += updateXStep) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
                        passRow.getPixel(newSrcX, 0, ps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
                        if (adjustBitDepths) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
                            for (int b = 0; b < numBands; b++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
                                ps[b] = scale[b][ps[b]];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
                        imRas.setPixel(dstX, dstY, ps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
                        newSrcX += srcXStep;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
                processImageUpdate(theImage,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
                                   updateMinX, dstY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
                                   updateWidth, 1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
                                   updateXStep, updateYStep,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
                                   destinationBands);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
        processPassComplete(theImage);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
    private void decodeImage()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
        throws IOException, IIOException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
        int width = metadata.IHDR_width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
        int height = metadata.IHDR_height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
        this.pixelsDone = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
        this.totalPixels = width*height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
        if (metadata.IHDR_interlaceMethod == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
            decodePass(0, 0, 0, 1, 1, width, height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
            for (int i = 0; i <= sourceMaxProgressivePass; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
                int XOffset = adam7XOffset[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
                int YOffset = adam7YOffset[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
                int XSubsampling = adam7XSubsampling[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
                int YSubsampling = adam7YSubsampling[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
                int xbump = adam7XSubsampling[i + 1] - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
                int ybump = adam7YSubsampling[i + 1] - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
                if (i >= sourceMinProgressivePass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
                    decodePass(i,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
                               XOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
                               YOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
                               XSubsampling,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
                               YSubsampling,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
                               (width + xbump)/XSubsampling,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
                               (height + ybump)/YSubsampling);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
                    skipPass((width + xbump)/XSubsampling,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
                             (height + ybump)/YSubsampling);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
41010
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1332
                /*
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1333
                 * If read has been aborted, just return
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1334
                 * processReadAborted will be called later
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1335
                 */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
                if (abortRequested()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
                    return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
    private void readImage(ImageReadParam param) throws IIOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
        readMetadata();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
        int width = metadata.IHDR_width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
        int height = metadata.IHDR_height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
        // Init default values
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
        sourceXSubsampling = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
        sourceYSubsampling = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
        sourceMinProgressivePass = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
        sourceMaxProgressivePass = 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
        sourceBands = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
        destinationBands = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
        destinationOffset = new Point(0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
        // If an ImageReadParam is available, get values from it
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
        if (param != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
            sourceXSubsampling = param.getSourceXSubsampling();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
            sourceYSubsampling = param.getSourceYSubsampling();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
            sourceMinProgressivePass =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
                Math.max(param.getSourceMinProgressivePass(), 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
            sourceMaxProgressivePass =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
                Math.min(param.getSourceMaxProgressivePass(), 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
            sourceBands = param.getSourceBands();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
            destinationBands = param.getDestinationBands();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
            destinationOffset = param.getDestinationOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
        }
1715
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1372
        Inflater inf = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
            stream.seek(imageStartPosition);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
2376
63e13f6d2319 6782079: PNG: reading metadata may cause OOM on truncated images.
bae
parents: 1734
diff changeset
  1376
            Enumeration<InputStream> e = new PNGImageDataEnumeration(stream);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
            InputStream is = new SequenceInputStream(e);
1715
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1378
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1379
           /* InflaterInputStream uses an Inflater instance which consumes
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1380
            * native (non-GC visible) resources. This is normally implicitly
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1381
            * freed when the stream is closed. However since the
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1382
            * InflaterInputStream wraps a client-supplied input stream,
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1383
            * we cannot close it.
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1384
            * But the app may depend on GC finalization to close the stream.
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1385
            * Therefore to ensure timely freeing of native resources we
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1386
            * explicitly create the Inflater instance and free its resources
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1387
            * when we are done with the InflaterInputStream by calling
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1388
            * inf.end();
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1389
            */
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1390
            inf = new Inflater();
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1391
            is = new InflaterInputStream(is, inf);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
            is = new BufferedInputStream(is);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
            this.pixelStream = new DataInputStream(is);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
21218
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
  1395
            /*
47962
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1396
             * PNG spec declares that valid range for width
21218
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
  1397
             * and height is [1, 2^31-1], so here we may fail to allocate
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
  1398
             * a buffer for destination image due to memory limitation.
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
  1399
             *
47962
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1400
             * If the read operation triggers OutOfMemoryError, the same
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1401
             * will be wrapped in an IIOException at PNGImageReader.read
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1402
             * method.
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1403
             *
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1404
             * The recovery strategy for this case should be defined at
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1405
             * the level of application, so we will not try to estimate
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1406
             * the required amount of the memory and/or handle OOM in
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1407
             * any way.
21218
42223d597a64 7058618: PNG parser bugs found via zzuf fuzzing
bae
parents: 5506
diff changeset
  1408
             */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
            theImage = getDestination(param,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
                                      getImageTypes(0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
                                      width,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
                                      height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
            Rectangle destRegion = new Rectangle(0, 0, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
            sourceRegion = new Rectangle(0, 0, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
            computeRegions(param, width, height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
                           theImage,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
                           sourceRegion, destRegion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
            destinationOffset.setLocation(destRegion.getLocation());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
            // At this point the header has been read and we know
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
            // how many bands are in the image, so perform checking
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
            // of the read param.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
            int colorType = metadata.IHDR_colorType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
            checkReadParamBandSettings(param,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
                                       inputBandsForColorType[colorType],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
                                      theImage.getSampleModel().getNumBands());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
41010
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1429
            clearAbortRequest();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
            processImageStarted(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
            if (abortRequested()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
                processReadAborted();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
            } else {
41010
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1434
                decodeImage();
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1435
                if (abortRequested()) {
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1436
                    processReadAborted();
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1437
                } else {
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1438
                    processImageComplete();
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1439
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
            }
41010
9824689edeb1 4924727: reader.abort() method does not work when called inside imageStarted for PNG
jdv
parents: 25859
diff changeset
  1441
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
            throw new IIOException("Error reading PNG image data", e);
1715
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1444
        } finally {
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1445
            if (inf != null) {
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1446
                inf.end();
349c53487e78 6687968: PNGImageReader leaks native memory through an Inflater.
bae
parents: 2
diff changeset
  1447
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
    public int getNumImages(boolean allowSearch) throws IIOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
        if (stream == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
            throw new IllegalStateException("No input source set!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
        if (seekForwardOnly && allowSearch) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
            throw new IllegalStateException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
                ("seekForwardOnly and allowSearch can't both be true!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
        return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
    public int getWidth(int imageIndex) throws IIOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
        if (imageIndex != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
            throw new IndexOutOfBoundsException("imageIndex != 0!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
        readHeader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
        return metadata.IHDR_width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
    public int getHeight(int imageIndex) throws IIOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
        if (imageIndex != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
            throw new IndexOutOfBoundsException("imageIndex != 0!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
        readHeader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
        return metadata.IHDR_height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
    public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
      throws IIOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
        if (imageIndex != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
            throw new IndexOutOfBoundsException("imageIndex != 0!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
        readHeader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
        ArrayList<ImageTypeSpecifier> l =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
            new ArrayList<ImageTypeSpecifier>(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
        ColorSpace rgb;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
        ColorSpace gray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
        int[] bandOffsets;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
        int bitDepth = metadata.IHDR_bitDepth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
        int colorType = metadata.IHDR_colorType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
        int dataType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
        if (bitDepth <= 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
            dataType = DataBuffer.TYPE_BYTE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
            dataType = DataBuffer.TYPE_USHORT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
        switch (colorType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
        case PNG_COLOR_GRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
            // Packed grayscale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
            l.add(ImageTypeSpecifier.createGrayscale(bitDepth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
                                                     dataType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
                                                     false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
        case PNG_COLOR_RGB:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
            if (bitDepth == 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
                // some standard types of buffered images
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
                // which can be used as destination
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
                l.add(ImageTypeSpecifier.createFromBufferedImageType(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
                          BufferedImage.TYPE_3BYTE_BGR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
                l.add(ImageTypeSpecifier.createFromBufferedImageType(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
                          BufferedImage.TYPE_INT_RGB));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
                l.add(ImageTypeSpecifier.createFromBufferedImageType(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
                          BufferedImage.TYPE_INT_BGR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
            // Component R, G, B
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
            rgb = ColorSpace.getInstance(ColorSpace.CS_sRGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
            bandOffsets = new int[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
            bandOffsets[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
            bandOffsets[1] = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
            bandOffsets[2] = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
            l.add(ImageTypeSpecifier.createInterleaved(rgb,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
                                                       bandOffsets,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
                                                       dataType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
                                                       false,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
                                                       false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
        case PNG_COLOR_PALETTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
            readMetadata(); // Need tRNS chunk
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
             * The PLTE chunk spec says:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
             * The number of palette entries must not exceed the range that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
             * can be represented in the image bit depth (for example, 2^4 = 16
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
             * for a bit depth of 4). It is permissible to have fewer entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
             * than the bit depth would allow. In that case, any out-of-range
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
             * pixel value found in the image data is an error.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
             * http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.PLTE
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
             * Consequently, the case when the palette length is smaller than
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
             * 2^bitDepth is legal in the view of PNG spec.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
             * However the spec of createIndexed() method demands the exact
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
             * equality of the palette lengh and number of possible palette
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
             * entries (2^bitDepth).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
             * {@link javax.imageio.ImageTypeSpecifier.html#createIndexed}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
             * In order to avoid this contradiction we need to extend the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
             * palette arrays to the limit defined by the bitDepth.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
            int plength = 1 << bitDepth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
            byte[] red = metadata.PLTE_red;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
            byte[] green = metadata.PLTE_green;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
            byte[] blue = metadata.PLTE_blue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
            if (metadata.PLTE_red.length < plength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
                red = Arrays.copyOf(metadata.PLTE_red, plength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
                Arrays.fill(red, metadata.PLTE_red.length, plength,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
                            metadata.PLTE_red[metadata.PLTE_red.length - 1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
                green = Arrays.copyOf(metadata.PLTE_green, plength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
                Arrays.fill(green, metadata.PLTE_green.length, plength,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
                            metadata.PLTE_green[metadata.PLTE_green.length - 1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
                blue = Arrays.copyOf(metadata.PLTE_blue, plength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
                Arrays.fill(blue, metadata.PLTE_blue.length, plength,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
                            metadata.PLTE_blue[metadata.PLTE_blue.length - 1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
            // Alpha from tRNS chunk may have fewer entries than
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
            // the RGB LUTs from the PLTE chunk; if so, pad with
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
            // 255.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
            byte[] alpha = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
            if (metadata.tRNS_present && (metadata.tRNS_alpha != null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
                if (metadata.tRNS_alpha.length == red.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
                    alpha = metadata.tRNS_alpha;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
                    alpha = Arrays.copyOf(metadata.tRNS_alpha, red.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
                    Arrays.fill(alpha,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1601
                                metadata.tRNS_alpha.length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
                                red.length, (byte)255);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
            l.add(ImageTypeSpecifier.createIndexed(red, green,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
                                                   blue, alpha,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
                                                   bitDepth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
                                                   DataBuffer.TYPE_BYTE));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
        case PNG_COLOR_GRAY_ALPHA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
            // Component G, A
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
            gray = ColorSpace.getInstance(ColorSpace.CS_GRAY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
            bandOffsets = new int[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
            bandOffsets[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
            bandOffsets[1] = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
            l.add(ImageTypeSpecifier.createInterleaved(gray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
                                                       bandOffsets,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
                                                       dataType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
                                                       true,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
                                                       false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
        case PNG_COLOR_RGB_ALPHA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
            if (bitDepth == 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
                // some standard types of buffered images
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
                // wich can be used as destination
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
                l.add(ImageTypeSpecifier.createFromBufferedImageType(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
                          BufferedImage.TYPE_4BYTE_ABGR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
                l.add(ImageTypeSpecifier.createFromBufferedImageType(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
                          BufferedImage.TYPE_INT_ARGB));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
            // Component R, G, B, A (non-premultiplied)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
            rgb = ColorSpace.getInstance(ColorSpace.CS_sRGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1638
            bandOffsets = new int[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1639
            bandOffsets[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
            bandOffsets[1] = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
            bandOffsets[2] = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
            bandOffsets[3] = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
            l.add(ImageTypeSpecifier.createInterleaved(rgb,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
                                                       bandOffsets,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
                                                       dataType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
                                                       true,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
                                                       false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
        return l.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
     * Super class implementation uses first element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
     * of image types list as raw image type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
     * Also, super implementation uses first element of this list
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
     * as default destination type image read param does not specify
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
     * anything other.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
     * However, in case of RGB and RGBA color types, raw image type
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
     * produces buffered image of custom type. It causes some
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
     * performance degradation of subsequent rendering operations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
     * To resolve this contradiction we put standard image types
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
     * at the first positions of image types list (to produce standard
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
     * images by default) and put raw image type (which is custom)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
     * at the last position of this list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
     * After this changes we should override getRawImageType()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
     * to return last element of image types list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
    public ImageTypeSpecifier getRawImageType(int imageIndex)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
      throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
        Iterator<ImageTypeSpecifier> types = getImageTypes(imageIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
        ImageTypeSpecifier raw = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
        do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
            raw = types.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
        } while (types.hasNext());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
        return raw;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
    public ImageReadParam getDefaultReadParam() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
        return new ImageReadParam();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
    public IIOMetadata getStreamMetadata()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
        throws IIOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
    public IIOMetadata getImageMetadata(int imageIndex) throws IIOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
        if (imageIndex != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
            throw new IndexOutOfBoundsException("imageIndex != 0!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
        readMetadata();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
        return metadata;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
    public BufferedImage read(int imageIndex, ImageReadParam param)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
        throws IIOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1708
        if (imageIndex != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
            throw new IndexOutOfBoundsException("imageIndex != 0!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1710
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
47962
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1712
        try {
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1713
            readImage(param);
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1714
        } catch (IOException |
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1715
                 IllegalStateException |
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1716
                 IllegalArgumentException e)
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1717
        {
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1718
            throw e;
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1719
        } catch (Throwable e) {
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1720
            throw new IIOException("Caught exception during read: ", e);
99000fb68d0e 8190332: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
jdv
parents: 47836
diff changeset
  1721
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
        return theImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1725
    public void reset() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
        super.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1727
        resetStreamSettings();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1728
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1729
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1730
    private void resetStreamSettings() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1731
        gotHeader = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1732
        gotMetadata = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1733
        metadata = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1734
        pixelStream = null;
47972
18dbd2ae7eca 8191431: Reading multiple PNG images with unique IDAT chunk positions will cause IIOException
jdv
parents: 47962
diff changeset
  1735
        imageStartPosition = -1L;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1736
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1737
}