Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 5103832
Votes 0
Synopsis PNG subsampling with JAI Image I/O Tools introduce an erroneous offset
Category jai:codec_imageio
Reported Against 1.0_01
Release Fixed 1.0_01
State 10-Fix Delivered, bug
Priority: 3-Medium
Related Bugs
Submit Date 17-SEP-2004
Description


FULL PRODUCT VERSION :
java version "1.4.2_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04)
Java HotSpot(TM) Client VM (build 1.4.2_05-b04, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
 customer  Windows 2000 [Version 5.00.2195

EXTRA RELEVANT SYSTEM CONFIGURATION :
JAI Image I/O Tools

A DESCRIPTION OF THE PROBLEM :
PNG subsampling with JAI Image I/O Tools introduce an erroneous offset by one as seen from the enclosed program and its output. If JAI Image I/O Tools are not used, the PNG subsampling works as expected.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the enclosed program

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
0 2 4 6 8 10 12 14 16 18
0 2 4 6 8 10 12 14 16 18
ACTUAL -
0 2 4 6 8 10 12 14 16 18
1 3 5 7 9 11 13 15 17 19

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package com.picturegrid.playground;

import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;

public class Test
{

    public static BufferedImage createTestImage(int w, int h)
    {
        byte[][] data = new byte[3][w * h];
        for(int x = 0; x < w; ++x)
            for(int y = 0; y < h; ++y)
            {
                data[0][w * y + x] = (byte) (x & 0xff);
                data[1][w * y + x] = (byte) ((x + y) >>> 1 & 0xff);
                data[2][w * y + x] = (byte) (y & 0xff);
            }
        DataBuffer dataBuffer = new DataBufferByte(data, w * h);
        WritableRaster raster = Raster.createBandedRaster(dataBuffer, w, h, w, new int[] { 0, 1, 2 }, new int[] { 0, 0, 0 }, null);
        ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8 }, false, false, ColorModel.OPAQUE, raster.getTransferType());
        return new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null);
    }

    private static void write(BufferedImage image, File file) throws IOException
    {
        ImageWriter writer = (ImageWriter) ImageIO.getImageWritersBySuffix(suffix(file)).next();
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        ImageOutputStream ios = ImageIO.createImageOutputStream(raf);
        writer.setOutput(ios);
        writer.write(image);
        writer.dispose();
        raf.close();
    }

    private static BufferedImage read(File file, int xStart, int yStart, int xStep, int yStep) throws IOException
    {
        ImageReader reader = (ImageReader) ImageIO.getImageReadersBySuffix(suffix(file)).next();
        ImageReadParam param = reader.getDefaultReadParam();
        param.setSourceSubsampling(xStep, yStep, xStart, yStart);
        RandomAccessFile raf = new RandomAccessFile(file, "r");
        ImageInputStream iis = ImageIO.createImageInputStream(raf);
        reader.setInput(iis);
        BufferedImage image = reader.read(0, param);
        reader.dispose();
        raf.close();
        return image;
    }

    private static String suffix(File file)
    {
        String fileName = file.getName();
        int i = fileName.lastIndexOf('.');
        return fileName.substring(i + 1);
    }

    private static void println(BufferedImage image, int band, int xStart, int yStart, int xStep, int yStep, int w, int h)
    {
        int[] samples = image.getRaster().getSamples(xStart, yStart, w, h, band, (int[]) null);
        for(int y = 0; y < h; y += yStep)
        {
            for(int x = 0; x < w; x += xStep)
                System.out.print(samples[x + w * y] + " ");
            System.out.println();
        }
    }

    public static void main(String[] args) throws IOException
    {

        int xStart = 0;
        int yStart = 0;
        int xStep = 2;
        int yStep = 2;
        int w = 20;
        int h = 1;

        File file = new File("test.png");
        file.deleteOnExit();

        BufferedImage imageBefore = createTestImage(256, 256);
        write(imageBefore, file);
        BufferedImage imageAfter = read(file, xStart, yStart, xStep, yStep);

        println(imageBefore, 0, xStart, yStart, xStep, yStep, w, h);
        println(imageAfter, 0, 0, 0, 1, 1, (w - xStart + xStep - 1) / xStep, (h - yStart + yStep - 1) / yStep);

    }

}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Don't use JAI Image I/O Tools
(Incident Review ID: 310766) 
======================================================================p
  xxxxx@xxxxx   10/7/04 01:33 GMT
Work Around
N/A
Evaluation
Problem due to an error in AffineTransformOp to be filed separately.
  xxxxx@xxxxx   10/7/04 01:33 GMT
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang