This is an automated email from the ASF dual-hosted git repository. jsorel pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push: new 1fb2aabbfa Implement TiledGridResource for Uncompressed items in GIMI Store 1fb2aabbfa is described below commit 1fb2aabbfa2bc019aeb8b25b8d2d804884e20cf5 Author: jsorel <johann.so...@geomatys.com> AuthorDate: Fri Oct 4 10:24:32 2024 +0200 Implement TiledGridResource for Uncompressed items in GIMI Store --- .../storage/gimi/ResourceImageUncompressed.java | 123 ++++++++++++++++----- 1 file changed, 93 insertions(+), 30 deletions(-) diff --git a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageUncompressed.java b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageUncompressed.java index 03b95d9168..6ec4f1bb41 100644 --- a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageUncompressed.java +++ b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageUncompressed.java @@ -17,11 +17,17 @@ package org.apache.sis.storage.gimi; import java.awt.Point; -import java.awt.image.BufferedImage; +import java.awt.Transparency; +import java.awt.color.ColorSpace; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; +import java.awt.image.PixelInterleavedSampleModel; import java.awt.image.Raster; +import java.awt.image.SampleModel; import java.awt.image.WritableRaster; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -31,16 +37,16 @@ import org.opengis.util.FactoryException; import org.opengis.util.GenericName; import org.apache.sis.coverage.SampleDimension; import org.apache.sis.coverage.grid.GridCoverage; -import org.apache.sis.coverage.grid.GridCoverageBuilder; import org.apache.sis.coverage.grid.GridExtent; import org.apache.sis.coverage.grid.GridGeometry; import org.apache.sis.coverage.grid.PixelInCell; import org.apache.sis.referencing.CommonCRS; import org.apache.sis.referencing.privy.AffineTransform2D; -import org.apache.sis.storage.AbstractGridCoverageResource; import org.apache.sis.storage.DataStore; import org.apache.sis.storage.DataStoreException; import org.apache.sis.storage.base.StoreResource; +import org.apache.sis.storage.base.TiledGridCoverage; +import org.apache.sis.storage.base.TiledGridResource; import org.apache.sis.storage.gimi.isobmff.Box; import org.apache.sis.storage.gimi.isobmff.gimi.ModelTiePointProperty; import org.apache.sis.storage.gimi.isobmff.gimi.ModelTransformationProperty; @@ -58,7 +64,7 @@ import org.opengis.referencing.operation.MathTransform; * * @author Johann Sorel (Geomatys) */ -class ResourceImageUncompressed extends AbstractGridCoverageResource implements StoreResource { +class ResourceImageUncompressed extends TiledGridResource implements StoreResource { public static final String TYPE = "unci"; protected final GimiStore store; @@ -96,6 +102,8 @@ class ResourceImageUncompressed extends AbstractGridCoverageResource implements private final int tileWidth; private final int tileHeight; private final int tileByteArrayLength; + private final SampleModel sampleModel; + private final ColorModel colorModel; public ResourceImageUncompressed(GimiStore store, Item item) throws DataStoreException { super(store); @@ -142,6 +150,32 @@ class ResourceImageUncompressed extends AbstractGridCoverageResource implements } else { throw new DataStoreException("Failed to compute tile sizein bytes"); } + + if ( (compDef != null && Arrays.equals(compDef.componentType, new int[]{4,5,6})) + || (pixelDef != null && pixelDef.bitsPerChannel.length == 3) + ) { + // RGB case + final ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + final int[] nBits = {8, 8, 8}; + final int[] bOffs = {2, 1, 0}; + colorModel = new ComponentColorModel( + cs, + nBits, + false, + false, + Transparency.OPAQUE, + DataBuffer.TYPE_BYTE); + sampleModel = new PixelInterleavedSampleModel( + DataBuffer.TYPE_BYTE, + tileWidth, + tileHeight, + 3, + tileWidth * 3, + bOffs); + } else { + throw new DataStoreException("Unsupported component model"); + } + } @Override @@ -207,41 +241,33 @@ class ResourceImageUncompressed extends AbstractGridCoverageResource implements } @Override - public GridCoverage read(GridGeometry gg, int... ints) throws DataStoreException { + protected int[] getTileSize() throws DataStoreException { + return new int[]{tileWidth, tileHeight}; + } - final BufferedImage img; - if ( (compDef != null && Arrays.equals(compDef.componentType, new int[]{4,5,6})) - || (pixelDef != null && pixelDef.bitsPerChannel.length == 3) - ) { - // RGB case - int width = imageExt.imageWidth; - int height = imageExt.imageHeight; - img = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); - final WritableRaster raster = img.getRaster(); - for (int y = 0; y <= frameConf.numTileRowsMinusOne; y++) { - for (int x = 0; x <= frameConf.numTileColsMinusOne; x++) { - readTile(x, y, raster, x*tileWidth, y*tileHeight); - } - } - } else { - throw new DataStoreException("Unsupported component model"); + @Override + protected SampleModel getSampleModel(int[] bands) throws DataStoreException { + if (bands != null) { + return null; + } + return sampleModel; + } + + @Override + protected ColorModel getColorModel(int[] bands) throws DataStoreException { + if (bands != null) { + return null; } - final GridGeometry gridGeometry = getGridGeometry(); - GridCoverageBuilder gcb = new GridCoverageBuilder(); - gcb.setDomain(gridGeometry); - gcb.setRanges(getSampleDimensions()); - gcb.setValues(img); - return gcb.build(); + return colorModel; } /** * - * @param data * @param tileX starting from image left * @param tileY starting from image top */ - private void readTile(int tileX, int tileY, WritableRaster raster, int offsetX, int offsetY) throws DataStoreException { - final int tileOffset = (tileX + tileY * (frameConf.numTileColsMinusOne+1)) * tileByteArrayLength; + private void readTile(long tileX, long tileY, WritableRaster raster, int offsetX, int offsetY) throws DataStoreException { + final long tileOffset = (tileX + tileY * (frameConf.numTileColsMinusOne+1)) * tileByteArrayLength; final byte[] data = item.getData(tileOffset, tileByteArrayLength); final DataBuffer buffer = new DataBufferByte(data, tileByteArrayLength, 0); @@ -250,4 +276,41 @@ class ResourceImageUncompressed extends AbstractGridCoverageResource implements raster.setDataElements(offsetX, offsetY, tile); } + @Override + public GridCoverage read(GridGeometry domain, int ... range) throws DataStoreException { + return new InternalTiledCoverage(new Subset(domain, range)); + } + + private class InternalTiledCoverage extends TiledGridCoverage { + + public InternalTiledCoverage(TiledGridResource.Subset subset) { + super(subset); + } + + @Override + protected GenericName getIdentifier() { + return ResourceImageUncompressed.this.identifier; + } + + @Override + protected Raster[] readTiles(final TileIterator iterator) throws IOException, DataStoreException { + final Raster[] result = new Raster[iterator.tileCountInQuery]; + synchronized (ResourceImageUncompressed.this.getSynchronizationLock()) { + do { + final Raster tile = iterator.getCachedTile(); + if (tile != null) { + result[iterator.getTileIndexInResultArray()] = tile; + } else { + long[] tileCoord = iterator.getTileCoordinatesInResource(); + final WritableRaster raster = iterator.createRaster(); + readTile(tileCoord[0], tileCoord[1], raster, Math.toIntExact(tileCoord[0]* tileWidth), Math.toIntExact(tileCoord[1]* tileHeight)); + result[iterator.getTileIndexInResultArray()] = raster; + } + } while (iterator.next()); + } + return result; + } + + } + }