View | Details | Raw Unified | Return to bug 53408
Collapse All | Expand All

(-)test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderPNGTestCase.java (+62 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
package org.apache.xmlgraphics.image.loader.impl;
21
22
import java.io.IOException;
23
24
import org.junit.Test;
25
26
import org.apache.xmlgraphics.image.loader.Image;
27
import org.apache.xmlgraphics.image.loader.ImageContext;
28
import org.apache.xmlgraphics.image.loader.ImageException;
29
import org.apache.xmlgraphics.image.loader.ImageFlavor;
30
import org.apache.xmlgraphics.image.loader.ImageInfo;
31
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
32
import org.apache.xmlgraphics.image.loader.MockImageContext;
33
import org.apache.xmlgraphics.image.loader.MockImageSessionContext;
34
import org.apache.xmlgraphics.util.MimeConstants;
35
36
import static org.junit.Assert.assertEquals;
37
import static org.junit.Assert.assertTrue;
38
39
public class ImageLoaderPNGTestCase {
40
41
    private ImageLoaderPNG ilpng = new ImageLoaderPNG();
42
43
    @Test
44
    public void testGetUsagePenalty() {
45
        assertEquals(1000, ilpng.getUsagePenalty());
46
    }
47
48
    @Test
49
    public void testLoadImageImageInfoMapImageSessionContext() throws ImageException, IOException {
50
        ImageContext context = MockImageContext.newSafeInstance();
51
        ImageSessionContext session = new MockImageSessionContext(context);
52
        ImageInfo info = new ImageInfo("basn2c08.png", MimeConstants.MIME_PNG);
53
        Image im = ilpng.loadImage(info, null, session);
54
        assertTrue(im instanceof ImageRendered);
55
    }
56
57
    @Test
58
    public void testGetTargetFlavor() {
59
        assertEquals(ImageFlavor.RENDERED_IMAGE, ilpng.getTargetFlavor());
60
    }
61
62
}
(-)test/java/org/apache/xmlgraphics/image/loader/impl/PNGFileTestCase.java (+119 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
package org.apache.xmlgraphics.image.loader.impl;
21
22
import java.awt.image.ColorModel;
23
import java.awt.image.ComponentColorModel;
24
import java.awt.image.IndexColorModel;
25
import java.io.IOException;
26
27
import org.junit.Test;
28
29
import org.apache.xmlgraphics.image.loader.ImageContext;
30
import org.apache.xmlgraphics.image.loader.ImageException;
31
import org.apache.xmlgraphics.image.loader.ImageInfo;
32
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
33
import org.apache.xmlgraphics.image.loader.MockImageContext;
34
import org.apache.xmlgraphics.image.loader.MockImageSessionContext;
35
import org.apache.xmlgraphics.util.MimeConstants;
36
37
import static org.junit.Assert.assertEquals;
38
import static org.junit.Assert.assertTrue;
39
import static org.junit.Assert.fail;
40
41
public class PNGFileTestCase implements PNGConstants {
42
43
    @Test
44
    public void testColorTypeTwoPNG() throws ImageException, IOException {
45
        testColorTypePNG("basn2c08.png", PNG_COLOR_RGB);
46
    }
47
48
    @Test
49
    public void testColorTypeZeroPNG() throws ImageException, IOException {
50
        testColorTypePNG("basn0g08.png", PNG_COLOR_GRAY);
51
    }
52
53
    @Test
54
    public void testColorTypeSixPNG() throws ImageException, IOException {
55
        testColorTypePNG("basn6a08.png", PNG_COLOR_RGB_ALPHA);
56
    }
57
58
    @Test
59
    public void testColorTypeThreePNG() throws ImageException, IOException {
60
        testColorTypePNG("basn3p08.png", PNG_COLOR_PALETTE);
61
    }
62
63
    @Test
64
    public void testColorTypeFourPNG() throws ImageException, IOException {
65
        testColorTypePNG("basn4a08.png", PNG_COLOR_GRAY_ALPHA);
66
    }
67
68
    @Test
69
    public void testTransparentPNG() throws ImageException, IOException {
70
        testColorTypePNG("tbbn3p08.png", PNG_COLOR_PALETTE, true);
71
        testColorTypePNG("tbrn2c08.png", PNG_COLOR_RGB, true);
72
    }
73
74
    @Test
75
    public void testCorruptPNG() {
76
        ImageContext context = MockImageContext.newSafeInstance();
77
        ImageSessionContext session = new MockImageSessionContext(context);
78
        ImageInfo info = new ImageInfo("corrupt-image.png", MimeConstants.MIME_PNG);
79
        ImageLoaderRawPNG ilrpng = new ImageLoaderRawPNG();
80
        try {
81
            ImageRawPNG irpng = (ImageRawPNG) ilrpng.loadImage(info, null, session);
82
            fail("An exception should have been thrown above");
83
        } catch (Exception e) {
84
            // do nothing; this was expected
85
        }
86
    }
87
88
    private void testColorTypePNG(String imageName, int colorType) throws ImageException, IOException {
89
        testColorTypePNG(imageName, colorType, false);
90
    }
91
92
    private void testColorTypePNG(String imageName, int colorType, boolean isTransparent)
93
            throws ImageException, IOException {
94
        ImageContext context = MockImageContext.newSafeInstance();
95
        ImageSessionContext session = new MockImageSessionContext(context);
96
        ImageInfo info = new ImageInfo(imageName, MimeConstants.MIME_PNG);
97
        ImageLoaderRawPNG ilrpng = new ImageLoaderRawPNG();
98
        ImageRawPNG irpng = (ImageRawPNG) ilrpng.loadImage(info, null, session);
99
        ColorModel cm = irpng.getColorModel();
100
        if (colorType == PNG_COLOR_PALETTE) {
101
            assertTrue(cm instanceof IndexColorModel);
102
        } else {
103
            assertTrue(cm instanceof ComponentColorModel);
104
            int numComponents = 3;
105
            if (colorType == PNG_COLOR_GRAY) {
106
                numComponents = 1;
107
            } else if (colorType == PNG_COLOR_GRAY_ALPHA) {
108
                numComponents = 2;
109
            } else if (colorType == PNG_COLOR_RGB_ALPHA) {
110
                numComponents = 4;
111
            }
112
            assertEquals(numComponents, cm.getNumComponents());
113
        }
114
        if (isTransparent) {
115
            assertTrue(irpng.isTransparent());
116
        }
117
    }
118
119
}
(-)test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawPNGTestCase.java (+76 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
package org.apache.xmlgraphics.image.loader.impl;
21
22
import java.io.IOException;
23
24
import org.junit.Test;
25
26
import org.apache.xmlgraphics.image.loader.Image;
27
import org.apache.xmlgraphics.image.loader.ImageContext;
28
import org.apache.xmlgraphics.image.loader.ImageException;
29
import org.apache.xmlgraphics.image.loader.ImageFlavor;
30
import org.apache.xmlgraphics.image.loader.ImageInfo;
31
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
32
import org.apache.xmlgraphics.image.loader.MockImageContext;
33
import org.apache.xmlgraphics.image.loader.MockImageSessionContext;
34
import org.apache.xmlgraphics.util.MimeConstants;
35
36
import static org.junit.Assert.assertEquals;
37
import static org.junit.Assert.assertTrue;
38
import static org.junit.Assert.fail;
39
40
public class ImageLoaderRawPNGTestCase {
41
42
    private ImageLoaderRawPNG ilrpng = new ImageLoaderRawPNG();
43
44
    @Test
45
    public void testGetUsagePenalty() {
46
        assertEquals(1000, ilrpng.getUsagePenalty());
47
    }
48
49
    @Test
50
    public void testLoadImageBadMime() throws ImageException, IOException {
51
        ImageContext context = MockImageContext.newSafeInstance();
52
        ImageSessionContext session = new MockImageSessionContext(context);
53
        ImageInfo info = new ImageInfo("basn2c08.png", MimeConstants.MIME_JPEG);
54
        try {
55
            ImageRawPNG irpng = (ImageRawPNG) ilrpng.loadImage(info, null, session);
56
            fail("An exception should have been thrown above");
57
        } catch (IllegalArgumentException e) {
58
            // do nothing; this was expected
59
        }
60
    }
61
62
    @Test
63
    public void testGetTargetFlavor() {
64
        assertEquals(ImageFlavor.RAW_PNG, ilrpng.getTargetFlavor());
65
    }
66
67
    @Test
68
    public void testLoadImageGoodMime() throws ImageException, IOException {
69
        ImageContext context = MockImageContext.newSafeInstance();
70
        ImageSessionContext session = new MockImageSessionContext(context);
71
        ImageInfo info = new ImageInfo("basn2c08.png", MimeConstants.MIME_PNG);
72
        Image im = ilrpng.loadImage(info, null, session);
73
        assertTrue(im instanceof ImageRawPNG);
74
    }
75
76
}
(-)test/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryPNGTestCase.java (+64 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
package org.apache.xmlgraphics.image.loader.impl;
21
22
import org.junit.Test;
23
24
import org.apache.xmlgraphics.image.loader.ImageFlavor;
25
import org.apache.xmlgraphics.image.loader.spi.ImageLoader;
26
import org.apache.xmlgraphics.util.MimeConstants;
27
28
import static org.junit.Assert.assertArrayEquals;
29
import static org.junit.Assert.assertTrue;
30
import static org.junit.Assert.fail;
31
32
public class ImageLoaderFactoryPNGTestCase {
33
34
    private ImageLoaderFactoryPNG ilfpng = new ImageLoaderFactoryPNG();
35
36
    @Test
37
    public void testGetSupportedMIMETypes() {
38
        assertArrayEquals(new String[] {MimeConstants.MIME_PNG}, ilfpng.getSupportedMIMETypes());
39
    }
40
41
    @Test
42
    public void testGetSupportedFlavors() {
43
        assertArrayEquals(new ImageFlavor[] {ImageFlavor.RENDERED_IMAGE},
44
                ilfpng.getSupportedFlavors(MimeConstants.MIME_PNG));
45
        try {
46
            ilfpng.getSupportedFlavors(MimeConstants.MIME_JPEG);
47
            fail("An exception should have been thrown above....");
48
        } catch (IllegalArgumentException e) {
49
            // do nothing; this is expected
50
        }
51
    }
52
53
    @Test
54
    public void testNewImageLoader() {
55
        ImageLoader il = ilfpng.newImageLoader(ImageFlavor.RENDERED_IMAGE);
56
        assertTrue(il instanceof ImageLoaderPNG);
57
    }
58
59
    @Test
60
    public void testIsAvailable() {
61
        assertTrue(ilfpng.isAvailable());
62
    }
63
64
}
(-)test/java/org/apache/xmlgraphics/image/loader/ImageLoaderTestCase.java (-3 / +10 lines)
Lines 34-39 Link Here
34
import junit.framework.TestCase;
34
import junit.framework.TestCase;
35
35
36
import org.apache.commons.io.IOUtils;
36
import org.apache.commons.io.IOUtils;
37
38
import org.apache.xmlgraphics.image.loader.impl.ImageLoaderPNG;
39
import org.apache.xmlgraphics.image.loader.impl.ImageLoaderRawPNG;
37
import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
40
import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
38
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
41
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
39
import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry;
42
import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry;
Lines 186-196 Link Here
186
            String mime, ImageFlavor rawFlavor) throws Exception {
189
            String mime, ImageFlavor rawFlavor) throws Exception {
187
        ImageLoaderFactory ilfs[] = ImageImplRegistry.getDefaultInstance()
190
        ImageLoaderFactory ilfs[] = ImageImplRegistry.getDefaultInstance()
188
                .getImageLoaderFactories(mime);
191
                .getImageLoaderFactories(mime);
189
        if (ilfs != null)
192
        if (ilfs != null) {
190
            for (int i = 0; i < ilfs.length; i++) {
193
            for (int i = 0; i < ilfs.length; i++) {
191
                ImageLoaderFactory ilf = ilfs[i];
194
                ImageLoaderFactory ilf = ilfs[i];
192
                try {
195
                try {
193
                    final ImageLoader il = ilf.newImageLoader(rawFlavor);
196
                    final ImageLoader il = ilf.newImageLoader(rawFlavor);
197
                    if (il instanceof ImageLoaderRawPNG || il instanceof ImageLoaderPNG) {
198
                        // temporary measure until ImageLoaderRawPNG and ImageLoader PNG handle ICC profiles
199
                        continue;
200
                    }
194
                    final ImageInfo im = new ImageInfo(uri, mime);
201
                    final ImageInfo im = new ImageInfo(uri, mime);
195
                    final Image img = il.loadImage(im, isc);
202
                    final Image img = il.loadImage(im, isc);
196
                    final ICC_Profile icc = img.getICCProfile();
203
                    final ICC_Profile icc = img.getICCProfile();
Lines 203-210 Link Here
203
                    // Ignore. This imageLoader does not support RAW
210
                    // Ignore. This imageLoader does not support RAW
204
                }
211
                }
205
                try {
212
                try {
206
                    final ImageLoader il = ilf
213
                    final ImageLoader il = ilf.newImageLoader(ImageFlavor.BUFFERED_IMAGE);
207
                            .newImageLoader(ImageFlavor.BUFFERED_IMAGE);
208
                    final ImageInfo im = new ImageInfo(uri, mime);
214
                    final ImageInfo im = new ImageInfo(uri, mime);
209
                    final Image img = il.loadImage(im, isc);
215
                    final Image img = il.loadImage(im, isc);
210
                    final ICC_Profile icc = img.getICCProfile();
216
                    final ICC_Profile icc = img.getICCProfile();
Lines 213-218 Link Here
213
                    // Ignore. This imageLoader does not support Buffered.
219
                    // Ignore. This imageLoader does not support Buffered.
214
                }
220
                }
215
            }
221
            }
222
        }
216
    }
223
    }
217
224
218
    public void testBrokenIccPng() throws Exception {
225
    public void testBrokenIccPng() throws Exception {
(-)test/java/org/apache/xmlgraphics/java2d/ps/PSGraphics2DTestCase.java (-1 lines)
Lines 1-6 Link Here
1
/*
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
4
 * contributor license agreements.  See the NOTICE file distributed with
3
 * contributor license agreements.  See the NOTICE file distributed with
5
 * this work for additional information regarding copyright ownership.
4
 * this work for additional information regarding copyright ownership.
6
 * The ASF licenses this file to You under the Apache License, Version 2.0
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
(-)src/resources/META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory (-1 / +2 lines)
Lines 2-5 Link Here
2
org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryRaw
2
org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryRaw
3
org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryRawCCITTFax
3
org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryRawCCITTFax
4
org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryEPS
4
org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryEPS
5
org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryInternalTIFF
5
org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryInternalTIFF
6
org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryPNG
(-)src/java/org/apache/xmlgraphics/ps/PSImageUtils.java (-30 / +37 lines)
Lines 143-167 Link Here
143
143
144
    /**
144
    /**
145
     * Writes a bitmap image to the PostScript stream.
145
     * Writes a bitmap image to the PostScript stream.
146
     * @param img the bitmap image as a byte array
146
     * @param encoder the image encoder
147
     * @param imgDim the dimensions of the image
148
     * @param imgDescription the name of the image
147
     * @param targetRect the target rectangle to place the image in
149
     * @param targetRect the target rectangle to place the image in
150
     * @param colorModel the color model of the image
148
     * @param gen the PostScript generator
151
     * @param gen the PostScript generator
149
     * @throws IOException In case of an I/O exception
152
     * @throws IOException In case of an I/O exception
150
     */
153
     */
151
    private static void writeImage(RenderedImage img,
154
    public static void writeImage(ImageEncoder encoder, Dimension imgDim, String imgDescription,
152
            Rectangle2D targetRect, PSGenerator gen) throws IOException {
155
            Rectangle2D targetRect, ColorModel colorModel, PSGenerator gen)
153
        ImageEncoder encoder = ImageEncodingHelper.createRenderedImageEncoder(img);
156
            throws IOException {
154
        String imgDescription = img.getClass().getName();
155
157
156
        gen.saveGraphicsState();
158
        gen.saveGraphicsState();
157
        translateAndScale(gen, null, targetRect);
159
        translateAndScale(gen, null, targetRect);
158
159
        gen.commentln("%AXGBeginBitmap: " + imgDescription);
160
        gen.commentln("%AXGBeginBitmap: " + imgDescription);
160
161
        gen.writeln("{{");
161
        gen.writeln("{{");
162
        // Template: (RawData is used for the EOF signal only)
162
163
        // gen.write("/RawData currentfile <first filter> filter def");
164
        // gen.write("/Data RawData <second filter> <third filter> [...] def");
165
        String implicitFilter = encoder.getImplicitFilter();
163
        String implicitFilter = encoder.getImplicitFilter();
166
        if (implicitFilter != null) {
164
        if (implicitFilter != null) {
167
            gen.writeln("/RawData currentfile /ASCII85Decode filter def");
165
            gen.writeln("/RawData currentfile /ASCII85Decode filter def");
Lines 175-185 Link Here
175
                gen.writeln("/Data RawData /RunLengthDecode filter def");
173
                gen.writeln("/Data RawData /RunLengthDecode filter def");
176
            }
174
            }
177
        }
175
        }
176
178
        PSDictionary imageDict = new PSDictionary();
177
        PSDictionary imageDict = new PSDictionary();
179
        imageDict.put("/DataSource", "Data");
178
        imageDict.put("/DataSource", "Data");
180
        writeImageCommand(img, imageDict, gen);
181
179
182
        /* the following two lines could be enabled if something still goes wrong
180
        populateImageDictionary(imgDim, colorModel, imageDict);
181
        writeImageCommand(imageDict, colorModel, gen);
182
183
        /*
184
         * the following two lines could be enabled if something still goes wrong
183
         * gen.write("Data closefile");
185
         * gen.write("Data closefile");
184
         * gen.write("RawData flushfile");
186
         * gen.write("RawData flushfile");
185
         */
187
         */
Lines 189-231 Link Here
189
191
190
        compressAndWriteBitmap(encoder, gen);
192
        compressAndWriteBitmap(encoder, gen);
191
193
192
        gen.writeln("");
194
        gen.newLine();
193
        gen.commentln("%AXGEndBitmap");
195
        gen.commentln("%AXGEndBitmap");
194
        gen.restoreGraphicsState();
196
        gen.restoreGraphicsState();
195
    }
197
    }
196
198
197
    private static ColorModel populateImageDictionary(
199
    private static ColorModel populateImageDictionary(Dimension imgDim, ColorModel colorModel,
198
                ImageEncodingHelper helper, PSDictionary imageDict) {
200
            PSDictionary imageDict) {
199
        RenderedImage img = helper.getImage();
201
        String w = Integer.toString(imgDim.width);
200
        String w = Integer.toString(img.getWidth());
202
        String h = Integer.toString(imgDim.height);
201
        String h = Integer.toString(img.getHeight());
202
        imageDict.put("/ImageType", "1");
203
        imageDict.put("/ImageType", "1");
203
        imageDict.put("/Width", w);
204
        imageDict.put("/Width", w);
204
        imageDict.put("/Height", h);
205
        imageDict.put("/Height", h);
205
206
206
        ColorModel cm = helper.getEncodedColorModel();
207
208
        boolean invertColors = false;
207
        boolean invertColors = false;
209
        String decodeArray = getDecodeArray(cm.getNumComponents(), invertColors);
208
        String decodeArray = getDecodeArray(colorModel.getNumColorComponents(), invertColors);
210
        int bitsPerComp = cm.getComponentSize(0);
209
        int bitsPerComp = colorModel.getComponentSize(0);
211
210
212
        // Setup scanning for left-to-right and top-to-bottom
211
        // Setup scanning for left-to-right and top-to-bottom
213
        imageDict.put("/ImageMatrix", "[" + w + " 0 0 " + h + " 0 0]");
212
        imageDict.put("/ImageMatrix", "[" + w + " 0 0 " + h + " 0 0]");
214
213
215
        if ((cm instanceof IndexColorModel)) {
214
        if ((colorModel instanceof IndexColorModel)) {
216
            IndexColorModel im = (IndexColorModel)cm;
215
            IndexColorModel indexColorModel = (IndexColorModel) colorModel;
217
            int c = im.getMapSize();
216
            int c = indexColorModel.getMapSize();
218
            int hival = c - 1;
217
            int hival = c - 1;
219
            if (hival > 4095) {
218
            if (hival > 4095) {
220
                throw new UnsupportedOperationException("hival must not go beyond 4095");
219
                throw new UnsupportedOperationException("hival must not go beyond 4095");
221
            }
220
            }
222
            bitsPerComp = im.getPixelSize();
221
            bitsPerComp = indexColorModel.getPixelSize();
223
            int ceiling = ((int)Math.pow(2, bitsPerComp)) - 1;
222
            int ceiling = ((int) Math.pow(2, bitsPerComp)) - 1;
224
            decodeArray = "[0 " + ceiling + "]";
223
            decodeArray = "[0 " + ceiling + "]";
225
        }
224
        }
226
        imageDict.put("/BitsPerComponent", Integer.toString(bitsPerComp));
225
        imageDict.put("/BitsPerComponent", Integer.toString(bitsPerComp));
227
        imageDict.put("/Decode", decodeArray);
226
        imageDict.put("/Decode", decodeArray);
228
        return cm;
227
        return colorModel;
229
    }
228
    }
230
229
231
    private static String getDecodeArray(int numComponents, boolean invertColors) {
230
    private static String getDecodeArray(int numComponents, boolean invertColors) {
Lines 288-295 Link Here
288
            PSDictionary imageDict, PSGenerator gen) throws IOException {
287
            PSDictionary imageDict, PSGenerator gen) throws IOException {
289
        ImageEncodingHelper helper = new ImageEncodingHelper(img, true);
288
        ImageEncodingHelper helper = new ImageEncodingHelper(img, true);
290
        ColorModel cm = helper.getEncodedColorModel();
289
        ColorModel cm = helper.getEncodedColorModel();
291
        populateImageDictionary(helper, imageDict);
290
        Dimension imgDim = new Dimension(img.getWidth(), img.getHeight());
292
291
292
        populateImageDictionary(imgDim, cm, imageDict);
293
        writeImageCommand(imageDict, cm, gen);
293
        writeImageCommand(imageDict, cm, gen);
294
    }
294
    }
295
295
Lines 340-351 Link Here
340
     * @param h height
340
     * @param h height
341
     * @param gen PS generator
341
     * @param gen PS generator
342
     * @throws IOException In case of an I/O problem while rendering the image
342
     * @throws IOException In case of an I/O problem while rendering the image
343
     * @deprecated Use {@link writeImage}
343
     */
344
     */
344
    public static void renderBitmapImage(RenderedImage img,
345
    public static void renderBitmapImage(RenderedImage img,
345
                float x, float y, float w, float h, PSGenerator gen)
346
                float x, float y, float w, float h, PSGenerator gen)
346
                    throws IOException {
347
                    throws IOException {
347
        Rectangle2D targetRect = new Rectangle2D.Double(x, y, w, h);
348
        Rectangle2D targetRect = new Rectangle2D.Double(x, y, w, h);
348
        writeImage(img, targetRect, gen);
349
        ImageEncoder encoder = ImageEncodingHelper.createRenderedImageEncoder(img);
350
        Dimension imgDim = new Dimension(img.getWidth(), img.getHeight());
351
        String imgDescription = img.getClass().getName();
352
        ImageEncodingHelper helper = new ImageEncodingHelper(img);
353
        ColorModel cm = helper.getEncodedColorModel();
354
355
        writeImage(encoder, imgDim, imgDescription, targetRect, cm, gen);
349
    }
356
    }
350
357
351
    /**
358
    /**
(-)src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRaw.java (+2 lines)
Lines 81-86 Link Here
81
    public ImageLoader newImageLoader(ImageFlavor targetFlavor) {
81
    public ImageLoader newImageLoader(ImageFlavor targetFlavor) {
82
        if (targetFlavor.equals(ImageFlavor.RAW_JPEG)) {
82
        if (targetFlavor.equals(ImageFlavor.RAW_JPEG)) {
83
            return new ImageLoaderRawJPEG();
83
            return new ImageLoaderRawJPEG();
84
        } else if (targetFlavor.equals(ImageFlavor.RAW_PNG)) {
85
            return new ImageLoaderRawPNG();
84
        } else {
86
        } else {
85
            return new ImageLoaderRaw(targetFlavor);
87
            return new ImageLoaderRaw(targetFlavor);
86
        }
88
        }
(-)src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawPNG.java (+85 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
// Original author: Matthias Reichenbacher
21
22
package org.apache.xmlgraphics.image.loader.impl;
23
24
import java.io.IOException;
25
import java.util.Map;
26
27
import javax.imageio.stream.ImageInputStream;
28
import javax.xml.transform.Source;
29
30
import org.apache.commons.logging.Log;
31
import org.apache.commons.logging.LogFactory;
32
33
import org.apache.xmlgraphics.image.codec.util.ImageInputStreamSeekableStreamAdapter;
34
import org.apache.xmlgraphics.image.codec.util.SeekableStream;
35
import org.apache.xmlgraphics.image.loader.Image;
36
import org.apache.xmlgraphics.image.loader.ImageException;
37
import org.apache.xmlgraphics.image.loader.ImageFlavor;
38
import org.apache.xmlgraphics.image.loader.ImageInfo;
39
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
40
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
41
import org.apache.xmlgraphics.util.MimeConstants;
42
43
public class ImageLoaderRawPNG extends AbstractImageLoader {
44
45
    /** logger */
46
    protected static Log log = LogFactory.getLog(ImageLoaderRawPNG.class);
47
48
    /**
49
     * Main constructor.
50
     */
51
    public ImageLoaderRawPNG() {
52
    }
53
54
    /** {@inheritDoc} */
55
    public ImageFlavor getTargetFlavor() {
56
        return ImageFlavor.RAW_PNG;
57
    }
58
59
    /** {@inheritDoc} */
60
    public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException,
61
            IOException {
62
        if (!MimeConstants.MIME_PNG.equals(info.getMimeType())) {
63
            throw new IllegalArgumentException("ImageInfo must be from a image with MIME type: "
64
                    + MimeConstants.MIME_PNG);
65
        }
66
67
        Source src = session.needSource(info.getOriginalURI());
68
        ImageInputStream in = ImageUtil.needImageInputStream(src);
69
        // Remove streams as we do things with them at some later time.
70
        ImageUtil.removeStreams(src);
71
        SeekableStream seekStream = new ImageInputStreamSeekableStreamAdapter(in);
72
        PNGFile im = new PNGFile(seekStream);
73
        ImageRawPNG irpng = im.getImageRawPNG(info);
74
        return irpng;
75
    }
76
77
    /** {@inheritDoc} */
78
    public int getUsagePenalty() {
79
        // since this image loader does not handle all kinds of PNG images then we add some penalty to it
80
        // so that it is not chosen by default; instead, users need to give it a negative penalty in
81
        // fop.xconf so that it is used
82
        return 1000;
83
    }
84
85
}
(-)src/java/org/apache/xmlgraphics/image/loader/impl/PNGConstants.java (+47 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
package org.apache.xmlgraphics.image.loader.impl;
21
22
public interface PNGConstants {
23
24
    /*
25
     * First 8 bytes of any PNG file.
26
     */
27
    long PNG_SIGNATURE = 0x89504e470d0a1a0aL;
28
29
    /*
30
     * Color types.
31
     */
32
    int PNG_COLOR_GRAY = 0;
33
    int PNG_COLOR_RGB = 2;
34
    int PNG_COLOR_PALETTE = 3;
35
    int PNG_COLOR_GRAY_ALPHA = 4;
36
    int PNG_COLOR_RGB_ALPHA = 6;
37
38
    /*
39
     * Filter types.
40
     */
41
    int PNG_FILTER_NONE = 0;
42
    int PNG_FILTER_SUB = 1;
43
    int PNG_FILTER_UP = 2;
44
    int PNG_FILTER_AVERAGE = 3;
45
    int PNG_FILTER_PAETH = 4;
46
47
}
(-)src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryPNG.java (+59 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
package org.apache.xmlgraphics.image.loader.impl;
21
22
import org.apache.xmlgraphics.image.loader.ImageFlavor;
23
import org.apache.xmlgraphics.image.loader.spi.ImageLoader;
24
import org.apache.xmlgraphics.util.MimeConstants;
25
26
public class ImageLoaderFactoryPNG extends AbstractImageLoaderFactory {
27
28
    private static final String[] MIMES = new String[] {MimeConstants.MIME_PNG};
29
30
    private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {ImageFlavor.RENDERED_IMAGE};
31
32
    public ImageLoaderFactoryPNG() {
33
        //
34
    }
35
36
    /** {@inheritDoc} */
37
    public String[] getSupportedMIMETypes() {
38
        return MIMES;
39
    }
40
41
    /** {@inheritDoc} */
42
    public ImageFlavor[] getSupportedFlavors(String mime) {
43
        if (MimeConstants.MIME_PNG.equals(mime)) {
44
            return FLAVORS;
45
        }
46
        throw new IllegalArgumentException("Unsupported MIME type: " + mime);
47
    }
48
49
    /** {@inheritDoc} */
50
    public ImageLoader newImageLoader(ImageFlavor targetFlavor) {
51
        return new ImageLoaderPNG();
52
    }
53
54
    /** {@inheritDoc} */
55
    public boolean isAvailable() {
56
        return true;
57
    }
58
59
}
(-)src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderPNG.java (+75 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
package org.apache.xmlgraphics.image.loader.impl;
21
22
import java.awt.image.RenderedImage;
23
import java.io.IOException;
24
import java.util.Map;
25
26
import javax.imageio.stream.ImageInputStream;
27
import javax.xml.transform.Source;
28
29
import org.apache.xmlgraphics.image.codec.png.PNGDecodeParam;
30
import org.apache.xmlgraphics.image.codec.png.PNGImageDecoder;
31
import org.apache.xmlgraphics.image.codec.util.ImageInputStreamSeekableStreamAdapter;
32
import org.apache.xmlgraphics.image.codec.util.SeekableStream;
33
import org.apache.xmlgraphics.image.loader.Image;
34
import org.apache.xmlgraphics.image.loader.ImageException;
35
import org.apache.xmlgraphics.image.loader.ImageFlavor;
36
import org.apache.xmlgraphics.image.loader.ImageInfo;
37
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
38
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
39
40
public class ImageLoaderPNG extends AbstractImageLoader {
41
42
    public ImageLoaderPNG() {
43
        //
44
    }
45
46
    /** {@inheritDoc} */
47
    public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session) throws ImageException,
48
            IOException {
49
50
        Source src = session.needSource(info.getOriginalURI());
51
        ImageInputStream imgStream = ImageUtil.needImageInputStream(src);
52
53
        SeekableStream seekStream = new ImageInputStreamSeekableStreamAdapter(imgStream);
54
55
        PNGImageDecoder decoder = new PNGImageDecoder(seekStream, new PNGDecodeParam());
56
        RenderedImage image = decoder.decodeAsRenderedImage();
57
58
        // need transparency here?
59
        return new ImageRendered(info, image, null);
60
    }
61
62
    /** {@inheritDoc} */
63
    public ImageFlavor getTargetFlavor() {
64
        return ImageFlavor.RENDERED_IMAGE;
65
    }
66
67
    /** {@inheritDoc} */
68
    public int getUsagePenalty() {
69
        // since this image loader does not provide any benefits over the default sun.imageio one we add
70
        // some penalty to it so that it is not chosen by default; instead users need to give it a negative
71
        // penalty in fop.xconf so that it is used; this image loader is mostly for testing purposes for now.
72
        return 1000;
73
    }
74
75
}
(-)src/java/org/apache/xmlgraphics/image/loader/impl/ImageRawPNG.java (+144 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
// Original author: Matthias Reichenbacher
21
22
package org.apache.xmlgraphics.image.loader.impl;
23
24
import java.awt.Color;
25
import java.awt.color.ColorSpace;
26
import java.awt.color.ICC_Profile;
27
import java.awt.image.ColorModel;
28
import java.io.InputStream;
29
30
import org.apache.xmlgraphics.image.loader.ImageFlavor;
31
import org.apache.xmlgraphics.image.loader.ImageInfo;
32
33
public class ImageRawPNG extends ImageRawStream {
34
35
    private ColorModel cm;
36
    private ICC_Profile iccProfile;
37
    private int bitDepth;
38
    private boolean isTransparent;
39
    private int grayTransparentAlpha;
40
    private int redTransparentAlpha;
41
    private int greenTransparentAlpha;
42
    private int blueTransparentAlpha;
43
44
    /**
45
     * Main constructor.
46
     * @param info the image info object
47
     * @param in the ImageInputStream with the raw content
48
     * @param colorSpace the color space
49
     * @param iccProfile an ICC color profile or null if no profile is associated
50
     */
51
    public ImageRawPNG(ImageInfo info, InputStream in, ColorModel cm, int bitDepth, ICC_Profile iccProfile) {
52
        super(info, ImageFlavor.RAW_PNG, in);
53
        this.iccProfile = iccProfile;
54
        this.cm = cm;
55
        this.bitDepth = bitDepth;
56
    }
57
58
    /**
59
     * The bit depth of each color channel.
60
     * @return the bit depth of one channel (same for all)
61
     */
62
    public int getBitDepth() {
63
        return bitDepth;
64
    }
65
66
    /**
67
     * Returns the ICC color profile if one is associated with the PNG image.
68
     * @return the ICC color profile or null if there's no profile
69
     */
70
    public ICC_Profile getICCProfile() {
71
        return this.iccProfile;
72
    }
73
74
    /**
75
     * Returns the image's color model.
76
     * @return the color model
77
     */
78
    public ColorModel getColorModel() {
79
        return this.cm;
80
    }
81
82
    /**
83
     * Returns the image's color space.
84
     * @return the color space
85
     */
86
    public ColorSpace getColorSpace() {
87
        return this.cm.getColorSpace();
88
    }
89
90
    /**
91
     * Sets the gray transparent pixel value.
92
     * @param gray the transparent pixel gray value (0...255)
93
     */
94
    protected void setGrayTransparentAlpha(int gray) {
95
        this.isTransparent = true;
96
        this.grayTransparentAlpha = gray;
97
    }
98
99
    /**
100
     * Sets the RGB transparent pixel values.
101
     * @param red the transparent pixel red value (0...255)
102
     * @param green the transparent pixel green value (0...255)
103
     * @param blue the transparent pixel blue value (0...255)
104
     */
105
    protected void setRGBTransparentAlpha(int red, int green, int blue) {
106
        this.isTransparent = true;
107
        this.redTransparentAlpha = red;
108
        this.greenTransparentAlpha = green;
109
        this.blueTransparentAlpha = blue;
110
    }
111
112
    /**
113
     * Used to flag image as transparent when the image is of pallete type.
114
     */
115
    protected void setTransparent() {
116
        this.isTransparent = true;
117
    }
118
119
    /**
120
     * Whether the image is transparent (meaning there is a transparent pixel)
121
     * @return true if transparent pixel exists
122
     */
123
    public boolean isTransparent() {
124
        return this.isTransparent;
125
    }
126
127
    /**
128
     * The color of the transparent pixel.
129
     * @return the color of the transparent pixel.
130
     */
131
    public Color getTransparentColor() {
132
        Color color = null;
133
        if (!this.isTransparent) {
134
            return color;
135
        }
136
        if (cm.getNumColorComponents() == 3) {
137
            color = new Color(this.redTransparentAlpha, this.greenTransparentAlpha, this.blueTransparentAlpha);
138
        } else {
139
            color = new Color(this.grayTransparentAlpha, 0, 0);
140
        }
141
        return color;
142
    }
143
144
}
(-)src/java/org/apache/xmlgraphics/image/loader/impl/PNGFile.java (+236 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
package org.apache.xmlgraphics.image.loader.impl;
21
22
import java.awt.color.ColorSpace;
23
import java.awt.color.ICC_Profile;
24
import java.awt.image.ColorModel;
25
import java.awt.image.ComponentColorModel;
26
import java.awt.image.DataBuffer;
27
import java.awt.image.IndexColorModel;
28
import java.io.BufferedInputStream;
29
import java.io.ByteArrayInputStream;
30
import java.io.DataInputStream;
31
import java.io.IOException;
32
import java.io.InputStream;
33
import java.io.SequenceInputStream;
34
import java.util.ArrayList;
35
import java.util.Collections;
36
import java.util.List;
37
38
import org.apache.xmlgraphics.image.codec.png.PNGChunk;
39
import org.apache.xmlgraphics.image.codec.util.PropertyUtil;
40
import org.apache.xmlgraphics.image.loader.ImageException;
41
import org.apache.xmlgraphics.image.loader.ImageInfo;
42
43
/**
44
 * Provides methods useful for processing PNG files.
45
 */
46
class PNGFile implements PNGConstants {
47
48
    private ColorModel colorModel;
49
    private ICC_Profile iccProfile;
50
    private int bitDepth;
51
    private int colorType;
52
    private boolean isTransparent;
53
    private int grayTransparentAlpha;
54
    private int redTransparentAlpha;
55
    private int greenTransparentAlpha;
56
    private int blueTransparentAlpha;
57
    private List<InputStream> streamVec = new ArrayList<InputStream>();
58
    private int paletteEntries;
59
    private byte[] redPalette;
60
    private byte[] greenPalette;
61
    private byte[] bluePalette;
62
    private byte[] alphaPalette;
63
    private boolean hasPalette;
64
    private boolean hasAlphaPalette = false;
65
66
    public PNGFile(InputStream stream) throws IOException, ImageException {
67
        if (!stream.markSupported()) {
68
            stream = new BufferedInputStream(stream);
69
        }
70
        DataInputStream distream = new DataInputStream(stream);
71
        long magic = distream.readLong();
72
        if (magic != PNG_SIGNATURE) {
73
            String msg = PropertyUtil.getString("PNGImageDecoder0");
74
            throw new ImageException(msg);
75
        }
76
        // only some chunks are worth parsing in the current implementation
77
        do {
78
            try {
79
                PNGChunk chunk;
80
                String chunkType = PNGChunk.getChunkType(distream);
81
                if (chunkType.equals(PNGChunk.ChunkType.IHDR.name())) {
82
                    chunk = PNGChunk.readChunk(distream);
83
                    parse_IHDR_chunk(chunk);
84
                } else if (chunkType.equals(PNGChunk.ChunkType.PLTE.name())) {
85
                    chunk = PNGChunk.readChunk(distream);
86
                    parse_PLTE_chunk(chunk);
87
                } else if (chunkType.equals(PNGChunk.ChunkType.IDAT.name())) {
88
                    chunk = PNGChunk.readChunk(distream);
89
                    streamVec.add(new ByteArrayInputStream(chunk.getData()));
90
                } else if (chunkType.equals(PNGChunk.ChunkType.IEND.name())) {
91
                    // chunk = PNGChunk.readChunk(distream);
92
                    PNGChunk.skipChunk(distream);
93
                    break; // fall through to the bottom
94
                } else if (chunkType.equals(PNGChunk.ChunkType.tRNS.name())) {
95
                    chunk = PNGChunk.readChunk(distream);
96
                    parse_tRNS_chunk(chunk);
97
                } else {
98
                    // chunk = PNGChunk.readChunk(distream);
99
                    PNGChunk.skipChunk(distream);
100
                }
101
            } catch (Exception e) {
102
                e.printStackTrace();
103
                String msg = PropertyUtil.getString("PNGImageDecoder2");
104
                throw new RuntimeException(msg);
105
            }
106
        } while (true);
107
    }
108
109
    public ImageRawPNG getImageRawPNG(ImageInfo info) throws ImageException {
110
        InputStream seqStream = new SequenceInputStream(Collections.enumeration(streamVec));
111
        switch (colorType) {
112
        case PNG_COLOR_GRAY:
113
            if (hasPalette) {
114
                throw new ImageException("Corrupt PNG: color palette is not allowed!");
115
            }
116
            colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), false, false,
117
                    ColorModel.OPAQUE, DataBuffer.TYPE_BYTE);
118
            break;
119
        case PNG_COLOR_RGB:
120
            // actually a check of the sRGB chunk would be necessary to confirm if it's really sRGB
121
            colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), false, false,
122
                    ColorModel.OPAQUE, DataBuffer.TYPE_BYTE);
123
            break;
124
        case PNG_COLOR_PALETTE:
125
            if (hasAlphaPalette) {
126
                colorModel = new IndexColorModel(bitDepth, paletteEntries, redPalette, greenPalette,
127
                        bluePalette, alphaPalette);
128
            } else {
129
                colorModel = new IndexColorModel(bitDepth, paletteEntries, redPalette, greenPalette,
130
                        bluePalette);
131
            }
132
            break;
133
        case PNG_COLOR_GRAY_ALPHA:
134
            if (hasPalette) {
135
                throw new ImageException("Corrupt PNG: color palette is not allowed!");
136
            }
137
            colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), true, false,
138
                    ColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE);
139
            break;
140
        case PNG_COLOR_RGB_ALPHA:
141
            // actually a check of the sRGB chunk would be necessary to confirm if it's really sRGB
142
            colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false,
143
                    ColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE);
144
            break;
145
        default:
146
            throw new ImageException("Unsupported color type: " + colorType);
147
        }
148
        // the iccProfile is still null for now
149
        ImageRawPNG rawImage = new ImageRawPNG(info, seqStream, colorModel, bitDepth, iccProfile);
150
        if (isTransparent) {
151
            if (colorType == PNG_COLOR_GRAY) {
152
                rawImage.setGrayTransparentAlpha(grayTransparentAlpha);
153
            } else if (colorType == PNG_COLOR_RGB) {
154
                rawImage.setRGBTransparentAlpha(redTransparentAlpha, greenTransparentAlpha,
155
                        blueTransparentAlpha);
156
            } else if (colorType == PNG_COLOR_PALETTE) {
157
                rawImage.setTransparent();
158
            } else {
159
                //
160
            }
161
        }
162
        return rawImage;
163
    }
164
165
    private void parse_IHDR_chunk(PNGChunk chunk) {
166
        int width = chunk.getInt4(0);
167
        int height = chunk.getInt4(4);
168
        bitDepth = chunk.getInt1(8);
169
        if (bitDepth != 8) {
170
            // this is a limitation of the current implementation
171
            throw new RuntimeException("Unsupported bit depth: " + bitDepth);
172
        }
173
        colorType = chunk.getInt1(9);
174
        int compressionMethod = chunk.getInt1(10);
175
        if (compressionMethod != 0) {
176
            throw new RuntimeException("Unsupported PNG compression method: " + compressionMethod);
177
        }
178
        int filterMethod = chunk.getInt1(11);
179
        if (filterMethod != 0) {
180
            throw new RuntimeException("Unsupported PNG filter method: " + filterMethod);
181
        }
182
        int interlaceMethod = chunk.getInt1(12);
183
        if (interlaceMethod != 0) {
184
            // this is a limitation of the current implementation
185
            throw new RuntimeException("Unsupported PNG interlace method: " + interlaceMethod);
186
        }
187
    }
