United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6795544 GIFImageWriter does not write the subImage of BufferedImage to a file correctly.
JDK-6795544 : GIFImageWriter does not write the subImage of BufferedImage to a file correctly.

Details
Type:
Bug
Submit Date:
2009-01-20
Status:
Closed
Updated Date:
2011-03-07
Project Name:
JDK
Resolved Date:
2011-03-07
Component:
client-libs
OS:
solaris_2.5.1,windows_xp
Sub-Component:
javax.imageio
CPU:
x86,sparc
Priority:
P3
Resolution:
Fixed
Affected Versions:
6u10,6u11
Fixed Versions:

Related Reports

Sub Tasks

Description
When I save the subImage of BufferedImage with GIFImageWriter, the ImageWriter
write an incorrect region of the original image to a file.

I try to show the subImage on JFrame, the subImage seems like expected.
So I guess that GIFImageWriter does not work correctly.

If I use jpg/png ImageWrite, the ImageWriter will write a correct region
to a file.

- STEPS TO FOLLOW TO REPRODUCE THE PROBLEM:

OS: Windows XP SP2
JRE: 6u10, 6u11

1. Compile the following java code.
2. Run the program with a image (larger than 60x60).


- EXPECTED VERSUS ACTUAL BEHAVIOR:

EXPECTED:

Save a correct middle region (rectangular (30,30)-(60,60)) of the original file.

ACTUAL:

Save an incorrect middle region (rectangular (0,0)-(30,30)) of the original file.


For the following source code, this bug can be reproduced always.

---------- BEGIN SOURCE ----------

package test;

import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;

public class SaveSubImage extends JFrame {

	/**
	 * inFile (GIF)
	 */
	private static final String IN_GIF = "./resource/image.gif";

	/**
	 * outFile1
	 */
	private static final String OUT_GIF_1 = "./resource/image_sub_1.gif";

	/**
	 * outFile2
	 */
	private static final String OUT_GIF_2 = "./resource/image_sub_2.gif";

	/**
	 * imageFormat (jpg/png/gif)
	 */
	private static final String IMAGE_FORMAT = "gif";

	/**
	 * main.
	 * 
	 * @param args
	 *            args
	 */
	public static void main(String[] args) {

		try {
			BufferedImage originalImage = ImageIO.read(new File(IN_GIF));

			ImageWriter writer = ImageIO.getImageWritersByFormatName(
					IMAGE_FORMAT).next();

			// not correctly
			BufferedImage subImage1 = originalImage.getSubimage(30, 30, 30, 30);
			writer.setOutput(new FileImageOutputStream(new File(OUT_GIF_1)));
			writer.write(subImage1);

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

---------- END SOURCE ------------
Bug WorkaroundIf reconstructing a subImage of BufferedImage, the program will work correctly.

---------- BEGIN SOURCE ----------

			// correctly
			BufferedImage subImage2 = originalImage.getSubimage(30, 30, 30, 30);
			BufferedImage subImage3 = new BufferedImage(subImage2.getHeight(),
					subImage2.getWidth(), subImage2.getType(),
					(IndexColorModel) subImage2.getColorModel());
			subImage3.setData(subImage2.getData());
			writer.setOutput(new FileImageOutputStream(new File(OUT_GIF_2)));
			writer.write(subImage3);

---------- END SOURCE ------------

                                    

Comments
EVALUATION

The reason of problem here is that the optimized writing loop (utilized 
 direct access to image data buffer) does not take into account a data 
 band offset (which is non-trivial for sub-images, for example). It results 
 in writing image data starting from top left corner of the parent image 
 instead of expected top left corner of the sub-image.

 We  should take into account data bands offset, calculated by translated
 raster instance.
                                     
2009-01-21
SUGGESTED FIX

http://sa.sfbay.sun.com/projects/java2d_data/7/6795544.0
                                     
2009-01-23



Hardware and Software, Engineered to Work Together