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 f253a92f25 Support reading range of bytes in data boxes in GIMI store
f253a92f25 is described below

commit f253a92f25ddaeae396262c2fe0c505879f719dc
Author: jsorel <johann.so...@geomatys.com>
AuthorDate: Thu Oct 3 15:32:09 2024 +0200

    Support reading range of bytes in data boxes in GIMI store
---
 .../main/org/apache/sis/storage/gimi/Item.java     | 35 ++++++++++++++++++----
 .../apache/sis/storage/gimi/ResourceImageJpeg.java |  2 +-
 .../storage/gimi/ResourceImageUncompressed.java    | 29 ++++++++----------
 .../gimi/isobmff/iso14496_12/MediaData.java        | 16 ++++++++++
 4 files changed, 59 insertions(+), 23 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/Item.java
 
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/Item.java
index 3fd046d6cf..0d96e375f5 100644
--- 
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/Item.java
+++ 
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/Item.java
@@ -167,25 +167,48 @@ final class Item {
         return location == NO_LOCATION ? null : location;
     }
 
-    public byte[] getData() throws DataStoreException {
+    /**
+     * @param offset start position to read from
+     * @param count number of bytes to read, -1 for all
+     * @return
+     * @throws DataStoreException
+     */
+    public byte[] getData(long dataOffset, int count) throws 
DataStoreException {
         try {
             final ItemLocation.Item location = getLocation();
             if (location == null) {
                 //read data from the default mediadata box
                 MediaData mediaData = (MediaData) 
store.getRootBox().getChild(MediaData.FCC, null);
-                return mediaData.getData();
+                return mediaData.getData(dataOffset, count);
             } else if (location.constructionMethod == 0) {
                 //absolute location
                 if (location.dataReferenceIndex == 0) {
                     //compute total size
                     final int length = 
IntStream.of(location.extentLength).sum();
                     //read datas
-                    final byte[] data = new byte[length];
+                    final byte[] data = new byte[count == -1 ? length : count];
                     final ISOBMFFReader reader = store.getReader();
                     synchronized (reader) {
-                        for (int i = 0, offset = 0; i < 
location.extentLength.length; i++) {
-                            reader.channel.seek(location.baseOffset + 
location.extentOffset[i]);
-                            reader.channel.readFully(data, offset, 
location.extentLength[i]);
+                        long remaining = data.length;
+                        int bufferOffset = 0;
+                        for (int i = 0, currentOffset = 0; i < 
location.extentLength.length && remaining > 0; i++) {
+                            if (dataOffset <= currentOffset) {
+                                reader.channel.seek(location.baseOffset + 
location.extentOffset[i]);
+                                final long toRead = Math.min(remaining, 
location.extentLength[i]);
+                                reader.channel.readFully(data, bufferOffset, 
Math.toIntExact(toRead));
+                                bufferOffset += toRead;
+                                remaining -= toRead;
+                            } else if (dataOffset >= (currentOffset + 
location.extentLength[i])) {
+                                //skip the full block
+                            } else if (dataOffset > currentOffset) {
+                                long toSkip = dataOffset - currentOffset;
+                                reader.channel.seek(location.baseOffset + 
location.extentOffset[i] + toSkip);
+                                final long toRead = Math.min(remaining, 
location.extentLength[i] - toSkip);
+                                reader.channel.readFully(data, bufferOffset, 
Math.toIntExact(toRead));
+                                bufferOffset += toRead;
+                                remaining -= toRead;
+                            }
+                            currentOffset += location.extentLength[i];
                         }
                     }
                     return data;
diff --git 
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageJpeg.java
 
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageJpeg.java
index 9433723778..e619a11bd7 100644
--- 
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageJpeg.java
+++ 
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageJpeg.java
@@ -42,7 +42,7 @@ final class ResourceImageJpeg extends 
ResourceImageUncompressed {
 
     @Override
     public GridCoverage read(GridGeometry gg, int... ints) throws 
DataStoreException {
-        final byte[] data = item.getData();
+        final byte[] data = item.getData(0,-1);
         ImageInputStream iis;
         BufferedImage img;
         try {
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 cc91245c96..03b95d9168 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
@@ -16,7 +16,11 @@
  */
 package org.apache.sis.storage.gimi;
 
+import java.awt.Point;
 import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.Raster;
 import java.awt.image.WritableRaster;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -204,7 +208,6 @@ class ResourceImageUncompressed extends 
AbstractGridCoverageResource implements
 
     @Override
     public GridCoverage read(GridGeometry gg, int... ints) throws 
DataStoreException {
-        final byte[] data = item.getData();
 
         final BufferedImage img;
         if ( (compDef != null && Arrays.equals(compDef.componentType, new 
int[]{4,5,6}))
@@ -217,7 +220,7 @@ class ResourceImageUncompressed extends 
AbstractGridCoverageResource implements
             final WritableRaster raster = img.getRaster();
             for (int y = 0; y <= frameConf.numTileRowsMinusOne; y++) {
                 for (int x = 0; x <= frameConf.numTileColsMinusOne; x++) {
-                    readTile(data, x, y, raster, x*tileWidth, y*tileHeight);
+                    readTile(x, y, raster, x*tileWidth, y*tileHeight);
                 }
             }
         } else {
@@ -226,8 +229,7 @@ class ResourceImageUncompressed extends 
AbstractGridCoverageResource implements
         final GridGeometry gridGeometry = getGridGeometry();
         GridCoverageBuilder gcb = new GridCoverageBuilder();
         gcb.setDomain(gridGeometry);
-        //gcb.setRanges(getSampleDimensions());
-        //gcb.setValues(db, new 
Dimension((int)gridGeometry.getExtent().getSize(0), 
(int)gridGeometry.getExtent().getSize(1)));
+        gcb.setRanges(getSampleDimensions());
         gcb.setValues(img);
         return gcb.build();
     }
@@ -238,19 +240,14 @@ class ResourceImageUncompressed extends 
AbstractGridCoverageResource implements
      * @param tileX starting from image left
      * @param tileY starting from image top
      */
-    private void readTile(byte[] data, int tileX, int tileY, WritableRaster 
raster, int offsetX, int offsetY) {
+    private void readTile(int tileX, int tileY, WritableRaster raster, int 
offsetX, int offsetY) throws DataStoreException {
         final int tileOffset = (tileX + tileY * 
(frameConf.numTileColsMinusOne+1)) * tileByteArrayLength;
-        for (int y = 0; y < tileHeight; y++) {
-            for (int x = 0; x < tileWidth; x++) {
-                final int offset = y * tileWidth + x;
-                final int finalX = offsetX + x;
-                final int finalY = offsetY + y;
-                raster.setSample(finalX, finalY, 0, data[tileOffset + offset * 
3] & 0xFF);
-                raster.setSample(finalX, finalY, 1, data[tileOffset + offset * 
3 + 1] & 0xFF);
-                raster.setSample(finalX, finalY, 2, data[tileOffset + offset * 
3 + 2] & 0xFF);
-            }
-        }
-    }
+        final byte[] data = item.getData(tileOffset, tileByteArrayLength);
 
+        final DataBuffer buffer = new DataBufferByte(data, 
tileByteArrayLength, 0);
+
+        final Raster tile = WritableRaster.createInterleavedRaster(buffer, 
tileWidth, tileHeight, tileWidth*3, 3, new int[]{0,1,2}, new Point(0,0));
+        raster.setDataElements(offsetX, offsetY, tile);
+    }
 
 }
diff --git 
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/iso14496_12/MediaData.java
 
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/iso14496_12/MediaData.java
index 028cfcb269..52ebae5045 100644
--- 
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/iso14496_12/MediaData.java
+++ 
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/iso14496_12/MediaData.java
@@ -37,4 +37,20 @@ public final class MediaData extends Box {
         }
     }
 
+    public byte[] getData(long offset, int count) throws IOException {
+        synchronized (reader) {
+            reader.channel.seek(payloadOffset + offset);
+            long nb = (boxOffset + size) - payloadOffset;
+            if (count == -1) {
+                nb = nb - offset;
+            } else {
+                if (nb < (offset + count)) {
+                    throw new IOException("Trying to read more data then what 
is available");
+                }
+                nb = count;
+            }
+            return reader.channel.readBytes(Math.toIntExact(nb));
+        }
+    }
+
 }

Reply via email to