188
189
    private void parse_PLTE_chunk(PNGChunk chunk) {
190
        paletteEntries = chunk.getLength() / 3;
191
        redPalette = new byte[paletteEntries];
192
        greenPalette = new byte[paletteEntries];
193
        bluePalette = new byte[paletteEntries];
194
        hasPalette = true;
195
196
        int pltIndex = 0;
197
        for (int i = 0; i < paletteEntries; i++) {
198
            redPalette[i] = chunk.getByte(pltIndex++);
199
            greenPalette[i] = chunk.getByte(pltIndex++);
200
            bluePalette[i] = chunk.getByte(pltIndex++);
201
        }
202
    }
203
204
    private void parse_tRNS_chunk(PNGChunk chunk) {
205
        if (colorType == PNG_COLOR_PALETTE) {
206
            int entries = chunk.getLength();
207
            if (entries > paletteEntries) {
208
                // Error -- mustn't have more alpha than RGB palette entries
209
                String msg = PropertyUtil.getString("PNGImageDecoder14");
210
                throw new RuntimeException(msg);
211
            }
212
            // Load beginning of palette from the chunk
213
            alphaPalette = new byte[paletteEntries];
214
            for (int i = 0; i < entries; i++) {
215
                alphaPalette[i] = chunk.getByte(i);
216
            }
217
            // Fill rest of palette with 255
218
            for (int i = entries; i < paletteEntries; i++) {
219
                alphaPalette[i] = (byte) 255;
220
            }
221
            hasAlphaPalette = true;
222
        } else if (colorType == PNG_COLOR_GRAY) {
223
            grayTransparentAlpha = chunk.getInt2(0);
224
        } else if (colorType == PNG_COLOR_RGB) {
225
            redTransparentAlpha = chunk.getInt2(0);
226
            greenTransparentAlpha = chunk.getInt2(2);
227
            blueTransparentAlpha = chunk.getInt2(4);
228
        } else if (colorType == PNG_COLOR_GRAY_ALPHA || colorType == PNG_COLOR_RGB_ALPHA) {
229
            // Error -- GA or RGBA image can't have a tRNS chunk.
230
            String msg = PropertyUtil.getString("PNGImageDecoder15");
231
            throw new RuntimeException(msg);
232
        }
233
        isTransparent = true;
234
    }
