Skip to main content

"Coordinate out of bounds!" writing gif

20 replies [Last post]
sitongia
Offline
Joined: 2004-03-04

Hi,
I have a simple program that reads in an image, rotates it, and writes it out as gif. If I write as png, it works. I get an exception if I write as gif:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
at sun.awt.image.ShortInterleavedRaster.getDataElements(ShortInterleavedRaster.java:221)
at com.sun.imageio.plugins.common.PaletteBuilder.getSrcColor(PaletteBuilder.java:185)
at com.sun.imageio.plugins.common.PaletteBuilder.buildPalette(PaletteBuilder.java:227)
at com.sun.imageio.plugins.common.PaletteBuilder.createIndexedImage(PaletteBuilder.java:76)
at com.sun.imageio.plugins.gif.GIFImageWriter.write(GIFImageWriter.java:564)
at com.sun.imageio.plugins.gif.GIFImageWriter.write(GIFImageWriter.java:492)
at javax.imageio.ImageWriter.write(ImageWriter.java:598)
at javax.imageio.ImageIO.write(ImageIO.java:1479)
at javax.imageio.ImageIO.write(ImageIO.java:1521)
at PSPT2gif.Main.main(Main.java:76)
Java Result: 1

All I change is "png" to "gif" in:

ImageIO.write(scaledImage, "gif", new File(args[1]));

Thank you for your help,
==Leonard

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Bob Deen

Nidel, Mike wrote:
> but the tile cache doesn't KNOW they are the same instance.
> so you don't end up consuming extra memory since the tile is only
> allocated once, but the tile cache THINKS there are two tiles when
> there is really only one, so it will flush tiles that otherwise
> could stay in the cache. note this is only a problem if you actually
> fill up your tile cache.

I agree that in general this can happen, and it is something to watch
out for (cache tuning is not for the faint of heart!!).

However, I think I recall that the translate op specifically does NOT
cache, since all it does is forward its source tiles on with a change
of origin. Noop may do the same thing.

I could be wrong, and a perusal of the source would probably clear
it up, but I'm going to have to leave that as an exercise for the reader.
;-)

-Bob

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

Nidel, Mike

That may be true. In our case, it was a BandSelect op that was
causing the problem, as well as possibly a format op. Those definitely
DO cache.

Both your and Robert's replies remind me that the real problem
is simply incorrect or uneducated setup of the caching for each op.
Allowing ops to use the default tile cache was the source of the
problem to begin with. I'm really just providing this lesson learned
as a caveat to people who are careless with their tile cache
assignments.
90% of users of JAI probably don't set up custom tile cache settings
anyway.

> -----Original Message-----
> From: Bob Deen [mailto:Bob.Deen@jpl.nasa.gov]
> Sent: Thursday, May 17, 2007 5:39 PM
> To: interest@jai-imageio.dev.java.net
> Subject: Re: [JAI-IMAGEIO] Tile caching (was Re: "Coordinate
> out of bounds!" writing gif)
>
> Nidel, Mike wrote:
> > but the tile cache doesn't KNOW they are the same instance.
> > so you don't end up consuming extra memory since the tile is only
> > allocated once, but the tile cache THINKS there are two tiles when
> > there is really only one, so it will flush tiles that
> otherwise could
> > stay in the cache. note this is only a problem if you
> actually fill up
> > your tile cache.
>
> I agree that in general this can happen, and it is something
> to watch out for (cache tuning is not for the faint of heart!!).
>
> However, I think I recall that the translate op specifically
> does NOT cache, since all it does is forward its source tiles
> on with a change of origin. Noop may do the same thing.
>
> I could be wrong, and a perusal of the source would probably
> clear it up, but I'm going to have to leave that as an
> exercise for the reader.
> ;-)
>
> -Bob
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail:
> interest-help@jai-imageio.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

Brian Burkhalter

Note that it is possible to supply a separate TileCache for each operation via
a RenderingHints key-value pair and that TileCache may have zero memory
capacity.

On Thu, 17 May 2007, Nidel, Mike wrote:

