Skip to main content

Error while writting GIF

6 replies [Last post]
ycoupin
Offline
Joined: 2005-03-08

Hi,

I'm having a serious problem writing a GIF file using ImageIO's "imagewriter" JAI method. Using the binary 1.0_01 version I get this error while writing my file (excerpt) :

Caused by: java.lang.ArrayIndexOutOfBoundsException: 4480
at com.sun.media.imageioimpl.common.LZWCompressor.compress(LZWCompressor.java:98)
at com.sun.media.imageioimpl.plugins.gif.GIFImageWriter.writeRowsOpt(GIFImageWriter.java:768)
at com.sun.media.imageioimpl.plugins.gif.GIFImageWriter.writeRasterData(GIFImageWriter.java:833)
at com.sun.media.imageioimpl.plugins.gif.GIFImageWriter.writeImage(GIFImageWriter.java:714)
at com.sun.media.imageioimpl.plugins.gif.GIFImageWriter.write(GIFImageWriter.java:621)
at com.sun.media.imageioimpl.plugins.gif.GIFImageWriter.write(GIFImageWriter.java:460)

I tried without success (with some help from Aastha) to get the source from the CVS to check which line doesn't work (the binary bundle and CVS source obviously don't share the same disclaimer at the beginning, introducing some bias in the line count I get), but either using guest or my account, I can't checkout the CVS content. Any help in solving this problem would be GREATLY appreciated ! Of course if you need more info to solve the problem, I'll do my best to give them to you ASAP.

Yann

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
ycoupin
Offline
Joined: 2005-03-08

I think I've made some progress (seems my vacation last week was profitable after all ;)
I managed to checkout the source from CVS, there was a problem with the CVS server, it told me user guest didn't exists, not anymore (at least for this reason I feel less dumb). I compiled the source and can confirm the line number has changed, the error is now line 124, not 98 anymore.
During the tests I did I noticed the same source could be written to TIFF (RGB raw) but not GIF, so I loaded the TIFF and tried to write it to GIF (with the same parameters used for palette conversion). That worked too, so that meant the problem wasn't in the source image byte sequence which could cause the compressor to overflow (which was my first explanation). I then compared the properties of my read TIFF and the result of my transformation and noticed two differences copied below :

tiff:
image_width -> 128
image_height -> 35
image_min_x_coord -> 0
image_min_y_coord -> 0

calculation:
image_width -> 128
image_height -> 35
image_min_x_coord -> -23
image_min_y_coord -> 3

The negative coordinates are introduced by the jai "border" operator, while the positive y coordinate, is the result of a "crop" operation.

I guess this is the problem. I would have preferred to send you a real example, but my code is quite huge and relies on copyrighted source images I can't put here.

bpb
Offline
Joined: 2004-06-23

Yann,

I was unable to reproduce the problem you desribed when I used the test code below on an input GIF image. Both the cropped and the border images appeared to be correct and the code generated no exceptions.

Brian

/*
* Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed,licensed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
import java.awt.image.*;
import java.awt.image.renderable.*;
import java.io.*;
import javax.imageio.*;
import javax.media.jai.*;

public class TestGIFWrite {
public static void main(String[] args) throws Throwable {
RenderedImage source = ImageIO.read(new File(args[0]));

ParameterBlock pb = new ParameterBlock();

pb.addSource(source);
pb.add(3.0F).add(3.0F);
pb.add(source.getWidth()-3.0F).add(source.getHeight()-3.0F);
RenderedImage crop = JAI.create("crop", pb).getRendering();

System.out.println(crop);

ImageIO.write(crop, "GIF", new File("crop.gif"));

pb = new ParameterBlock();
pb.addSource(source);
pb.add(3).add(3).add(3).add(3);
RenderedImage border = JAI.create("border", pb).getRendering();

System.out.println(border);

ImageIO.write(border, "GIF", new File("border.gif"));
}
}

ycoupin
Offline
Joined: 2005-03-08

OK I managed to shrink my code to this small subset which triggers the problem. The source image is a random 150x150 pixels RGB tiff made for the occasion. I must say that I tried saving the source as a paletted image and commenting the dithering part and it didn't exhibit the problem. I put the image there in case you need it : http://www.coupin.net/150x150.tif

/*
* Created on 23 mars 2005
*
*/

import java.awt.image.renderable.ParameterBlock;

import javax.media.jai.JAI;
import javax.media.jai.KernelJAI;
import javax.media.jai.LookupTableJAI;
import javax.media.jai.RenderedOp;
import javax.media.jai.operator.ColorQuantizerDescriptor;

/**
* @author ycoupin
*
*/
public class GifWriterBug {

public static void main(String[] args) {
RenderedOp op = JAI.create("imageread", "c:\\150x150.tif");
System.out.println("Propriétés tiff :");
for (int i = 0; i< op.getPropertyNames().length; i++) {
System.out.println(op.getPropertyNames()[i]+" -> "+op.getProperty(op.getPropertyNames()[i]));
}

ParameterBlock pb = new ParameterBlock();
pb.addSource(op).add(11f).add(11f).add(128f).add(128f);
op = JAI.create("crop", pb);

pb = new ParameterBlock();
pb.addSource(op).add(ColorQuantizerDescriptor.MEDIANCUT).add(255);
LookupTableJAI colorMap = (LookupTableJAI)JAI.create("ColorQuantizer", pb).getProperty("LUT");
KernelJAI ditherMask = KernelJAI.ERROR_FILTER_FLOYD_STEINBERG;
pb.removeParameters();
pb.addSource(op).add(colorMap).add(ditherMask);
op = JAI.create("errordiffusion",pb);

JAI.create("imagewrite",op, "c:\\test-write.gif", "gif").dispose();
}
}

bpb
Offline
Joined: 2004-06-23

Sorry for the delayed response: messages are not being cross-posted automatically to our mailing list so I missed this.

In any case, I was able to reproduce the exception you reported although I did not analyze it further just yet.

Please note that you also have the possibility of submitting this issue directly at:

https://jai-imageio-core.dev.java.net/servlets/ProjectIssues

Regards,

Brian

bpb
Offline
Joined: 2004-06-23

This has been filed in the jai-imageio-core project as issue #8.

aastha
Offline
Joined: 2004-04-19

Hi Yann,

If you can provide a self-contained, compiling piece of code that demonstrates this problem, then we can investigate this further.

Thanks,

Aastha