235
236
}
(-)src/java/org/apache/xmlgraphics/image/codec/png/PNGImageDecoder.java (-153 / +38 lines)
Lines 51-56 Link Here
51
import org.apache.xmlgraphics.image.codec.util.ImageDecoderImpl;
51
import org.apache.xmlgraphics.image.codec.util.ImageDecoderImpl;
52
import org.apache.xmlgraphics.image.codec.util.PropertyUtil;
52
import org.apache.xmlgraphics.image.codec.util.PropertyUtil;
53
import org.apache.xmlgraphics.image.codec.util.SimpleRenderedImage;
53
import org.apache.xmlgraphics.image.codec.util.SimpleRenderedImage;
54
import org.apache.xmlgraphics.image.loader.impl.PNGConstants;
54
55
55
// CSOFF: ConstantName
56
// CSOFF: ConstantName
56
// CSOFF: InnerAssignment
57
// CSOFF: InnerAssignment
Lines 80-180 Link Here
80
    }
81
    }
81
}
82
}
82
83
83
class PNGChunk {
84
    int length;
85
    int type;
86
    byte[] data;
87
    int crc;
88
89
    final String typeString;
90
91
    PNGChunk(int length, int type, byte[] data, int crc) {
92
        this.length = length;
93
        this.type = type;
94
        this.data = data;
95
        this.crc = crc;
96
97
        typeString = ""
98
                     + (char)((type >>> 24) & 0xff)
99
                     + (char)((type >>> 16) & 0xff)
100
                     + (char)((type >>>  8) & 0xff)
101
                     + (char)((type       ) & 0xff);
102
    }
103
104
    public int getLength() {
105
        return length;
106
    }
107
108
    public int getType() {
109
        return type;
110
    }
111
112
    public String getTypeString() {
113
        return typeString;
114
    }
115
116
    public byte[] getData() {
117
        return data;
118
    }
119
120
    public byte getByte(int offset) {
121
        return data[offset];
122
    }
123
124
    public int getInt1(int offset) {
125
        return data[offset] & 0xff;
126
    }
127
128
    public int getInt2(int offset) {
129
        return ((data[offset] & 0xff) << 8) |
130
            (data[offset + 1] & 0xff);
131
    }
132
133
    public int getInt4(int offset) {
134
        return ((data[offset] & 0xff) << 24) |
135
            ((data[offset + 1] & 0xff) << 16) |
136
            ((data[offset + 2] & 0xff) << 8) |
137
            (data[offset + 3] & 0xff);
138
    }
139
140
    public String getString4(int offset) {
141
        return  ""
142
            + (char)data[offset]
143
            + (char)data[offset + 1]
144
            + (char)data[offset + 2]
145
            + (char)data[offset + 3];
146
    }
147
148
    public boolean isType(String typeName) {
149
        return typeString.equals(typeName);
150
    }
151
}
152
153
/**
84
/**
154
 * TO DO:
85
 * TO DO:
155
 *
86
 *
156
 * zTXt chunks
87
 * zTXt chunks
157
 *
88
 *
158
 */
