This is an automated email from the ASF dual-hosted git repository.
desruisseaux 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 750eb6c19c World File reader/writer should accepts Image I/O
reader/writer directly. Move package documentation to the data store classes.
750eb6c19c is described below
commit 750eb6c19cf6af33de2e09f16fe112d101cd7656
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Apr 21 00:48:18 2022 +0200
World File reader/writer should accepts Image I/O reader/writer directly.
Move package documentation to the data store classes.
---
.../apache/sis/internal/storage/URIDataStore.java | 14 ++++--
.../apache/sis/internal/storage/image/Store.java | 54 +++++++++++++++++++++-
.../sis/internal/storage/image/StoreProvider.java | 17 ++++++-
.../sis/internal/storage/image/WritableStore.java | 22 ++++++++-
.../sis/internal/storage/image/package-info.java | 37 +++------------
5 files changed, 106 insertions(+), 38 deletions(-)
diff --git
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
index 32b1b139cc..62bb5e09e9 100644
---
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
+++
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
@@ -16,9 +16,11 @@
*/
package org.apache.sis.internal.storage;
+import java.util.Optional;
+import java.io.DataOutput;
+import java.io.OutputStream;
import java.io.File;
import java.net.URI;
-import java.util.Optional;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
@@ -316,12 +318,18 @@ public abstract class URIDataStore extends DataStore
implements StoreResource, R
}
/**
- * Returns {@code true} if the open options contains {@link
StandardOpenOption#WRITE}.
+ * Returns {@code true} if the open options contains {@link
StandardOpenOption#WRITE}
+ * or if the storage type is some kind of output stream.
*
* @param connector the connector to use for opening a file.
* @return whether the specified connector should open a writable data
store.
+ * @throws DataStoreException if the storage object has already been
used and can not be reused.
*/
- public static boolean isWritable(final StorageConnector connector) {
+ public static boolean isWritable(final StorageConnector connector)
throws DataStoreException {
+ final Object storage = connector.getStorage();
+ if (storage instanceof OutputStream || storage instanceof
DataOutput) {
+ return true;
+ }
return
ArraysExt.contains(connector.getOption(OptionKey.OPEN_OPTIONS),
StandardOpenOption.WRITE);
}
}
diff --git
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
index 9b4846d6d8..d129a7513b 100644
---
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
+++
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
@@ -31,6 +31,7 @@ import java.nio.file.NoSuchFileException;
import java.nio.file.StandardOpenOption;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
+import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import org.opengis.metadata.Metadata;
@@ -64,8 +65,47 @@ import org.apache.sis.setup.OptionKey;
/**
- * A data store which creates grid coverages from Image I/O.
- * The store is considered as an aggregate, with one resource per image.
+ * A data store which creates grid coverages from Image I/O readers using
<cite>World File</cite> convention.
+ * Georeferencing is defined by two auxiliary files having the same name than
the image file but different suffixes:
+ *
+ * <ul class="verbose">
+ * <li>A text file containing the coefficients of the affine transform
mapping pixel coordinates to geodesic coordinates.
+ * The reader expects one coefficient per line, in the same order than the
order expected by the
+ * {@link java.awt.geom.AffineTransform#AffineTransform(double[])
AffineTransform(double[])} constructor, which is
+ * <var>scaleX</var>, <var>shearY</var>, <var>shearX</var>,
<var>scaleY</var>, <var>translateX</var>, <var>translateY</var>.
+ * The reader looks for a file having the following suffixes, in
preference order:
+ * <ol>
+ * <li>The first letter of the image file extension, followed by the
last letter of
+ * the image file extension, followed by {@code 'w'}. Example: {@code
"tfw"} for
+ * {@code "tiff"} images, and {@code "jgw"} for {@code "jpeg"}
images.</li>
+ * <li>The extension of the image file with a {@code 'w'} appended.</li>
+ * <li>The {@code "wld"} extension.</li>
+ * </ol>
+ * </li>
+ * <li>A text file containing the <cite>Coordinate Reference System</cite>
(CRS) definition
+ * in <cite>Well Known Text</cite> (WKT) syntax.
+ * The reader looks for a file having the {@code ".prj"} extension.</li>
+ * </ul>
+ *
+ * Every auxiliary text file are expected to be encoded in UTF-8
+ * and every numbers are expected to be formatted in US locale.
+ *
+ * <h2>Type of input objects</h2>
+ * The {@link StorageConnector} input should be an instance of the following
types:
+ * {@link java.nio.file.Path}, {@link java.io.File}, {@link java.net.URL} or
{@link java.net.URI}.
+ * Other types such as {@link ImageInputStream} are also accepted but in those
cases the auxiliary files can not be read.
+ * For any input of unknown type, this data store first checks if an {@link
ImageReader} accepts the input type directly.
+ * If none is found, this data store tries to {@linkplain
ImageIO#createImageInputStream(Object) create an input stream}
+ * from the input object.
+ *
+ * <p>The storage input object may also be an {@link ImageReader} instance
ready for use
+ * (i.e. with its {@linkplain ImageReader#setInput(Object) input set} to a
non-null value).
+ * In that case, this data store will use the given image reader as-is.</p>
+ *
+ * <h2>Handling of multi-image files</h2>
+ * Because some image formats can store an arbitrary amount of images,
+ * this data store is considered as an aggregate with one resource per image.
+ * All image should have the same size and all resources will share the same
{@link GridGeometry}.
*
* @author Martin Desruisseaux (Geomatys)
* @version 1.2
@@ -173,6 +213,16 @@ class Store extends PRJDataStore implements Aggregate {
{
super(provider, connector);
final Object storage = connector.getStorage();
+ if (storage instanceof ImageReader) {
+ reader = (ImageReader) storage;
+ suffix = IOUtilities.extension(reader.getInput());
+ configureReader();
+ return;
+ }
+ if (storage instanceof ImageWriter) {
+ suffix = IOUtilities.extension(((ImageWriter)
storage).getOutput());
+ return;
+ }
suffix = IOUtilities.extension(storage);
if (!(readOnly || fileExists(connector))) {
/*
diff --git
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/StoreProvider.java
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/StoreProvider.java
index d987c2ca45..563dafcd46 100644
---
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/StoreProvider.java
+++
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/StoreProvider.java
@@ -18,7 +18,10 @@ package org.apache.sis.internal.storage.image;
import java.util.Set;
import java.util.HashSet;
+import java.io.DataOutput;
import java.io.IOException;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageReaderSpi;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
@@ -67,6 +70,8 @@ public final class StoreProvider extends
PRJDataStore.Provider {
/**
* Returns a {@link Store} implementation associated with this provider.
+ * The data store will be writable if {@link
java.nio.file.StandardOpenOption#WRITE} is provided,
+ * or if the storage is a writable object such as {@link
javax.imageio.stream.ImageOutputStream}.
*
* @param connector information about the storage (URL, stream,
<i>etc</i>).
* @return a data store implementation associated with this provider for
the given storage.
@@ -74,8 +79,18 @@ public final class StoreProvider extends
PRJDataStore.Provider {
*/
@Override
public DataStore open(final StorageConnector connector) throws
DataStoreException {
+ final Object storage = connector.getStorage();
+ boolean isWritable = (storage instanceof ImageWriter);
+ if (!isWritable) {
+ if (storage instanceof ImageReader) {
+ Object input = ((ImageReader) storage).getInput();
+ isWritable = (input instanceof DataOutput); // Parent
of ImageOutputStream.
+ } else {
+ isWritable = isWritable(connector);
+ }
+ }
try {
- if (isWritable(connector)) {
+ if (isWritable) {
return new WritableStore(this, connector);
} else {
return new Store(this, connector, true);
diff --git
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/WritableStore.java
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/WritableStore.java
index 986105f849..e20c3c7263 100644
---
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/WritableStore.java
+++
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/WritableStore.java
@@ -52,7 +52,20 @@ import org.apache.sis.setup.OptionKey;
/**
- * A data store with writing capabilities.
+ * A data store which writes grid coverages using Image I/O writers completed
by the <cite>World File</cite> convention.
+ * Georeferencing is defined by two auxiliary files described in the {@link
Store} parent class.
+ *
+ * <h2>Type of output objects</h2>
+ * The {@link StorageConnector} output should be an instance of the following
types:
+ * {@link java.nio.file.Path}, {@link java.io.File}, {@link java.net.URL} or
{@link java.net.URI}.
+ * Other types such as {@link ImageOutputStream} are also accepted but in
those cases the auxiliary files can not be written.
+ * For any output of unknown type, this data store first checks if an {@link
ImageWriter} accepts the output type directly.
+ * If none is found, this data store tries to {@linkplain
ImageIO#createImageOutputStream(Object) create an output stream}
+ * from the output object.
+ *
+ * <p>The storage input object may also be an {@link ImageWriter} instance
ready for use
+ * (i.e. with its {@linkplain ImageWriter#setOutput(Object) output set} to a
non-null value).
+ * In that case, this data store will use the given image writer as-is.</p>
*
* @author Martin Desruisseaux (Geomatys)
* @version 1.2
@@ -95,11 +108,17 @@ final class WritableStore extends Store implements
WritableAggregate {
throws DataStoreException, IOException
{
super(provider, connector, false);
+ final Object storage = connector.getStorage();
final ImageReader reader = getCurrentReader();
final Object inout;
if (reader != null) {
inout = reader.getInput();
numImages = -1;
+ } else if (storage instanceof ImageWriter) {
+ writer = (ImageWriter) storage;
+ inout = writer.getOutput();
+ configureWriter();
+ numImages = -1;
} else {
/*
* If it was possible to initialize an image reader, wait to see
if an image writer is needed.
@@ -115,7 +134,6 @@ final class WritableStore extends Store implements
WritableAggregate {
writer = FormatFilter.SUFFIX.createWriter(null, connector,
null, deferred);
fallback: if (writer == null) {
ImageOutputStream stream = null;
- final Object storage = connector.getStorage();
for (final Map.Entry<ImageWriterSpi,Boolean> entry :
deferred.entrySet()) {
if (entry.getValue()) {
if (stream == null) {
diff --git
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/package-info.java
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/package-info.java
index 2912efae95..60397f5937 100644
---
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/package-info.java
+++
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/package-info.java
@@ -16,40 +16,17 @@
*/
/**
- * {@link org.apache.sis.storage.DataStore} implementation for Image I/O.
- * This data store wraps Image I/O reader and wrapper for image format such as
TIFF, PNG or JPEG.
- * The data store delegates the reading and writing of pixel values to the
wrapped reader or writer,
- * and additionally looks for two small text files in the same directory than
the image file
- * with the same filename but a different extension:
- *
- * <ul class="verbose">
- * <li>A text file containing the coefficients of the affine transform
mapping pixel
- * coordinates to geodesic coordinates. The reader expects one
coefficient per line,
- * in the same order than the one expected by the
- * {@link java.awt.geom.AffineTransform#AffineTransform(double[])
AffineTransform(double[])}
- * constructor, which is <var>scaleX</var>, <var>shearY</var>,
<var>shearX</var>,
- * <var>scaleY</var>, <var>translateX</var>, <var>translateY</var>.
- * The reader looks for a file having the following extensions, in
preference order:
- * <ol>
- * <li>The first letter of the image file extension, followed by the
last letter of
- * the image file extension, followed by {@code 'w'}. Example:
{@code "tfw"} for
- * {@code "tiff"} images, and {@code "jgw"} for {@code "jpeg"}
images.</li>
- * <li>The extension of the image file with a {@code 'w'}
appended.</li>
- * <li>The {@code "wld"} extension.</li>
- * </ol>
- * </li>
- * <li>A text file containing the <cite>Coordinate Reference System</cite>
(CRS)
- * definition in <cite>Well Known Text</cite> (WKT) syntax. The reader
looks
- * for a file having the {@code ".prj"} extension.</li>
- * </ul>
- *
- * Every text file are expected to be encoded in ISO-8859-1 (a.k.a.
ISO-LATIN-1)
- * and every numbers are expected to be formatted in US locale.
+ * Bridges between Apache SIS data stores and Java Image I/O.
+ * This package provides {@link org.apache.sis.storage.DataStore}
implementations wrapping
+ * {@link javax.imageio.ImageReader} and {@link javax.imageio.ImageWriter}
instances.
+ * The data stores delegate the reading and writing of pixel values to the
wrapped reader or writer,
+ * completed with an additional source of information for georeferencing the
image.
+ * A commonly-used convention is the <cite>World File</cite> format.
*
* @author Martin Desruisseaux (Geomatys)
* @version 1.2
*
- * @see <a href="https://en.wikipedia.org/wiki/World_file">World File Format
Description</a>
+ * @see <a href="https://en.wikipedia.org/wiki/World_file">World File format
description on Wikipedia</a>
*
* @since 1.2
* @module