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 <[email protected]>
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;
+ }
}
}