JDK-4943659 : ImageWriter.write() fails when overweiting existing file
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.imageio
  • Affected Version: 1.4.1,1.4.2
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2003-10-24
  • Updated: 2015-11-03
Description

Name: rl43681			Date: 10/24/2003


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

FULL OS VERSION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
When using ImageWriter.write(IIOMetadata, IIOImage, ImageWriteParam) to write a .jpg with a certain quality setting, the image file is not written properly when the output file already exists, e.g. when the file present has a higher quality than the new image, the new image will be saved with a lower quality, but the filesize stays unchanged.

When writing the same image with the same low quality swtting without the file existing, the file size is much smaller.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the attached sample code with some input file 'test.jpg'. Make sure test_out* do not exist.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
See descripton.
ACTUAL -
See description.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.awt.image.BufferedImage;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageOutputStream;

public class QualityTest {
    public static void main(String[] args) throws IOException {
         BufferedImage image = ImageIO.read(new File("test.jpg"));
         
         System.out.println("Writing test_out1.jpg, quality: 1.0f");
         writeCompressedJPG(image, "test_out1.jpg", 1.0f); // Here, test_out1.jpg will be large with high quality, as it should be
                  
         System.out.println("Writing test_out1.jpg, quality: 0.1f");
         writeCompressedJPG(image, "test_out1.jpg", 0.1f); // Here, test_out1.jpg will still be large but with low quality, should be small/low quality

         System.out.println("Writing test_out2.jpg, quality: 1.0f");
         writeCompressedJPG(image, "test_out2.jpg", 1.0f); // Here, test_out2.jpg will be large with high quality, as it should be

         System.out.println("Writing test_out3.jpg, quality: 0.1f");
         writeCompressedJPG(image, "test_out3.jpg", 0.1f); // Here, test_out3.jpg will be small with low quality, as it should be
    }

    public static void writeCompressedJPG(BufferedImage image, String filename, float compressionQuality) throws IOException {
         Iterator writers = ImageIO.getImageWritersBySuffix("jpg");
         if (!writers.hasNext())
                      throw new IllegalStateException("No writers for jpg?!");
         ImageWriter writer = (ImageWriter) writers.next();

         ImageOutputStream out = ImageIO.createImageOutputStream(new File(filename));
         ImageWriteParam imageWriteParam = writer.getDefaultWriteParam();
         imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
         imageWriteParam.setCompressionQuality(compressionQuality);
         writer.setOutput(out);
         writer.write(null, new IIOImage(image, null, null), imageWriteParam);
         out.close();
         writer.dispose();
    }
} 


---------- END SOURCE ----------
(Incident Review ID: 217514) 
======================================================================

Comments
Please re-open if - if fix is in progress or on the plan to fix soon - if this is a P3 (file as P3, not P4)
18-03-2014

EVALUATION Name: abR10136 Date: 10/26/2003 The reason of the problem is that we do not drop old file content when create new FileImageOutputStream instance. So, if file already exist and its length greater than image data length we have old data tail in the result file. The proposed solution is reset length of the given RandomAccessFile instance to zero. ======================================================================
21-08-2004