> That may be true. In our case, it was a BandSelect op that was
> causing the problem, as well as possibly a format op. Those definitely
> DO cache.
>
> Both your and Robert's replies remind me that the real problem
> is simply incorrect or uneducated setup of the caching for each op.
> Allowing ops to use the default tile cache was the source of the
> problem to begin with. I'm really just providing this lesson learned
> as a caveat to people who are careless with their tile cache
> assignments.
> 90% of users of JAI probably don't set up custom tile cache settings
> anyway.
>
>> -----Original Message-----
>> From: Bob Deen [mailto:Bob.Deen@jpl.nasa.gov]
>> Sent: Thursday, May 17, 2007 5:39 PM
>> To: interest@jai-imageio.dev.java.net
>> Subject: Re: [JAI-IMAGEIO] Tile caching (was Re: "Coordinate
>> out of bounds!" writing gif)
>>
>> Nidel, Mike wrote:
>>> but the tile cache doesn't KNOW they are the same instance.
>>> so you don't end up consuming extra memory since the tile is only
>>> allocated once, but the tile cache THINKS there are two tiles when
>>> there is really only one, so it will flush tiles that
>> otherwise could
>>> stay in the cache. note this is only a problem if you
>> actually fill up
>>> your tile cache.
>>
>> I agree that in general this can happen, and it is something
>> to watch out for (cache tuning is not for the faint of heart!!).
>>
>> However, I think I recall that the translate op specifically
>> does NOT cache, since all it does is forward its source tiles
>> on with a change of origin. Noop may do the same thing.
>>
>> I could be wrong, and a perusal of the source would probably
>> clear it up, but I'm going to have to leave that as an
>> exercise for the reader.
>> ;-)
>>
>> -Bob
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
>> For additional commands, e-mail:
>> interest-help@jai-imageio.dev.java.net
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail: interest-help@jai-imageio.dev.java.net
>
>

----------------
Brian Burkhalter
Java Media, Imaging, and Graphics
Sun Microsystems, Inc.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

James Cheng

>> i don't know much about the indexing. but you could find out a bit
>> about your image by printing out scaledImage.getMinX() and getMinY().
>> If they are not 0 then your image's upper left corner is shifted to
>> accommodate the rotation, in which case this might cause the problem.
>> try to write it as a JPEG instead of GIF and see if you get any errors.
>
> I suspect this is the issue. If so, a bug should be filed against the GIF
> writer, because it should be able to handle images with non-0 origins
> (doing an internal translation if the format itself doesn't know anything
> about translating images).

The stack trace in the original post seems to show that the JRE built-in
GIF writer was used, so I cc the Java Image I/O interest list.

If you see a similar problem with the GIF writer of jai-imageio, please
file an issue (preferably with a test case) at:

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

Thanks,
-James

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

Nidel, Mike

I had a couple further comments about no-op nodes in a chain.
See below.

> It's possible the gif writer might do something like that
> anyway internally, but it's best not to force the issue.
> Well-written writers can deal with tiles. So, just do a
> translate by the negative of
> getMinX()/getMinY() as suggested above and that should take
> care of the problem. (don't try to make it conditional; if
> the origin is 0,0 already then translate will do nothing, and
> it is an exceptionally fast operation so you won't see any
> performance penalty).

The one thing I will say is that there CAN be a penalty associated with
creating otherwise-unnecessary nodes in the operator graph. We had
a case where this caused us a sizable performance hit, due to a bit of
bad/mistaken design combined with an incomplete understanding of the
interplay of caching with certain operators.

Let's say we have a chain with two operators, X and Y, both of which
share
a single cache. The result image R can be represented in a kind of
functional
notation as:

R = Y(X(I))

where I is the input image. Now let's say that for certain cases, Y is a
no-op. Therefore Y(X(I)) = X(I) in a computational sense. However, the
tile cache
does not know this. Therefore if a tile passes through X and then Y,
these are
the same tile, but with two different owner RenderedOps. Thus, the same
tile
can be cached twice.

This isn't at all a serious issue, but it is a subtlety that can cause
performance problems if overlooked. In our case, we are caching the
input
tiles in one cache, to avoid re-reading tiles from disk, which can be
slow.
Then we were also accidentally caching some of our operators' tiles in
the
same cache, which meant they were competing with the read cache for
space.
This would have been true even if there weren't any unnecessary
operators in
the chain, but it was made worse by the fact that tiles that didn't even
NEED to be cached were pushing tiles that absolutely needed to be cached
out.

Tile caching for complicated chains is definitely a fine art.

Mike

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

robert engels

That doesn't make a lot of sense. The no-op should be returning the
same tile instance in memory, so there should be minimal overhead.

On May 17, 2007, at 4:07 PM, Nidel, Mike wrote:

> I had a couple further comments about no-op nodes in a chain.
> See below.
>
>> It's possible the gif writer might do something like that
>> anyway internally, but it's best not to force the issue.
>> Well-written writers can deal with tiles. So, just do a
>> translate by the negative of
>> getMinX()/getMinY() as suggested above and that should take
>> care of the problem. (don't try to make it conditional; if
>> the origin is 0,0 already then translate will do nothing, and
>> it is an exceptionally fast operation so you won't see any
>> performance penalty).
>
>
> The one thing I will say is that there CAN be a penalty associated
> with
> creating otherwise-unnecessary nodes in the operator graph. We had
> a case where this caused us a sizable performance hit, due to a bit of
> bad/mistaken design combined with an incomplete understanding of the
> interplay of caching with certain operators.
>
>
> Let's say we have a chain with two operators, X and Y, both of which
> share
> a single cache. The result image R can be represented in a kind of
> functional
> notation as:
>
> R = Y(X(I))
>
> where I is the input image. Now let's say that for certain cases, Y
> is a
> no-op. Therefore Y(X(I)) = X(I) in a computational sense. However, the
> tile cache
> does not know this. Therefore if a tile passes through X and then Y,
> these are
> the same tile, but with two different owner RenderedOps. Thus, the
> same
> tile
> can be cached twice.
>
> This isn't at all a serious issue, but it is a subtlety that can cause
> performance problems if overlooked. In our case, we are caching the
> input
> tiles in one cache, to avoid re-reading tiles from disk, which can be
> slow.
> Then we were also accidentally caching some of our operators' tiles in
> the
> same cache, which meant they were competing with the read cache for
> space.
> This would have been true even if there weren't any unnecessary
> operators in
> the chain, but it was made worse by the fact that tiles that didn't
> even
> NEED to be cached were pushing tiles that absolutely needed to be
> cached
> out.
>
> Tile caching for complicated chains is definitely a fine art.
>
> Mike
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail: interest-help@jai-
> imageio.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

Nidel, Mike

but the tile cache doesn't KNOW they are the same instance.
so you don't end up consuming extra memory since the tile is only
allocated once, but the tile cache THINKS there are two tiles when
there is really only one, so it will flush tiles that otherwise
could stay in the cache. note this is only a problem if you actually
fill up your tile cache.