89
 */
159
class PNGImage extends SimpleRenderedImage {
90
class PNGImage extends SimpleRenderedImage implements PNGConstants {
160
161
    public static final int PNG_COLOR_GRAY = 0;
162
    public static final int PNG_COLOR_RGB = 2;
163
    public static final int PNG_COLOR_PALETTE = 3;
164
    public static final int PNG_COLOR_GRAY_ALPHA = 4;
165
    public static final int PNG_COLOR_RGB_ALPHA = 6;
166
91
167
    private static final String[] colorTypeNames = {
92
    private static final String[] colorTypeNames = {
168
        "Grayscale", "Error", "Truecolor", "Index",
93
        "Grayscale", "Error", "Truecolor", "Index",
169
        "Grayscale with alpha", "Error", "Truecolor with alpha"
94
        "Grayscale with alpha", "Error", "Truecolor with alpha"
170
    };
95
    };
171
96
172
    public static final int PNG_FILTER_NONE = 0;
173
    public static final int PNG_FILTER_SUB = 1;
174
    public static final int PNG_FILTER_UP = 2;
175
    public static final int PNG_FILTER_AVERAGE = 3;
176
    public static final int PNG_FILTER_PAETH = 4;
177
178
    private int[][] bandOffsets = {
97
    private int[][] bandOffsets = {
179
        null,
98
        null,
180
        { 0 }, // G
99
        { 0 }, // G
Lines 304-310 Link Here
304
    private static final int POST_ADD_GRAY_TRANS_EXP =
223
    private static final int POST_ADD_GRAY_TRANS_EXP =
305
        POST_ADD_GRAY_TRANS | POST_EXP_MASK;
224
        POST_ADD_GRAY_TRANS | POST_EXP_MASK;
306
225
307
    private List streamVec = new ArrayList();
226
    private List<InputStream> streamVec = new ArrayList<InputStream>();
308
    private DataInputStream dataStream;
227
    private DataInputStream dataStream;
309
228
310
    private int bytesPerPixel; // number of bytes per input pixel
229
    private int bytesPerPixel; // number of bytes per input pixel
Lines 399-405 Link Here
399
318
400
        try {
319
        try {
401
            long magic = distream.readLong();
320
            long magic = distream.readLong();
402
            if (magic != 0x89504e470d0a1a0aL) {
321
            if (magic != PNG_SIGNATURE) {
403
                String msg = PropertyUtil.getString("PNGImageDecoder0");
322
                String msg = PropertyUtil.getString("PNGImageDecoder0");
404
                throw new RuntimeException(msg);
323
                throw new RuntimeException(msg);
405
            }
324
            }
Lines 413-470 Link Here
413
            try {
332
            try {
414
                PNGChunk chunk;
333
                PNGChunk chunk;
415
334
416
                String chunkType = getChunkType(distream);
335
                String chunkType = PNGChunk.getChunkType(distream);
417
                if (chunkType.equals("IHDR")) {
336
                if (chunkType.equals(PNGChunk.ChunkType.IHDR.name())) {
418
                    chunk = readChunk(distream);
337
                    chunk = PNGChunk.readChunk(distream);
419
                    parse_IHDR_chunk(chunk);
338
                    parse_IHDR_chunk(chunk);
420
                } else if (chunkType.equals("PLTE")) {
339
                } else if (chunkType.equals(PNGChunk.ChunkType.PLTE.name())) {
421
                    chunk = readChunk(distream);
340
                    chunk = PNGChunk.readChunk(distream);
422
                    parse_PLTE_chunk(chunk);
341
                    parse_PLTE_chunk(chunk);
423
                } else if (chunkType.equals("IDAT")) {
342
                } else if (chunkType.equals(PNGChunk.ChunkType.IDAT.name())) {
424
                    chunk = readChunk(distream);
343
                    chunk = PNGChunk.readChunk(distream);
425
                    streamVec.add(new ByteArrayInputStream(chunk.getData()));
344
                    streamVec.add(new ByteArrayInputStream(chunk.getData()));
426
                } else if (chunkType.equals("IEND")) {
345
                } else if (chunkType.equals(PNGChunk.ChunkType.IEND.name())) {
427
                    chunk = readChunk(distream);
346
                    chunk = PNGChunk.readChunk(distream);
428
                    parse_IEND_chunk(chunk);
347
                    parse_IEND_chunk(chunk);
429
                    break; // fall through to the bottom
348
                    break; // fall through to the bottom
430
                } else if (chunkType.equals("bKGD")) {
349
                } else if (chunkType.equals(PNGChunk.ChunkType.bKGD.name())) {
431
                    chunk = readChunk(distream);
350
                    chunk = PNGChunk.readChunk(distream);
432
                    parse_bKGD_chunk(chunk);
351
                    parse_bKGD_chunk(chunk);
433
                } else if (chunkType.equals("cHRM")) {
352
                } else if (chunkType.equals(PNGChunk.ChunkType.cHRM.name())) {
434
                    chunk = readChunk(distream);
353
                    chunk = PNGChunk.readChunk(distream);
435
                    parse_cHRM_chunk(chunk);
354
                    parse_cHRM_chunk(chunk);
436
                } else if (chunkType.equals("gAMA")) {
355
                } else if (chunkType.equals(PNGChunk.ChunkType.gAMA.name())) {
437
                    chunk = readChunk(distream);
356
                    chunk = PNGChunk.readChunk(distream);
438
                    parse_gAMA_chunk(chunk);
357
                    parse_gAMA_chunk(chunk);
439
                } else if (chunkType.equals("hIST")) {
358
                } else if (chunkType.equals(PNGChunk.ChunkType.hIST.name())) {
440
                    chunk = readChunk(distream);
359
                    chunk = PNGChunk.readChunk(distream);
441
                    parse_hIST_chunk(chunk);
360
                    parse_hIST_chunk(chunk);
442
                } else if (chunkType.equals("iCCP")) {
361
                } else if (chunkType.equals(PNGChunk.ChunkType.iCCP.name())) {
443
                    chunk = readChunk(distream);
362
                    chunk = PNGChunk.readChunk(distream);
444
                    parse_iCCP_chunk(chunk);
363
                    parse_iCCP_chunk(chunk);
445
                } else if (chunkType.equals("pHYs")) {
364
                } else if (chunkType.equals(PNGChunk.ChunkType.pHYs.name())) {
446
                    chunk = readChunk(distream);
365
                    chunk = PNGChunk.readChunk(distream);
447
                    parse_pHYs_chunk(chunk);
366
                    parse_pHYs_chunk(chunk);
448
                } else if (chunkType.equals("sBIT")) {
367
                } else if (chunkType.equals(PNGChunk.ChunkType.sBIT.name())) {
449
                    chunk = readChunk(distream);
368
                    chunk = PNGChunk.readChunk(distream);
450
                    parse_sBIT_chunk(chunk);
369
                    parse_sBIT_chunk(chunk);
451
                } else if (chunkType.equals("sRGB")) {
370
                } else if (chunkType.equals(PNGChunk.ChunkType.sRGB.name())) {
452
                    chunk = readChunk(distream);
371
                    chunk = PNGChunk.readChunk(distream);
453
                    parse_sRGB_chunk(chunk);
372
                    parse_sRGB_chunk(chunk);
454
                } else if (chunkType.equals("tEXt")) {
373
                } else if (chunkType.equals(PNGChunk.ChunkType.tEXt.name())) {
455
                    chunk = readChunk(distream);
374
                    chunk = PNGChunk.readChunk(distream);
456
                    parse_tEXt_chunk(chunk);
375
                    parse_tEXt_chunk(chunk);
457
                } else if (chunkType.equals("tIME")) {
376
                } else if (chunkType.equals(PNGChunk.ChunkType.tIME.name())) {
458
                    chunk = readChunk(distream);
377
                    chunk = PNGChunk.readChunk(distream);
459
                    parse_tIME_chunk(chunk);
378
                    parse_tIME_chunk(chunk);
460
                } else if (chunkType.equals("tRNS")) {
379
                } else if (chunkType.equals(PNGChunk.ChunkType.tRNS.name())) {
461
                    chunk = readChunk(distream);
380
                    chunk = PNGChunk.readChunk(distream);
462
                    parse_tRNS_chunk(chunk);
381
                    parse_tRNS_chunk(chunk);
463
                } else if (chunkType.equals("zTXt")) {
382
                } else if (chunkType.equals(PNGChunk.ChunkType.zTXt.name())) {
464
                    chunk = readChunk(distream);
383
                    chunk = PNGChunk.readChunk(distream);
465
                    parse_zTXt_chunk(chunk);
384
                    parse_zTXt_chunk(chunk);
466
                } else {
385
                } else {
467
                    chunk = readChunk(distream);
386
                    chunk = PNGChunk.readChunk(distream);
468
                    // Output the chunk data in raw form
387
                    // Output the chunk data in raw form
469
388
470
                    String type = chunk.getTypeString();
389
                    String type = chunk.getTypeString();
Lines 498-537 Link Here
498
        }
417
        }
499
    }
418
    }
500
419
501
    private static String getChunkType(DataInputStream distream) {
502
        try {
503
            distream.mark(8);
504
            /* int length = */ distream.readInt();
505
            int type      =    distream.readInt();
506
            distream.reset();
507
508
            String typeString = "";        // todo simplify this
509
            typeString += (char)(type >> 24);
510
            typeString += (char)((type >> 16) & 0xff);
511
            typeString += (char)((type >> 8) & 0xff);
512
            typeString += (char)(type & 0xff);
513
            return typeString;
514
        } catch (Exception e) {
515
            e.printStackTrace();
516
            return null;
517
        }
518
    }
519
520
    private static PNGChunk readChunk(DataInputStream distream) {
521
        try {
522
            int length = distream.readInt();
523
            int type = distream.readInt();
524
            byte[] data = new byte[length];
525
            distream.readFully(data);
526
            int crc = distream.readInt();
527
528
            return new PNGChunk(length, type, data, crc);
529
        } catch (Exception e) {
530
            e.printStackTrace();
531
            return null;
532
        }
533
    }
534
535
    private void parse_IHDR_chunk(PNGChunk chunk) {
420
    private void parse_IHDR_chunk(PNGChunk chunk) {
536
        tileWidth = width = chunk.getInt4(0);
421
        tileWidth = width = chunk.getInt4(0);
537
        tileHeight = height = chunk.getInt4(4);
422
        tileHeight = height = chunk.getInt4(4);
(-)src/java/org/apache/xmlgraphics/image/codec/png/PNGChunk.java (+184 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* $Id$ */
19
20
package org.apache.xmlgraphics.image.codec.png;
21
22
import java.io.DataInputStream;
23
24
import org.apache.commons.logging.Log;
25
import org.apache.commons.logging.LogFactory;
26
27
public class PNGChunk {
28
    int length;
29
    int type;
30
    byte[] data;
31
    int crc;
32
33
    String typeString;
34
35
    /** logger */
36
    protected static Log log = LogFactory.getLog(PNGChunk.class);
37
38
    /**
39
     * See http://en.wikipedia.org/wiki/Portable_Network_Graphics for a light explanation;
40
     * See http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html for the spec.
41
     */
42
    public enum ChunkType {
43
        IHDR, // IHDR must be the first chunk
44
        PLTE, // PLTE contains the palette
45
        IDAT, // IDAT contains the image, which may be split among multiple IDAT chunks
46
        IEND, // IEND marks the image end
47
        bKGD, // bKGD gives the default background color
48
        cHRM, // cHRM gives the chromaticity coordinates
49
        gAMA, // gAMA specifies gamma
50
        hIST, // hIST can store the histogram
51
        iCCP, // iCCP is an ICC color profile
52
        iTXt, // iTXt contains UTF-8 text
53
        pHYs, // pHYs holds the intended pixel size
54
        sBIT, // sBIT (significant bits) indicates the color-accuracy
55
        sPLT, // sPLT suggests a palette to use
56
        sRGB, // sRGB indicates that the standard sRGB color space is used
57
        sTER, // sTER stereo-image indicator chunk for stereoscopic images
58
        tEXt, // tEXt can store text that can be represented in ISO/IEC 8859-1
59
        tIME, // tIME stores the time that the image was last changed
60
        tRNS, // tRNS contains transparency information
61
        zTXt; // zTXt contains compressed text with the same limits as tEXt
62
    }
63
64
    public PNGChunk(int length, int type, byte[] data, int crc) {
65
        this.length = length;
66
        this.type = type;
67
        this.data = data;
68
        this.crc = crc;
69
        this.typeString = typeIntToString(this.type);
70
    }
71
72
    public int getLength() {
73
        return length;
74
    }
75
76
    public int getType() {
77
        return type;
78
    }
79
80
    public String getTypeString() {
81
        return typeString;
82
    }
83
84
    public byte[] getData() {
85
        return data;
86
    }
87
88
    public byte getByte(int offset) {
89
        return data[offset];
90
    }
91
92
    public int getInt1(int offset) {
93
        return data[offset] & 0xff;
94
    }
95
96
    public int getInt2(int offset) {
97
        return ((data[offset] & 0xff) << 8) | (data[offset + 1] & 0xff);
98
    }
99
100
    public int getInt4(int offset) {
101
        return ((data[offset] & 0xff) << 24) | ((data[offset + 1] & 0xff) << 16)
102
                | ((data[offset + 2] & 0xff) << 8) | (data[offset + 3] & 0xff);
103
    }
104
105
    public String getString4(int offset) {
106
        return "" + (char) data[offset] + (char) data[offset + 1] + (char) data[offset + 2]
107
                + (char) data[offset + 3];
108
    }
109
110
    public boolean isType(String typeName) {
111
        return typeString.equals(typeName);
112
    }
113
114
    /**
115
     * Reads the next chunk from the input stream.
116
     * @param distream the input stream
117
     * @return the chunk
118
     */
119
    public static PNGChunk readChunk(DataInputStream distream) {
120
        try {
121
            int length = distream.readInt();
122
            int type = distream.readInt();
123
            byte[] data = new byte[length];
124
            distream.readFully(data);
125
            int crc = distream.readInt();
126
127
            return new PNGChunk(length, type, data, crc);
128
        } catch (Exception e) {
129
            e.printStackTrace();
130
            return null;
131
        }
132
    }
133
134
    /**
135
     * Returns the PNG chunk type, a four letter case sensitive ASCII type/name.
136
     * @param distream the input stream
137
     * @return a four letter case sensitive ASCII type/name
138
     */
139
    public static String getChunkType(DataInputStream distream) {
140
        try {
141
            distream.mark(8);
142
            /* int length = */distream.readInt();
143
            int type = distream.readInt();
144
            distream.reset();
145
146
            return typeIntToString(type);
147
        } catch (Exception e) {
148
            e.printStackTrace();
149
            return null;
150
        }
151
    }
152
153
    private static String typeIntToString(int type) {
154
        String typeString = "";
155
        typeString += (char) (type >> 24);
156
        typeString += (char) ((type >> 16) & 0xff);
157
        typeString += (char) ((type >> 8) & 0xff);
158
        typeString += (char) (type & 0xff);
159
        return typeString;
160
    }
161
162
    /**
163
     * Skips the next chunk from the input stream.
164
     * @param distream the input stream
165
     * @return true if skipping successful, false otherwise
166
     */
167
    public static boolean skipChunk(DataInputStream distream) {
168
        try {
169
            int length = distream.readInt();
170
            int type = distream.readInt();
171
            // is this really faster than reading?
172
            int skipped = distream.skipBytes(length);
173
            int crc = distream.readInt();
174
            if (skipped != length) {
175
                log.warn("Incorrect number of bytes skipped.");
176
                return false;
177
            }
178
            return true;
179
        } catch (Exception e) {
180
            log.warn(e.getMessage());
181
            return false;
182
        }
183
    }
184
}

Return to bug 53408