[OpenJDK 2D-Dev] BufferedImage.getTileGridXOffset() not compliant with its specification?

Martin Desruisseaux martin.desruisseaux at geomatys.com
Sun Feb 23 11:12:35 UTC 2020


Le 23/02/2020 à 08:13, Sergey Bylokhov a écrit :

>> (…snip⋅), the second part of the sentence is much clearer:
>>
>>       i.e., the X coordinate of the upper-left pixel of tile (0, 0). 
>> (Note that tile (0, 0) may not actually exist.)
>>
> Note that this part does not exists in the specification of the 
> BufferedImage.
>
But BufferedImage specification said pretty much the same thing: "For 
example, the x coordinate of the location of tile (0, 0). This is always 
zero." (admittedly the meaning of "For example" here could be another 
interpretation debate).

Also even if BufferedImage does not duplicate RenderedImage javadoc, we 
usually expect implementations to obey to the contract specified in 
their interfaces, otherwise we get forced to write code like below 
(actually I indeed had to put this kind of code in Apache Spatial 
Information System):

    public void doSomething(RenderedImage image) {
         int tileGridXOffset;
         if (image instanceof BufferedImage) {
             /*
              * BufferedImage does not obey to RenderedImage specification!
              * We have to compute the value ourselves.
              */
             tileGridXOffset = image.getMinX() - image.getMinTileX() * image.getTileWidth();
         } else {
             /*
              * General case. But how could I know if there is other implementations
              * who decided to not obey to RenderedImage specification?
              */
             tileGridXOffset = image.getTileGridXOffset();
         }
    }


>> So we can write:
>>
>>     tileGridXOffset = minX - minTileX * tileWidth
>>
>> (…snip⋅)
>>
> I agree that all calculation above are valid for the simple 
> BufferedImage, but not sure about sub image, will check the history of 
> the file and its usage.
>
The above calculation is valid for both BufferedImage and sub-images, 
with the assumption that images have an integer number of tiles (if we 
accept fractional tiles, then "tileGridXOffset" and "minX - minTileX * 
tileWidth" can differ). With sub-images, either the image origin (0,0) 
is translated (this is what BufferedImage does), or the image origin is 
kept unchanged and the sub-image has a non-zero (minX, minY) value. In 
both cases the above tileGridXOffset calculation allows us to identfy 
correctly in which tile is a pixel at an arbitrary (x,y) location in a 
multi-tiled image (works also for single-tiled image and sub-areas). By 
contrast current BufferedImage implementation results in wrong numbers, 
which cause an ArrayIndexOutOfBoundsException to be thrown by 
BufferedImage.getTile(int, int) when we try to use those numbers.

The purpose of RenderedImage.getTileGridXOffset() is to provide 
information needed for converting pixel coordinates to tile indices and 
conversely. Current BufferedImage.getTileGridXOffset() implementation 
breaks this purpose, and in turn does not provide any information that I 
can see as useful at the image level (it is useful at the Raster / 
SampleModel level, but developers already have dedicated API for that). 
It is not even an offset of the sub-image compared to the parent image 
except by coincidence in the simple case (it depends on how the 
BufferedImage has been constructed).

     Regards,

         Martin


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/2d-dev/attachments/20200223/f615415d/attachment-0001.htm>


More information about the 2d-dev mailing list