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