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 a9f4e4bc86 In Gimi store, avoid large array copies by reading from 
Channel directely in image DataBuffer
a9f4e4bc86 is described below

commit a9f4e4bc86ae67c19120f9ac8cfb35f414871991
Author: jsorel <johann.so...@geomatys.com>
AuthorDate: Fri Oct 4 11:08:59 2024 +0200

    In Gimi store, avoid large array copies by reading from Channel directely 
in image DataBuffer
---
 .../main/org/apache/sis/storage/gimi/Item.java         | 18 +++++++++++-------
 .../org/apache/sis/storage/gimi/ResourceImageJpeg.java |  2 +-
 .../sis/storage/gimi/ResourceImageUncompressed.java    | 17 +++++++++++------
 .../storage/gimi/isobmff/iso14496_12/MediaData.java    |  9 +++++++--
 4 files changed, 30 insertions(+), 16 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 0d96e375f5..2e01cb1789 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
@@ -170,32 +170,36 @@ final class Item {
     /**
      * @param offset start position to read from
      * @param count number of bytes to read, -1 for all
-     * @return
+     * @param target Optional array to write into
+     * @param targetOffset if target is provided, offset to start writing at
+     * @return new or provided array
      * @throws DataStoreException
      */
-    public byte[] getData(long dataOffset, int count) throws 
DataStoreException {
+    public byte[] getData(long dataOffset, int count, byte[] target, int 
targetOffset) 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(dataOffset, count);
+                return mediaData.getData(dataOffset, count, target, 
targetOffset);
             } 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[count == -1 ? length : count];
+                    if (count == -1) count = length;
+                    if (target == null) targetOffset = 0; //ignore user value 
if array is null
+                    final byte[] data = target == null ? new byte[count] : 
target;
                     final ISOBMFFReader reader = store.getReader();
                     synchronized (reader) {
-                        long remaining = data.length;
+                        long remaining = count;
                         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));
+                                reader.channel.readFully(data, bufferOffset + 
targetOffset, Math.toIntExact(toRead));
                                 bufferOffset += toRead;
                                 remaining -= toRead;
                             } else if (dataOffset >= (currentOffset + 
location.extentLength[i])) {
@@ -204,7 +208,7 @@ final class Item {
                                 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));
+                                reader.channel.readFully(data, bufferOffset + 
targetOffset, Math.toIntExact(toRead));
                                 bufferOffset += toRead;
                                 remaining -= toRead;
                             }
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 e619a11bd7..d3cbbdacff 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(0,-1);
+        final byte[] data = item.getData(0,-1, null, 0);
         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 6ec4f1bb41..13aeacf04f 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
@@ -157,7 +157,7 @@ class ResourceImageUncompressed extends TiledGridResource 
implements StoreResour
             // RGB case
             final ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
             final int[] nBits = {8, 8, 8};
-            final int[] bOffs = {2, 1, 0};
+            final int[] bOffs = {0, 1, 2};
             colorModel = new ComponentColorModel(
                     cs,
                     nBits,
@@ -268,12 +268,17 @@ class ResourceImageUncompressed extends TiledGridResource 
implements StoreResour
      */
     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);
-
-        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);
+        final DataBuffer targetBuffer = raster.getDataBuffer();
+        if (targetBuffer instanceof DataBufferByte) {
+            final DataBufferByte dbb = (DataBufferByte) targetBuffer;
+            item.getData(tileOffset, tileByteArrayLength, dbb.getData(), 0);
+        } else {
+            final byte[] data = item.getData(tileOffset, tileByteArrayLength, 
null, 0);
+            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);
+        }
     }
 
     @Override
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 52ebae5045..cf3dc4e9bc 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,7 +37,7 @@ public final class MediaData extends Box {
         }
     }
 
-    public byte[] getData(long offset, int count) throws IOException {
+    public byte[] getData(long offset, int count, byte[] target, int 
targetOffset) throws IOException {
         synchronized (reader) {
             reader.channel.seek(payloadOffset + offset);
             long nb = (boxOffset + size) - payloadOffset;
@@ -49,7 +49,12 @@ public final class MediaData extends Box {
                 }
                 nb = count;
             }
-            return reader.channel.readBytes(Math.toIntExact(nb));
+            if (target == null) {
+                return reader.channel.readBytes(Math.toIntExact(nb));
+            } else {
+                reader.channel.readFully(target, targetOffset, 
Math.toIntExact(nb));
+                return target;
+            }
         }
     }
 

Reply via email to