> -----Original Message-----
> From: robert engels [mailto:rengels@ix.netcom.com]
> Sent: Thursday, May 17, 2007 5:23 PM
> To: interest@jai-imageio.dev.java.net
> Subject: Re: [JAI-IMAGEIO] Re: "Coordinate out of bounds!" writing gif
>
> That doesn't make a lot of sense. The no-op should be
> returning the same tile instance in memory, so there should
> be minimal overhead.
>
> On May 17, 2007, at 4:07 PM, Nidel, Mike wrote:
>
> > I had a couple further comments about no-op nodes in a chain.
> > See below.
> >
> >> It's possible the gif writer might do something like that anyway
> >> internally, but it's best not to force the issue.
> >> Well-written writers can deal with tiles. So, just do a
> translate by
> >> the negative of
> >> getMinX()/getMinY() as suggested above and that should
> take care of
> >> the problem. (don't try to make it conditional; if the
> origin is 0,0
> >> already then translate will do nothing, and it is an exceptionally
> >> fast operation so you won't see any performance penalty).
> >
> >
> > The one thing I will say is that there CAN be a penalty associated
> > with creating otherwise-unnecessary nodes in the operator graph. We
> > had a case where this caused us a sizable performance hit, due to a
> > bit of bad/mistaken design combined with an incomplete
> understanding
> > of the interplay of caching with certain operators.
> >
> >
> > Let's say we have a chain with two operators, X and Y, both
> of which
> > share a single cache. The result image R can be represented
> in a kind
> > of functional notation as:
> >
> > R = Y(X(I))
> >
> > where I is the input image. Now let's say that for certain
> cases, Y is
> > a no-op. Therefore Y(X(I)) = X(I) in a computational sense.
> However,
> > the tile cache does not know this. Therefore if a tile
> passes through
> > X and then Y, these are the same tile, but with two different owner
> > RenderedOps. Thus, the same tile can be cached twice.
> >
> > This isn't at all a serious issue, but it is a subtlety
> that can cause
> > performance problems if overlooked. In our case, we are caching the
> > input tiles in one cache, to avoid re-reading tiles from
> disk, which
> > can be slow.
> > Then we were also accidentally caching some of our
> operators' tiles in
> > the same cache, which meant they were competing with the read cache
> > for space.
> > This would have been true even if there weren't any unnecessary
> > operators in the chain, but it was made worse by the fact
> that tiles
> > that didn't even NEED to be cached were pushing tiles that
> absolutely
> > needed to be cached out.
> >
> > Tile caching for complicated chains is definitely a fine art.
> >
> > Mike
> >
> >
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail:
> interest-unsubscribe@jai-imageio.dev.java.net
> > For additional commands, e-mail: interest-help@jai-
> > imageio.dev.java.net
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail:
> interest-help@jai-imageio.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

robert engels

Ah.

Seems to be a need to for a NoCacheTile marker interface that could
be used by a Raster implementation, or add a method to RenderedImage
getTile() that returns a Tile object, with an additional method
isCacheable() ?

Since I assume the no-op is not a no-op in all cases.

Robert

On May 17, 2007, at 4:27 PM, Nidel, Mike wrote:

> but the tile cache doesn't KNOW they are the same instance.
> so you don't end up consuming extra memory since the tile is only
> allocated once, but the tile cache THINKS there are two tiles when
> there is really only one, so it will flush tiles that otherwise
> could stay in the cache. note this is only a problem if you actually
> fill up your tile cache.
>
>> -----Original Message-----
>> From: robert engels [mailto:rengels@ix.netcom.com]
>> Sent: Thursday, May 17, 2007 5:23 PM
>> To: interest@jai-imageio.dev.java.net
>> Subject: Re: [JAI-IMAGEIO] Re: "Coordinate out of bounds!" writing
>> gif
>>
>> That doesn't make a lot of sense. The no-op should be
>> returning the same tile instance in memory, so there should
>> be minimal overhead.
>>
>> On May 17, 2007, at 4:07 PM, Nidel, Mike wrote:
>>
>>> I had a couple further comments about no-op nodes in a chain.
>>> See below.
>>>
>>>> It's possible the gif writer might do something like that anyway
>>>> internally, but it's best not to force the issue.
>>>> Well-written writers can deal with tiles. So, just do a
>> translate by
>>>> the negative of
>>>> getMinX()/getMinY() as suggested above and that should
>> take care of
>>>> the problem. (don't try to make it conditional; if the
>> origin is 0,0
>>>> already then translate will do nothing, and it is an exceptionally
>>>> fast operation so you won't see any performance penalty).
>>>
>>>
>>> The one thing I will say is that there CAN be a penalty associated
>>> with creating otherwise-unnecessary nodes in the operator graph. We
>>> had a case where this caused us a sizable performance hit, due to a
>>> bit of bad/mistaken design combined with an incomplete
>> understanding
>>> of the interplay of caching with certain operators.
>>>
>>>
>>> Let's say we have a chain with two operators, X and Y, both
>> of which
>>> share a single cache. The result image R can be represented
>> in a kind
>>> of functional notation as:
>>>
>>> R = Y(X(I))
>>>
>>> where I is the input image. Now let's say that for certain
>> cases, Y is
>>> a no-op. Therefore Y(X(I)) = X(I) in a computational sense.
>> However,
>>> the tile cache does not know this. Therefore if a tile
>> passes through
>>> X and then Y, these are the same tile, but with two different owner
>>> RenderedOps. Thus, the same tile can be cached twice.
>>>
>>> This isn't at all a serious issue, but it is a subtlety
>> that can cause
>>> performance problems if overlooked. In our case, we are caching the
>>> input tiles in one cache, to avoid re-reading tiles from
>> disk, which
>>> can be slow.
>>> Then we were also accidentally caching some of our
>> operators' tiles in
>>> the same cache, which meant they were competing with the read cache
>>> for space.
>>> This would have been true even if there weren't any unnecessary
>>> operators in the chain, but it was made worse by the fact
>> that tiles
>>> that didn't even NEED to be cached were pushing tiles that
>> absolutely
>>> needed to be cached out.
>>>
>>> Tile caching for complicated chains is definitely a fine art.
>>>
>>> Mike
>>>
>>>
>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail:
>> interest-unsubscribe@jai-imageio.dev.java.net
>>> For additional commands, e-mail: interest-help@jai-
>>> imageio.dev.java.net
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
>> For additional commands, e-mail:
>> interest-help@jai-imageio.dev.java.net
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail: interest-help@jai-
> imageio.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

robert engels

Actually, in reviewing the code, it appears that the op is
responsible for the caching, and I inspected the TranslateOpImage and
it does not do any caching.

On May 17, 2007, at 4:38 PM, robert engels wrote:

> Ah.
>
> Seems to be a need to for a NoCacheTile marker interface that could
> be used by a Raster implementation, or add a method to
> RenderedImage getTile() that returns a Tile object, with an
> additional method isCacheable() ?
>
> Since I assume the no-op is not a no-op in all cases.
>
> Robert
>
> On May 17, 2007, at 4:27 PM, Nidel, Mike wrote:
>
>> but the tile cache doesn't KNOW they are the same instance.
>> so you don't end up consuming extra memory since the tile is only
>> allocated once, but the tile cache THINKS there are two tiles when
>> there is really only one, so it will flush tiles that otherwise
>> could stay in the cache. note this is only a problem if you actually
>> fill up your tile cache.
>>
>>> -----Original Message-----
>>> From: robert engels [mailto:rengels@ix.netcom.com]
>>> Sent: Thursday, May 17, 2007 5:23 PM
>>> To: interest@jai-imageio.dev.java.net
>>> Subject: Re: [JAI-IMAGEIO] Re: "Coordinate out of bounds!"
>>> writing gif
>>>
>>> That doesn't make a lot of sense. The no-op should be
>>> returning the same tile instance in memory, so there should
>>> be minimal overhead.
>>>
>>> On May 17, 2007, at 4:07 PM, Nidel, Mike wrote:
>>>
>>>> I had a couple further comments about no-op nodes in a chain.
>>>> See below.
>>>>
>>>>> It's possible the gif writer might do something like that anyway
>>>>> internally, but it's best not to force the issue.
>>>>> Well-written writers can deal with tiles. So, just do a
>>> translate by
>>>>> the negative of
>>>>> getMinX()/getMinY() as suggested above and that should
>>> take care of
>>>>> the problem. (don't try to make it conditional; if the
>>> origin is 0,0
>>>>> already then translate will do nothing, and it is an exceptionally
>>>>> fast operation so you won't see any performance penalty).
>>>>
>>>>
>>>> The one thing I will say is that there CAN be a penalty associated
>>>> with creating otherwise-unnecessary nodes in the operator graph. We
>>>> had a case where this caused us a sizable performance hit, due to a
>>>> bit of bad/mistaken design combined with an incomplete
>>> understanding
>>>> of the interplay of caching with certain operators.
>>>>
>>>>
>>>> Let's say we have a chain with two operators, X and Y, both
>>> of which
>>>> share a single cache. The result image R can be represented
>>> in a kind
>>>> of functional notation as:
>>>>
>>>> R = Y(X(I))
>>>>
>>>> where I is the input image. Now let's say that for certain
>>> cases, Y is
>>>> a no-op. Therefore Y(X(I)) = X(I) in a computational sense.
>>> However,
>>>> the tile cache does not know this. Therefore if a tile
>>> passes through
>>>> X and then Y, these are the same tile, but with two different owner
>>>> RenderedOps. Thus, the same tile can be cached twice.
>>>>
>>>> This isn't at all a serious issue, but it is a subtlety
>>> that can cause
>>>> performance problems if overlooked. In our case, we are caching the
>>>> input tiles in one cache, to avoid re-reading tiles from
>>> disk, which
>>>> can be slow.
>>>> Then we were also accidentally caching some of our
>>> operators' tiles in
>>>> the same cache, which meant they were competing with the read cache
>>>> for space.
>>>> This would have been true even if there weren't any unnecessary
>>>> operators in the chain, but it was made worse by the fact
>>> that tiles
>>>> that didn't even NEED to be cached were pushing tiles that
>>> absolutely
>>>> needed to be cached out.
>>>>
>>>> Tile caching for complicated chains is definitely a fine art.
>>>>
>>>> Mike
>>>>
>>>>
>>> --------------------------------------------------------------------
>>> -
>>>> To unsubscribe, e-mail:
>>> interest-unsubscribe@jai-imageio.dev.java.net
>>>> For additional commands, e-mail: interest-help@jai-
>>>> imageio.dev.java.net
>>>>
>>>
>>> --------------------------------------------------------------------
>>> -
>>> To unsubscribe, e-mail: interest-unsubscribe@jai-
>>> imageio.dev.java.net
>>> For additional commands, e-mail:
>>> interest-help@jai-imageio.dev.java.net
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
>> For additional commands, e-mail: interest-help@jai-
>> imageio.dev.java.net
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail: interest-help@jai-
> imageio.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

robert engels

When you rotate you might create colors that are not in the original
image - due to aliasing/interpolation.

When you write as a GIF you may have too many colors than can be
represented.

Either way though, your code below looks correct, so I am betting
that there is a problem with the GIF writer, and that it is not
handling the offsets correctly.

You might try creating a BufferedImage first, just to see if that
solves the problem.

On May 17, 2007, at 3:14 PM, jai-imageio@javadesktop.org wrote:

> Thank you for your replies.
>
> I'm rotating an image that is 512x512. It gets Extender'd to
> 677x677. I'd think that the origin would be the right place (but
> not the origin of my original data, but that's okay). I wouldn't
> know how to translate it, the rotation is a variable amount of
> float. It's an image of the Sun, and so it stays round ;-) and
> I'll probably clip it back to 512x512.
>
> I do:
>
> BufferedImage fImage = ImageIO.read(new FileInputStream
> (args[0]));
> ...
> PlanarImage scaledImage = JAI.create("rotate", pb, hint);
> ImageIO.write(scaledImage, "gif", new File(args[1]));
>
> I have another program in which I do a transpose instead of the
> rotate. No error. Also, no error when writing a png. Could you
> elaborate on the indexing and how this would be different for gif
> and png, and how it relates to rotation?
>
> Thanks!
> ==Leonard
> [Message sent by forum member 'sitongia' (sitongia)]
>
> http://forums.java.net/jive/thread.jspa?messageID=217712
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail: interest-help@jai-
> imageio.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

sitongia
Offline
Joined: 2004-03-04

Thank you all! The translation resolved this. Not surprisingly, the negative origin surprises me. I figured the extender took care of filling in pixels such that the result was an larger image, simply writable. Obviously, I don't understand the coordinate model.

==Leonard

Nidel, Mike

to help visualize this, you could take a small piece of paper and a
larger one. put the small one on top of the big one like this (pardon my
ASCII art):

-----------
| |
| ----- |
| | | |
| | | |
| ----- |
| |
-----------

the large paper is your coordinate system the small one is your image.
make a mark at the upper left of the small paper, this is the origin. if
you want, draw X and Y axes along the top and left sides of the small
paper.

NOW, put your finger in the center of the small paper (image) and rotate
it without rotating the big paper (coordinate system). notice that the
corners of the image now extend into negative space, above the x axis
and left of the y axis. your minX and minY are now negative. by
translating after the rotation, you are effectively repositioning the
image so that its edges line up with the coordinate axes.

Hope that clears it up a bit.

Mike

> -----Original Message-----
> From: jai-imageio@javadesktop.org
> [mailto:jai-imageio@javadesktop.org]
> Sent: Thursday, May 17, 2007 5:10 PM
> To: interest@jai-imageio.dev.java.net
> Subject: [JAI-IMAGEIO] Re: "Coordinate out of bounds!" writing gif
>
> Thank you all! The translation resolved this. Not
> surprisingly, the negative origin surprises me. I figured
> the extender took care of filling in pixels such that the
> result was an larger image, simply writable. Obviously, I
> don't understand the coordinate model.
>
> ==Leonard
> [Message sent by forum member 'sitongia' (sitongia)]
>
> http://forums.java.net/jive/thread.jspa?messageID=217726
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail:
> interest-help@jai-imageio.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

sitongia
Offline
Joined: 2004-03-04

Huh. MinX and MinY are both -83.

Nidel, Mike

not at all surprising, if you're rotating the image about the center.
are you rotating by 45 degrees?

> -----Original Message-----
> From: jai-imageio@javadesktop.org
> [mailto:jai-imageio@javadesktop.org]
> Sent: Thursday, May 17, 2007 4:31 PM
> To: interest@jai-imageio.dev.java.net
> Subject: [JAI-IMAGEIO] Re: "Coordinate out of bounds!" writing gif
>
> Huh. MinX and MinY are both -83.
> [Message sent by forum member 'sitongia' (sitongia)]
>
> http://forums.java.net/jive/thread.jspa?messageID=217718
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail:
> interest-help@jai-imageio.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

sitongia
Offline
Joined: 2004-03-04

Thank you for your replies.

I'm rotating an image that is 512x512. It gets Extender'd to 677x677. I'd think that the origin would be the right place (but not the origin of my original data, but that's okay). I wouldn't know how to translate it, the rotation is a variable amount of float. It's an image of the Sun, and so it stays round ;-) and I'll probably clip it back to 512x512.

I do:

BufferedImage fImage = ImageIO.read(new FileInputStream(args[0]));
...
PlanarImage scaledImage = JAI.create("rotate", pb, hint);
ImageIO.write(scaledImage, "gif", new File(args[1]));

I have another program in which I do a transpose instead of the rotate. No error. Also, no error when writing a png. Could you elaborate on the indexing and how this would be different for gif and png, and how it relates to rotation?

Thanks!
==Leonard

Nidel, Mike

i don't know much about the indexing. but you could find out a bit
about your image by printing out scaledImage.getMinX() and getMinY().
If they are not 0 then your image's upper left corner is shifted to
accommodate the rotation, in which case this might cause the problem.
try to write it as a JPEG instead of GIF and see if you get any errors.

one thing you could try is

PlanarImage scaledImage = JAI.create("rotate", pb, hint);
BufferedImage bufferedImage = scaledImage.getAsBufferedImage();
ImageIO.write(bufferedImage, "gif", new File(args[1]));

A BufferedImage by definition has its origin at 0,0 so this might
work. Alternatively, you could insert a "translate" operator into
the chain before you write the output. Just get the MinX and MinY
as I mentioned above and translate by (-MinX, -MinY). See the
translate operator javadocs for more info.

> -----Original Message-----
> From: jai-imageio@javadesktop.org
> [mailto:jai-imageio@javadesktop.org]
> Sent: Thursday, May 17, 2007 4:14 PM
> To: interest@jai-imageio.dev.java.net
> Subject: [JAI-IMAGEIO] Re: "Coordinate out of bounds!" writing gif
>
> Thank you for your replies.
>
> I'm rotating an image that is 512x512. It gets Extender'd to
> 677x677. I'd think that the origin would be the right place
> (but not the origin of my original data, but that's okay). I
> wouldn't know how to translate it, the rotation is a variable
> amount of float. It's an image of the Sun, and so it stays
> round ;-) and I'll probably clip it back to 512x512.
>
> I do:
>
> BufferedImage fImage = ImageIO.read(new
> FileInputStream(args[0])); ...
> PlanarImage scaledImage = JAI.create("rotate", pb, hint);
> ImageIO.write(scaledImage, "gif", new File(args[1]));
>
> I have another program in which I do a transpose instead of
> the rotate. No error. Also, no error when writing a png.
> Could you elaborate on the indexing and how this would be
> different for gif and png, and how it relates to rotation?
>
> Thanks!
> ==Leonard
> [Message sent by forum member 'sitongia' (sitongia)]
>
> http://forums.java.net/jive/thread.jspa?messageID=217712
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail:
> interest-help@jai-imageio.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

Bob Deen

> i don't know much about the indexing. but you could find out a bit
> about your image by printing out scaledImage.getMinX() and getMinY().
> If they are not 0 then your image's upper left corner is shifted to
> accommodate the rotation, in which case this might cause the problem.
> try to write it as a JPEG instead of GIF and see if you get any errors.

I suspect this is the issue. If so, a bug should be filed against the GIF
writer, because it should be able to handle images with non-0 origins
(doing an internal translation if the format itself doesn't know anything
about translating images).

> one thing you could try is
>
> PlanarImage scaledImage = JAI.create("rotate", pb, hint);
> BufferedImage bufferedImage = scaledImage.getAsBufferedImage();
> ImageIO.write(bufferedImage, "gif", new File(args[1]));
>
> A BufferedImage by definition has its origin at 0,0 so this might
> work. Alternatively, you could insert a "translate" operator into
> the chain before you write the output. Just get the MinX and MinY
> as I mentioned above and translate by (-MinX, -MinY). See the
> translate operator javadocs for more info.

The alternate is far cleaner and probably more efficient too.
getAsBufferedImage() is a very bad thing to do generally, as it
destroys any kind of tiling you might have and forces the entire
image to be in memory at once.

It's possible the gif writer might do something like that anyway
internally, but it's best not to force the issue. Well-written writers
can deal with tiles. So, just do a translate by the negative of
getMinX()/getMinY() as suggested above and that should take
care of the problem. (don't try to make it conditional; if the origin
is 0,0 already then translate will do nothing, and it is an exceptionally
fast operation so you won't see any performance penalty).

-Bob

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

Nidel, Mike

> > one thing you could try is
> >
> > PlanarImage scaledImage = JAI.create("rotate", pb, hint);
> > BufferedImage bufferedImage = scaledImage.getAsBufferedImage();
> > ImageIO.write(bufferedImage, "gif", new File(args[1]));
> >
> > A BufferedImage by definition has its origin at 0,0 so this might
> > work. Alternatively, you could insert a "translate"
> operator into the
> > chain before you write the output. Just get the MinX and MinY as I
> > mentioned above and translate by (-MinX, -MinY). See the translate
> > operator javadocs for more info.
>
> The alternate is far cleaner and probably more efficient too.
> getAsBufferedImage() is a very bad thing to do generally, as
> it destroys any kind of tiling you might have and forces the
> entire image to be in memory at once.
>
> It's possible the gif writer might do something like that
> anyway internally, but it's best not to force the issue.
> Well-written writers can deal with tiles. So, just do a
> translate by the negative of
> getMinX()/getMinY() as suggested above and that should take
> care of the problem. (don't try to make it conditional; if
> the origin is 0,0 already then translate will do nothing, and
> it is an exceptionally fast operation so you won't see any
> performance penalty).

yup, i realized this. i made a mental tradeoff in my suggestion but
didn't explain my reasoning. basically if your format is really
hardcoded
and you know you're only writing GIF (which is a nontiled format) then
getAsBufferedImage() saves you the complexity of creating a
parameterblock
etc. but that's just my laziness talking, i realize it's a hack. so do
what
Bob suggests.

I do have another thought but I will post it separately since it is
tangent to the original thread.

Mike

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

robert engels

I believe GIF has a limitations on size. 64k by 64k. Could you be
hitting this limit?

More likely you are trying to reuse the underlying raster, and it is
not compatible with the indexed format.

On May 17, 2007, at 2:03 PM, jai-imageio@javadesktop.org wrote:

> Hi,
> I have a simple program that reads in an image, rotates it, and
> writes it out as gif. If I write as png, it works. I get an
> exception if I write as gif:
>
> Exception in thread "main"
> java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
> at sun.awt.image.ShortInterleavedRaster.getDataElements
> (ShortInterleavedRaster.java:221)
> at com.sun.imageio.plugins.common.PaletteBuilder.getSrcColor
> (PaletteBuilder.java:185)
> at
> com.sun.imageio.plugins.common.PaletteBuilder.buildPalette
> (PaletteBuilder.java:227)
> at
> com.sun.imageio.plugins.common.PaletteBuilder.createIndexedImage
> (PaletteBuilder.java:76)
> at com.sun.imageio.plugins.gif.GIFImageWriter.write
> (GIFImageWriter.java:564)
> at com.sun.imageio.plugins.gif.GIFImageWriter.write
> (GIFImageWriter.java:492)
> at javax.imageio.ImageWriter.write(ImageWriter.java:598)
> at javax.imageio.ImageIO.write(ImageIO.java:1479)
> at javax.imageio.ImageIO.write(ImageIO.java:1521)
> at PSPT2gif.Main.main(Main.java:76)
> Java Result: 1
>
> All I change is "png" to "gif" in:
>
> ImageIO.write(scaledImage, "gif", new File(args[1]));
>
> Thank you for your help,
> ==Leonard
> [Message sent by forum member 'sitongia' (sitongia)]
>
> http://forums.java.net/jive/thread.jspa?messageID=217703
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail: interest-help@jai-
> imageio.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net

Nidel, Mike

off the top of my head, one thing you might want to try is to translate
the rotated image so that its upper left corner is at (0,0). when you
rotate,
the coordinate system of the image changes in ways you might not
intuitively
expect. i know i've had this problem with JPEG before, but i haven't
written
GIFs so I don't know if it's the same issue.

Mike

> -----Original Message-----
> From: jai-imageio@javadesktop.org
> [mailto:jai-imageio@javadesktop.org]
> Sent: Thursday, May 17, 2007 3:03 PM
> To: interest@jai-imageio.dev.java.net
> Subject: [JAI-IMAGEIO] "Coordinate out of bounds!" writing gif
>
> Hi,
> I have a simple program that reads in an image, rotates it,
> and writes it out as gif. If I write as png, it works. I
> get an exception if I write as gif:
>
> Exception in thread "main"
> java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
> at
> sun.awt.image.ShortInterleavedRaster.getDataElements(ShortInte
> rleavedRaster.java:221)
> at
> com.sun.imageio.plugins.common.PaletteBuilder.getSrcColor(Pale
> tteBuilder.java:185)
> at
> com.sun.imageio.plugins.common.PaletteBuilder.buildPalette(Pal
> etteBuilder.java:227)
> at
> com.sun.imageio.plugins.common.PaletteBuilder.createIndexedIma
> ge(PaletteBuilder.java:76)
> at
> com.sun.imageio.plugins.gif.GIFImageWriter.write(GIFImageWrite
> r.java:564)
> at
> com.sun.imageio.plugins.gif.GIFImageWriter.write(GIFImageWrite
> r.java:492)
> at javax.imageio.ImageWriter.write(ImageWriter.java:598)
> at javax.imageio.ImageIO.write(ImageIO.java:1479)
> at javax.imageio.ImageIO.write(ImageIO.java:1521)
> at PSPT2gif.Main.main(Main.java:76) Java Result: 1
>
> All I change is "png" to "gif" in:
>
> ImageIO.write(scaledImage, "gif", new File(args[1]));
>
> Thank you for your help,
> ==Leonard
> [Message sent by forum member 'sitongia' (sitongia)]
>
> http://forums.java.net/jive/thread.jspa?messageID=217703
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
> For additional commands, e-mail:
> interest-help@jai-imageio.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai-imageio.dev.java.net
For additional commands, e-mail: interest-help@jai-imageio.dev.java.net