You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2026/06/11 18:56:50 UTC

(sis) branch geoapi-4.0 updated (10619683eb -> 4a5efac0c6)

This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a change to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


    from 10619683eb Add a `SOURCE_NAME_KEY` property to `PlanarImage` for making debugging easier.
     new 45eb43ee19 Javadoc and class renaming for clarity.
     new 4a5efac0c6 Move part of the `org.apache.sis.storage.geotiff.inflater` package to `org.apache.sis.io.stream.inflater` for sharing with GeoHEIF.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../apache/sis/storage/geotiff/Compression.java    | 27 +++++++----
 .../org/apache/sis/storage/geotiff/DataCube.java   |  8 ++--
 .../org/apache/sis/storage/geotiff/DataSubset.java |  4 +-
 .../sis/storage/geotiff/ImageFileDirectory.java    | 12 ++---
 .../apache/sis/storage/geotiff/NativeMetadata.java |  6 +--
 .../{Compression.java => CompressionMethod.java}   | 53 ++++++++++++++--------
 .../apache/sis/storage/geotiff/base/Predictor.java | 37 ++++++++-------
 .../org/apache/sis/storage/geotiff/base/Tags.java  |  2 +-
 .../sis/storage/geotiff/inflater/CCITTRLE.java     | 14 +++---
 .../storage/geotiff/inflater/CopyFromBytes.java    |  4 +-
 .../geotiff/inflater/HorizontalPredictor.java      | 18 ++++----
 .../sis/storage/geotiff/inflater/Inflater.java     | 41 +++++++++--------
 .../apache/sis/storage/geotiff/inflater/LZW.java   | 16 +++++--
 .../sis/storage/geotiff/inflater/PackBits.java     |  3 +-
 .../storage/geotiff/inflater/PredictorChannel.java | 16 +++----
 .../sis/storage/geotiff/inflater/package-info.java |  6 +--
 .../sis/storage/geotiff/writer/TileMatrix.java     | 18 ++------
 .../sis/storage/geotiff/base/CompressionTest.java  | 20 ++++++--
 .../sis/storage/geotiff/inflater/CCITTRLETest.java |  3 +-
 .../org.apache.sis.storage/main/module-info.java   |  4 ++
 .../io/stream/inflater/ComputedByteChannel.java}   | 16 ++++---
 .../apache/sis/io/stream/inflater/Deflate.java}    | 15 +++---
 .../sis/io/stream/inflater/InflaterChannel.java}   | 31 ++++++-------
 .../sis/io/stream/inflater}/package-info.java      | 17 +++----
 24 files changed, 215 insertions(+), 176 deletions(-)
 rename endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/{Compression.java => CompressionMethod.java} (72%)
 rename endorsed/src/{org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PixelChannel.java => org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/ComputedByteChannel.java} (78%)
 rename endorsed/src/{org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/ZIP.java => org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/Deflate.java} (86%)
 rename endorsed/src/{org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CompressionChannel.java => org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/InflaterChannel.java} (84%)
 copy endorsed/src/{org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature => org.apache.sis.storage/main/org/apache/sis/io/stream/inflater}/package-info.java (62%)


(sis) 01/02: Javadoc and class renaming for clarity.

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 45eb43ee196e103522025e841350bd29f43db3d3
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Thu Jun 11 17:31:16 2026 +0200

    Javadoc and class renaming for clarity.
---
 .../apache/sis/storage/geotiff/Compression.java    | 27 +++++++----
 .../org/apache/sis/storage/geotiff/DataCube.java   |  8 ++--
 .../sis/storage/geotiff/ImageFileDirectory.java    | 12 ++---
 .../apache/sis/storage/geotiff/NativeMetadata.java |  6 +--
 .../{Compression.java => CompressionMethod.java}   | 53 ++++++++++++++--------
 .../apache/sis/storage/geotiff/base/Predictor.java | 37 ++++++++-------
 .../org/apache/sis/storage/geotiff/base/Tags.java  |  2 +-
 .../sis/storage/geotiff/inflater/CCITTRLE.java     | 11 +++--
 .../geotiff/inflater/CompressionChannel.java       |  2 +-
 .../storage/geotiff/inflater/CopyFromBytes.java    |  4 +-
 .../geotiff/inflater/{ZIP.java => Deflate.java}    |  8 ++--
 .../geotiff/inflater/HorizontalPredictor.java      |  3 +-
 .../sis/storage/geotiff/inflater/Inflater.java     | 26 +++++------
 .../apache/sis/storage/geotiff/inflater/LZW.java   |  6 +--
 .../storage/geotiff/inflater/PredictorChannel.java |  8 ++--
 .../sis/storage/geotiff/inflater/package-info.java |  6 +--
 .../sis/storage/geotiff/writer/TileMatrix.java     | 18 ++------
 .../sis/storage/geotiff/base/CompressionTest.java  | 20 ++++++--
 .../sis/storage/geotiff/inflater/CCITTRLETest.java |  3 +-
 19 files changed, 142 insertions(+), 118 deletions(-)

diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Compression.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Compression.java
index 339c3d3d41..784d33ddec 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Compression.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Compression.java
@@ -19,10 +19,12 @@ package org.apache.sis.storage.geotiff;
 import java.io.Serializable;
 import java.util.OptionalInt;
 import java.util.zip.Deflater;
+import javax.imageio.plugins.tiff.BaselineTIFFTagSet;   // For javadoc.
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.internal.shared.Strings;
 import org.apache.sis.storage.OptionKey;
 import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.geotiff.base.CompressionMethod;
 import org.apache.sis.storage.geotiff.base.Predictor;
 import org.apache.sis.io.stream.InternalOptionKey;
 
@@ -47,7 +49,7 @@ import org.apache.sis.io.stream.InternalOptionKey;
  * If no compression is explicitly specified, Apache SIS uses by default the {@link #DEFLATE} compression.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.5
+ * @version 1.7
  * @since   1.5
  */
 public final class Compression implements Serializable {
@@ -59,9 +61,7 @@ public final class Compression implements Serializable {
     /**
      * No compression, but pack data into bytes as tightly as possible.
      */
-    public static final Compression NONE = new Compression(
-            org.apache.sis.storage.geotiff.base.Compression.NONE,
-            0, Predictor.NONE);
+    public static final Compression NONE = new Compression(CompressionMethod.NONE, 0, Predictor.NONE);
 
     /**
      * Deflate compression (like ZIP format) with a default compression level and a default predictor.
@@ -88,8 +88,7 @@ public final class Compression implements Serializable {
      * @see #withPredictor(int)
      */
     public static final Compression DEFLATE = new Compression(
-            org.apache.sis.storage.geotiff.base.Compression.DEFLATE,
-            Deflater.DEFAULT_COMPRESSION, Predictor.NONE);
+            CompressionMethod.DEFLATE, Deflater.DEFAULT_COMPRESSION, Predictor.NONE);
 
     /**
      * The key for declaring the compression at store creation time.
@@ -102,7 +101,7 @@ public final class Compression implements Serializable {
     /**
      * The compression method.
      */
-    final org.apache.sis.storage.geotiff.base.Compression method;
+    final CompressionMethod method;
 
     /**
      * The compression level from 0 to 9 inclusive, or -1 for default.
@@ -121,7 +120,7 @@ public final class Compression implements Serializable {
      * @param  level      the compression level, or -1 for default.
      * @param  predictor  the predictor to apply before compression.
      */
-    private Compression(final org.apache.sis.storage.geotiff.base.Compression method, final int level, final Predictor predictor) {
+    private Compression(final CompressionMethod method, final int level, final Predictor predictor) {
         this.method    = method;
         this.level     = level;
         this.predictor = predictor;
@@ -180,8 +179,16 @@ public final class Compression implements Serializable {
      * @see BaselineTIFFTagSet#PREDICTOR_HORIZONTAL_DIFFERENCING
      */
     public Compression withPredictor(int value) {
-        // `NONE` is required by `TileMatrix.writeRasters(…)` assumption that `level == 0` implies no predictor.
-        final Predictor p = usePredictor() ? Predictor.supported(value) : Predictor.NONE;
+        final Predictor p;
+        if (usePredictor()) {
+            p = Predictor.valueOf(value);
+            if (!p.isSupported()) {
+                throw new IllegalArgumentException(p.unsupported(null));
+            }
+        } else {
+            // `NONE` is required by `TileMatrix.writeRasters(…)` assumption that `level == 0` implies no predictor.
+            p = Predictor.NONE;
+        }
         return p.equals(predictor) ? this : new Compression(method, level, p);
     }
 
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java
index e5a3c4ec95..180f0f5013 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java
@@ -29,7 +29,7 @@ import org.apache.sis.storage.event.StoreListeners;
 import org.apache.sis.storage.geotiff.base.Tags;
 import org.apache.sis.storage.geotiff.base.Resources;
 import org.apache.sis.storage.geotiff.base.Predictor;
-import org.apache.sis.storage.geotiff.base.Compression;
+import org.apache.sis.storage.geotiff.base.CompressionMethod;
 import org.apache.sis.storage.tiling.TiledGridCoverage;
 import org.apache.sis.storage.tiling.TiledGridCoverageResource;
 import org.apache.sis.storage.base.StoreResource;
@@ -159,7 +159,7 @@ abstract class DataCube extends TiledGridCoverageResource implements StoreResour
     /**
      * Returns the compression method, or {@code null} if unspecified.
      */
-    abstract Compression getCompression();
+    abstract CompressionMethod getCompression();
 
     /**
      * Returns the mathematical operator that is applied to the image data before an encoding scheme is applied.
@@ -246,7 +246,7 @@ abstract class DataCube extends TiledGridCoverageResource implements StoreResour
      */
     @Override
     protected final TiledGridCoverage read(final Subset subset) throws DataStoreException {
-        final Compression compression = getCompression();
+        final CompressionMethod compression = getCompression();
         if (compression == null) {
             throw new DataStoreContentException(reader.resources().getString(
                     Resources.Keys.MissingValue_2, Tags.name((short) TAG_COMPRESSION)));
@@ -256,7 +256,7 @@ abstract class DataCube extends TiledGridCoverageResource implements StoreResour
          * documented in the javadoc of its `readSlice(…)` method. If any precondition
          * is not met, we need to fallback on the less direct `CompressedSubset` class.
          */
-        if (compression == Compression.NONE && getPredictor() == Predictor.NONE && canReadDirect(subset)) {
+        if (compression == CompressionMethod.NONE && getPredictor() == Predictor.NONE && canReadDirect(subset)) {
             return new DataSubset(this, subset);
         } else {
             return new CompressedSubset(this, subset);
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
index 2a2668ab0b..121a9fc764 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
@@ -48,7 +48,7 @@ import org.apache.sis.storage.DataStoreReferencingException;
 import org.apache.sis.storage.geotiff.base.Tags;
 import org.apache.sis.storage.geotiff.base.Resources;
 import org.apache.sis.storage.geotiff.base.Predictor;
-import org.apache.sis.storage.geotiff.base.Compression;
+import org.apache.sis.storage.geotiff.base.CompressionMethod;
 import org.apache.sis.storage.geotiff.reader.Type;
 import org.apache.sis.storage.geotiff.reader.GridGeometryBuilder;
 import org.apache.sis.storage.geotiff.reader.ImageMetadataBuilder;
@@ -374,7 +374,7 @@ final class ImageFileDirectory extends DataCube {
      *
      * @see #getCompression()
      */
-    private Compression compression;
+    private CompressionMethod compression;
 
     /**
      * Mathematical operator that is applied to the image data before an encoding scheme is applied.
@@ -657,8 +657,8 @@ final class ImageFileDirectory extends DataCube {
              */
             case TAG_COMPRESSION: {
                 final int value = type.readAsInt(input(), count);
-                compression = Compression.valueOf(value);
-                if (compression == Compression.UNKNOWN) {
+                compression = CompressionMethod.valueOf(value);
+                if (compression == CompressionMethod.UNKNOWN) {
                     return value;                           // Cause a warning to be reported by the caller.
                 }
                 break;
@@ -1316,7 +1316,7 @@ final class ImageFileDirectory extends DataCube {
          * then we set a bit for preventing the `switch` block to perform a calculation but we let the code performs
          * the other checks in order to get an exception thrown with a better message.
          */
-        int missing = !isPlanar && compression.equals(Compression.NONE) ? 0 : 0b1000;
+        int missing = !isPlanar && compression.equals(CompressionMethod.NONE) ? 0 : 0b1000;
         if (tileWidth      < 0)     missing |= 0b0001;
         if (tileHeight     < 0)     missing |= 0b0010;
         if (tileByteCounts == null) missing |= 0b0100;
@@ -1933,7 +1933,7 @@ final class ImageFileDirectory extends DataCube {
      * Returns the compression method, or {@code null} if unspecified.
      */
     @Override
-    Compression getCompression() {
+    CompressionMethod getCompression() {
         return compression;
     }
 
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/NativeMetadata.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/NativeMetadata.java
index b8a0e767e3..b7ba60a978 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/NativeMetadata.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/NativeMetadata.java
@@ -35,7 +35,7 @@ import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TableColumn;
 import org.apache.sis.util.collection.DefaultTreeTable;
 import org.apache.sis.io.stream.ChannelDataInput;
-import org.apache.sis.storage.geotiff.base.Compression;
+import org.apache.sis.storage.geotiff.base.CompressionMethod;
 import org.apache.sis.storage.geotiff.base.Predictor;
 import org.apache.sis.storage.geotiff.base.GeoKeys;
 import org.apache.sis.storage.geotiff.base.Tags;
@@ -202,8 +202,8 @@ final class NativeMetadata extends GeoKeysLoader {
                                  * we continue to handle as integers for now.
                                  */
                                 switch (tag) {
-                                    case TAG_COMPRESSION: value = toName(value, Compression::valueOf); break;
-                                    case TAG_PREDICTOR:   value = toName(value,   Predictor::valueOf); break;
+                                    case TAG_COMPRESSION: value = toName(value, CompressionMethod::valueOf); break;
+                                    case TAG_PREDICTOR:   value = toName(value, Predictor::valueOf); break;
                                     case TAG_PLANAR_CONFIGURATION: {
                                         value = toString(value, (code) -> {
                                             switch (code) {
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Compression.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/CompressionMethod.java
similarity index 72%
rename from endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Compression.java
rename to endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/CompressionMethod.java
index bfbabadc10..61d29ba9c1 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Compression.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/CompressionMethod.java
@@ -16,28 +16,29 @@
  */
 package org.apache.sis.storage.geotiff.base;
 
+import java.util.Locale;
 import static javax.imageio.plugins.tiff.BaselineTIFFTagSet.*;
 
 
 /**
- * Possible values for {@code BaselineTIFFTagSet.TAG_COMPRESSION}.
- * Data compression applies only to raster image data. All other TIFF fields are unaffected.
- *
- * <p>Except otherwise noted, field names in this class are upper-case variant of the names
- * used in Web Coverage Service (WCS) as specified in the following specification:</p>
+ * Possible values for compression methods supported by the <abbr>TIFF</abbr> reader.
+ * This enumeration identifies only the algorithm. It does not contain the parameters that
+ * are sometime associated with the algorithm, such as the predictor or compression level.
+ * Except otherwise noted, field names in this class are upper-case variant of the names used
+ * in the Web Coverage Service (<abbr>WCS</abbr>) as specified in the following specification:
  *
  * <blockquote>OGC 12-100: GML Application Schema - Coverages - GeoTIFF Coverage Encoding Profile</blockquote>
  *
- * The main exception is {@code CCITT}, which has different name in WCS query and response.
+ * The main exception is {@code CCITT}, which has different name in <abbr>WCS</abbr> query and response.
  *
- * <p>This enumeration contains a relatively large number of compressions in order to put a name
- * on the numerical codes that the reader may find. However the Apache SIS reader and writer do
- * not support all those compressions. This enumeration is not put in public API for that reason.</p>
+ * <p>This enumeration contains a relatively large number of compressions in order to put a name on the numerical codes
+ * that a reader may find. However, the Apache <abbr>SIS</abbr> reader and writer do not support all those compressions.
+ * This enumeration is not put in public <abbr>API</abbr> for that reason.</p>
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  */
-public enum Compression {
+public enum CompressionMethod {
     /**
      * No compression, but pack data into bytes as tightly as possible, leaving no unused bits except
      * potentially at the end of rows. The component values are stored as an array of type byte.
@@ -49,7 +50,7 @@ public enum Compression {
     NONE(COMPRESSION_NONE),
 
     /**
-     * CCITT Group 3, 1-Dimensional Modified Huffman run length encoding.
+     * <abbr>CCITT</abbr> Group 3, 1-Dimensional Modified Huffman run length encoding.
      * <ul>
      *   <li>Name in WCS query:    "Huffman"</li>
      *   <li>Name in WCS response: "CCITTRLE"</li>
@@ -69,7 +70,7 @@ public enum Compression {
     // ---- End of baseline GeoTIFF. Remaining are extensions cited by OGC standard ----
 
     /**
-     * LZW compression.
+     * <abbr>LZW</abbr> compression.
      * <ul>
      *   <li>Name in WCS query:    "LZW"</li>
      *   <li>Name in WCS response: "LZW"</li>
@@ -89,7 +90,7 @@ public enum Compression {
     DEFLATE(COMPRESSION_ZLIB),
 
     /**
-     * JPEG compression.
+     * <abbr>JPEG</abbr> compression.
      * <ul>
      *   <li>Name in WCS query:    "JPEG"</li>
      *   <li>Name in WCS response: "JPEG"</li>
@@ -123,24 +124,24 @@ public enum Compression {
     UNKNOWN(0);
 
     /**
-     * The TIFF code for this compression.
+     * The <abbr>TIFF</abbr> code for this compression.
      */
     public final int code;
 
     /**
      * Creates a new compression enumeration.
      */
-    private Compression(final int code) {
+    private CompressionMethod(final int code) {
         this.code = code;
     }
 
     /**
-     * Returns the compression method for the given GeoTIFF code, or {@code UNKNOWN} if none.
+     * Returns the compression method for the given <abbr>TIFF</abbr> code, or {@link #UNKNOWN} if none.
      *
-     * @param  code  the TIFF code for which to get a compression enumeration value.
-     * @return enumeration value for the given code, or {@link #UNKNOWN} if none.
+     * @param  code  the <abbr>TIFF</abbr> code for which to get a compression enumeration value.
+     * @return enumeration value for the given code, or {@code UNKNOWN} if none.
      */
-    public static Compression valueOf(final int code) {
+    public static CompressionMethod valueOf(final int code) {
         switch (code) {
             case COMPRESSION_DEFLATE:   // Fall through
             case COMPRESSION_ZLIB:      return DEFLATE;
@@ -152,7 +153,7 @@ public enum Compression {
             case COMPRESSION_NONE:      return NONE;
             default: {
                 // Fallback for uncommon formats.
-                for (final Compression c : values()) {
+                for (final var c : values()) {
                     if (c.code == code) return c;
                 }
                 break;
@@ -173,8 +174,20 @@ public enum Compression {
 
     /**
      * Returns whether the compression can be configured with different levels.
+     *
+     * @return whether the compression can be configured with different levels.
      */
     public final boolean supportLevels() {
         return this == DEFLATE;
     }
+
+    /**
+     * Returns an error message for saying that this compression is unsupported.
+     *
+     * @param  locale  the locale for the error message, or {@code null} for the default locale.
+     * @return error message for unsupported predictor.
+     */
+    public final String unsupported(final Locale locale) {
+        return Resources.forLocale(locale).getString(Resources.Keys.UnsupportedCompressionMethod_1, this);
+    }
 }
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Predictor.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Predictor.java
index c0be9ed3fd..23a645c1b5 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Predictor.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Predictor.java
@@ -16,17 +16,16 @@
  */
 package org.apache.sis.storage.geotiff.base;
 
+import java.util.Locale;
 import static javax.imageio.plugins.tiff.BaselineTIFFTagSet.*;
-import org.apache.sis.util.resources.Errors;
 
 
 /**
  * Possible values for {@code BaselineTIFFTagSet.TAG_PREDICTOR}.
- * A predictor is a mathematical operator that is applied to the image data
- * before an encoding scheme is applied.
+ * A predictor is a mathematical operator that is applied to the image data before an encoding scheme is applied.
  *
- * <p>This enumeration contains more values than what the Apache SIS reader and writer can support.
- * This enumeration is not put in public API for that reason.</p>
+ * <p>This enumeration contains more values than what the Apache <abbr>SIS</abbr> reader and writer can support.
+ * This enumeration is not put in public <abbr>API</abbr> for that reason.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
@@ -52,7 +51,7 @@ public enum Predictor {
     UNKNOWN(0);
 
     /**
-     * The TIFF code for this predictor.
+     * The <abbr>TIFF</abbr> code for this predictor.
      */
     public final int code;
 
@@ -66,7 +65,7 @@ public enum Predictor {
     /**
      * Returns the predictor for the given code.
      *
-     * @param  code  value associated to TIFF "predictor" tag.
+     * @param  code  value associated to <abbr>TIFF</abbr> "predictor" tag.
      * @return predictor for the given code.
      */
     public static Predictor valueOf(final int code) {
@@ -79,17 +78,21 @@ public enum Predictor {
     }
 
     /**
-     * Returns the predictor for the given code if supported.
+     * Returns whether this predictor is supported by the writer.
      *
-     * @param  code  value associated to TIFF "predictor" tag.
-     * @return predictor for the given code.
-     * @throws IllegalArgumentException if the given code is unsupported.
+     * @return whether this predictor is supported.
      */
-    public static Predictor supported(final int code) {
-        final Predictor value = valueOf(code);
-        if (value.ordinal() <= HORIZONTAL_DIFFERENCING.ordinal()) {
-            return value;
-        }
-        throw new IllegalArgumentException(Errors.format(Errors.Keys.UnsupportedArgumentValue_1, code));
+    public boolean isSupported() {
+        return ordinal() <= HORIZONTAL_DIFFERENCING.ordinal();
+    }
+
+    /**
+     * Returns an error message for saying that this predictor is unsupported.
+     *
+     * @param  locale  the locale for the error message, or {@code null} for the default locale.
+     * @return error message for unsupported predictor.
+     */
+    public final String unsupported(final Locale locale) {
+        return Resources.forLocale(locale).getString(Resources.Keys.UnsupportedPredictor_1, this);
     }
 }
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Tags.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Tags.java
index 426a5588eb..8eb12cd5dc 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Tags.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/base/Tags.java
@@ -71,7 +71,7 @@ public final class Tags {
     public static final short GDAL_NODATA = (short) 0xA481;               // 42113
 
     /**
-     * Supplier of TIFF tag sets, in preference order.
+     * Supplier of <abbr>TIFF</abbr> tag sets, in preference order.
      * The sets that are most likely to be used (for the kind of data handled by SIS) should be first.
      */
     @SuppressWarnings({"unchecked", "rawtypes"})
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CCITTRLE.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CCITTRLE.java
index d20498886b..7e748820cd 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CCITTRLE.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CCITTRLE.java
@@ -24,8 +24,9 @@ import org.apache.sis.io.stream.ChannelDataInput;
 
 /**
  * Inflater for values encoded with the CCITT Group 3, 1-Dimensional Modified Huffman run length encoding.
- * This compression is described in section 10 of TIFF 6 specification. "Run length" (consecutive black or
- * white pixels) are encoded with "words" having a variable number of bits. Example:
+ * This compression is described in section 10 of <abbr>TIFF</abbr> 6 specification. "Run length"
+ * (consecutive black or white pixels) are encoded with "words" having a variable number of bits.
+ * Example:
  *
  * <table class="sis">
  *   <caption>Run length encoding examples</caption>
@@ -151,7 +152,7 @@ final class CCITTRLE extends CompressionChannel {
      * @param  tree  {@link #WHITE_RUNLENGTH_TREE} or {@link #BLACK_RUNLENGTH_TREE}.
      */
     final int getRunLength(final short[] tree) throws IOException {
-        int runLength = 0, code;
+        int length = 0, code;
         do {
             int offset = 0;
             while ((code = tree[offset]) >= 0) {
@@ -177,9 +178,9 @@ final class CCITTRLE extends CompressionChannel {
                 offset = (input.readBit() != 0) ? code : offset + 1;
             }
             code = ~code;
-            runLength += code;
+            length += code;
         } while (code >= TERMINATING_LIMIT);
-        return runLength;
+        return length;
     }
 
     /**
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CompressionChannel.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CompressionChannel.java
index ba3bd4e76a..e24163771d 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CompressionChannel.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CompressionChannel.java
@@ -102,7 +102,7 @@ abstract class CompressionChannel extends PixelChannel {
      * for performance reasons. A well adjusted buffer size reduces calls to {@link ByteBuffer#compact()},
      * which in turn reduces the number of copy operations between different regions of the buffer.</p>
      *
-     * @param  channel         the channel to wrap. This is {@code this} unless a {@link Predictor} is applied.
+     * @param  channel         the channel to wrap. This is {@code this} unless a predictor is applied.
      * @param  scanlineStride  the scanline stride of the image to read. Used for choosing a buffer size.
      * @param  directBuffer    whether the use of direct buffer is preferred to heap buffer.
      * @throws IOException if an error occurred while filling the buffer with initial data.
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CopyFromBytes.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CopyFromBytes.java
index 1ff90bde51..384211bc7a 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CopyFromBytes.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CopyFromBytes.java
@@ -31,8 +31,8 @@ import org.apache.sis.util.resources.Errors;
 
 /**
  * A pseudo-inflater which copies values from a buffer of bytes to the destination image buffer.
- * When reading uncompressed TIFF images, the source buffer is the direct buffer used for I/O operations.
- * When reading compressed TIFF images, the source buffer is a temporary buffer where data segments are
+ * When reading uncompressed images, the source buffer is the direct buffer used for I/O operations.
+ * When reading compressed images, the source buffer is a temporary buffer where data segments are
  * uncompressed before to be copied to the destination image. This is useful when handling subsampling
  * on-the-fly at decompression time would be too difficult: implementers can decompress everything in
  * a temporary buffer and let this {@code CopyFromBytes} class do the subsampling.
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/ZIP.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Deflate.java
similarity index 94%
rename from endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/ZIP.java
rename to endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Deflate.java
index 7acf831b11..d8fa212a5e 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/ZIP.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Deflate.java
@@ -31,7 +31,7 @@ import org.apache.sis.io.stream.ChannelDataInput;
  * @author  Rémi Marechal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  */
-final class ZIP extends CompressionChannel {
+final class Deflate extends CompressionChannel {
     /**
      * Access to the ZLIB compression library.
      * Must be released by call to {@link Inflater#end()} after decompression is completed.
@@ -49,7 +49,7 @@ final class ZIP extends CompressionChannel {
      * @param  byteCount  number of bytes to read from the input.
      * @throws IOException if the stream cannot be seek to the given start position.
      */
-    public ZIP(final ChannelDataInput input, final StoreListeners listeners) {
+    public Deflate(final ChannelDataInput input, final StoreListeners listeners) {
         super(input, listeners);
         inflater = new Inflater();
     }
@@ -79,8 +79,7 @@ final class ZIP extends CompressionChannel {
         final int start = target.position();
         int required = 0;
         try {
-            int n;
-            while ((n = inflater.inflate(target)) == 0) {
+            while (inflater.inflate(target) == 0) {
                 if (inflater.needsInput()) {
                     if (++required >= input.buffer.capacity()) {
                         throw new BufferOverflowException();
@@ -103,6 +102,7 @@ final class ZIP extends CompressionChannel {
      * Releases resources used by the inflater.
      */
     @Override
+    @SuppressWarnings("ConvertToTryWithResources")
     public void close() {
         inflater.end();
         super.close();
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java
index 57fa2ee2eb..cf7b381313 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java
@@ -20,11 +20,10 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import org.apache.sis.image.DataType;
 import org.apache.sis.pending.jdk.JDK13;
-import org.apache.sis.storage.geotiff.base.Predictor;
 
 
 /**
- * Implementation of {@link Predictor#HORIZONTAL_DIFFERENCING}.
+ * Implementation of the horizontal differencing predictor.
  * Current implementation works only on 8, 16, 32 or 64-bits samples.
  * Values packed on 4, 2 or 1 bits are not yet supported.
  *
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Inflater.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Inflater.java
index 130000a7ed..a79573bc04 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Inflater.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Inflater.java
@@ -24,7 +24,7 @@ import org.apache.sis.image.DataType;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.storage.UnsupportedEncodingException;
-import org.apache.sis.storage.geotiff.base.Compression;
+import org.apache.sis.storage.geotiff.base.CompressionMethod;
 import org.apache.sis.storage.geotiff.base.Predictor;
 import org.apache.sis.storage.geotiff.base.Resources;
 import org.apache.sis.io.stream.ChannelDataInput;
@@ -183,24 +183,24 @@ public abstract class Inflater implements Closeable {
      *       in a way that make them usable with other tiled formats than TIFF.
      */
     @SuppressWarnings("fallthrough")
-    public static Inflater create(final StoreListeners   listeners,
-                                  final ChannelDataInput input,
-                                  final Compression      compression,
-                                  final Predictor        predictor,
-                                  final int              sourcePixelStride,
-                                  final int              sourceWidth,
-                                  final int              chunksPerRow,
-                                  final int              samplesPerChunk,
-                                  final int[]            skipAfterChunks,
-                                  final int              pixelsPerElement,
-                                  final DataType         dataType)
+    public static Inflater create(final StoreListeners    listeners,
+                                  final ChannelDataInput  input,
+                                  final CompressionMethod compression,
+                                  final Predictor         predictor,
+                                  final int               sourcePixelStride,
+                                  final int               sourceWidth,
+                                  final int               chunksPerRow,
+                                  final int               samplesPerChunk,
+                                  final int[]             skipAfterChunks,
+                                  final int               pixelsPerElement,
+                                  final DataType          dataType)
             throws IOException, UnsupportedEncodingException
     {
         ArgumentChecks.ensureNonNull("input", input);
         final CompressionChannel inflater;
         switch (compression) {
             case LZW:      inflater = new LZW     (input, listeners); break;
-            case DEFLATE:  inflater = new ZIP     (input, listeners); break;
+            case DEFLATE:  inflater = new Deflate (input, listeners); break;
             case PACKBITS: inflater = new PackBits(input, listeners); break;
             case CCITTRLE: inflater = new CCITTRLE(input, listeners, sourceWidth); break;
             case NONE: {
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/LZW.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/LZW.java
index 0db2dc0e3a..e0141af165 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/LZW.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/LZW.java
@@ -26,12 +26,12 @@ import org.apache.sis.storage.event.StoreListeners;
 
 
 /**
- * Inflater for values encoded with the LZW compression.
- * This compression is described in section 13 of TIFF 6 specification, "LZW Compression".
+ * Inflater for values encoded with the <abbr>LZW</abbr> compression.
+ * This compression is described in section 13 of <abbr>TIFF</abbr> 6 specification, "<abbr>LZW</abbr> Compression".
  * Each code is written using at least 9 bits and at most 12 bits.
  *
  * <h2>Legal note</h2>
- * Unisys's patent on the LZW algorithm expired in 2004.
+ * Unisys's patent on the <abbr>LZW</abbr> algorithm expired in 2004.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Rémi Maréchal (Geomatys)
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PredictorChannel.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PredictorChannel.java
index be9068ed7e..223382a214 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PredictorChannel.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PredictorChannel.java
@@ -19,12 +19,11 @@ package org.apache.sis.storage.geotiff.inflater;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import org.apache.sis.util.ArraysExt;
-import org.apache.sis.storage.geotiff.base.Predictor;
 import org.apache.sis.pending.jdk.JDK13;
 
 
 /**
- * Implementation of a {@link Predictor} to be executed after decompression.
+ * Implementation of a predictor to be executed after decompression.
  * A predictor is a mathematical operator that is applied to the image data
  * before an encoding scheme is applied, in order to improve compression.
  *
@@ -48,9 +47,8 @@ abstract class PredictorChannel extends PixelChannel {
     private int deferredCount;
 
     /**
-     * Creates a predictor.
-     * The {@link #setInputRegion(long, long)} method must be invoked after construction
-     * before a reading process can start.
+     * Creates a predictor. The {@link #setInputRegion(long, long)} method
+     * must be invoked after construction before a reading process can start.
      *
      * @param  input  the channel that decompress data.
      */
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/package-info.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/package-info.java
index 7b1add2fee..4d242b5934 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/package-info.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/package-info.java
@@ -20,8 +20,8 @@
  *
  * <STRONG>Do not use!</STRONG>
  *
- * This package is for internal use by SIS only. Classes in this package
- * may change in incompatible ways in any future version without notice.
+ * This package is for internal use by <abbr>SIS</abbr> only.
+ * Classes in this package may change in incompatible ways in any future version without notice.
  * This package is currently in the GeoTIFF module but we may move it to
  * another module in the future for sharing with other raster formats.
  *
@@ -32,7 +32,7 @@
  *       For example, a pixel might have three samples storing the intensity of red, green and blue colors.</dd>
  *
  *   <dt>Sample</dt>
- *   <dd>The value of a pixel in one band. For example if an image has three bands for red, green and blue colors,
+ *   <dd>The value of a pixel in one band. For example, if an image has three bands for red, green and blue colors,
  *       then the first sample value of a pixel is the intensity of the red color.</dd>
  *
  *   <dt>Element</dt>
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/TileMatrix.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/TileMatrix.java
index 18d6729d60..89e36fa683 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/TileMatrix.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/TileMatrix.java
@@ -38,9 +38,8 @@ import org.apache.sis.io.stream.ChannelDataOutput;
 import org.apache.sis.io.stream.HyperRectangleWriter;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.InternalDataStoreException;
-import org.apache.sis.storage.geotiff.base.Compression;
+import org.apache.sis.storage.geotiff.base.CompressionMethod;
 import org.apache.sis.storage.geotiff.base.Predictor;
-import org.apache.sis.storage.geotiff.base.Resources;
 import org.apache.sis.pending.jdk.JDK18;
 
 
@@ -105,7 +104,7 @@ public final class TileMatrix {
     /**
      * The compression to use for writing tiles.
      */
-    private final Compression compression;
+    private final CompressionMethod compression;
 
     /**
      * The compression level, or -1 for default.
@@ -128,7 +127,7 @@ public final class TileMatrix {
      * @param predictor         the predictor to apply before to compress data.
      */
     public TileMatrix(final RenderedImage image, final int numPlanes, final int[] bitsPerSample,
-                      final Compression compression, final int compressionLevel, final Predictor predictor)
+                      final CompressionMethod compression, final int compressionLevel, final Predictor predictor)
     {
         final int pixelSize, numArrays;
         this.numPlanes        = numPlanes;
@@ -176,13 +175,6 @@ public final class TileMatrix {
         }
     }
 
-    /**
-     * Creates an exception for an unsupported configuration.
-     */
-    private static DataStoreException unsupported(final short key, final Enum<?> value) {
-        return new DataStoreException(Resources.forLocale(null).getString(key, value));
-    }
-
     /**
      * Writes the (eventually compressed) sample values of all tiles of the image.
      * Caller shall invoke {@link #writeOffsetsAndLengths(ChannelDataOutput)} after this method.
@@ -248,10 +240,10 @@ public final class TileMatrix {
                     final long length = Math.multiplyExact(builder.length(), type.bytes());
                     switch (compression) {
                         case DEFLATE: compressor = new ZIP(output, length, compressionLevel); break;
-                        default: throw unsupported(Resources.Keys.UnsupportedCompressionMethod_1, compression);
+                        default: throw new DataStoreException(compression.unsupported(null));
                     }
                     switch (predictor) {
-                        default: throw unsupported(Resources.Keys.UnsupportedPredictor_1, predictor);
+                        default: throw new DataStoreException(predictor.unsupported(null));
                         case NONE: break;
                         case HORIZONTAL_DIFFERENCING: {
                             compressor = HorizontalPredictor.create(compressor, type, builder.pixelStride(), builder.scanlineStride());
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/base/CompressionTest.java b/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/base/CompressionTest.java
index b1fac853b6..14802b3f5a 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/base/CompressionTest.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/base/CompressionTest.java
@@ -23,7 +23,7 @@ import org.apache.sis.test.TestCase;
 
 
 /**
- * Tests the {@link Compression} enumeration.
+ * Tests the {@link CompressionMethod} and {@link Predictor} enumerations.
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
@@ -35,12 +35,22 @@ public final class CompressionTest extends TestCase {
     }
 
     /**
-     * Tests {@link Compression#valueOf(long)}.
+     * Tests {@link CompressionMethod#valueOf(int)}.
      */
     @Test
-    public void testValueOf() {
-        for (final Compression c : Compression.values()) {
-            assertSame(c, Compression.valueOf(c.code), c.name());
+    public void testMethodFromCode() {
+        for (final var c : CompressionMethod.values()) {
+            assertSame(c, CompressionMethod.valueOf(c.code), c.name());
+        }
+    }
+
+    /**
+     * Tests {@link Predictor#valueOf(int)}.
+     */
+    @Test
+    public void testPreductorFromCode() {
+        for (final var c : Predictor.values()) {
+            assertSame(c, Predictor.valueOf(c.code), c.name());
         }
     }
 }
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/inflater/CCITTRLETest.java b/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/inflater/CCITTRLETest.java
index 37faa6e8fb..1a47b5a68a 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/inflater/CCITTRLETest.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/inflater/CCITTRLETest.java
@@ -31,7 +31,8 @@ import org.apache.sis.test.TestCase;
 
 
 /**
- * Verifies the table of words for {@link CCITTRLE} implementation of TIFF Modified Huffman Compression.
+ * Verifies the table of words for {@link CCITTRLE} implementation
+ * of <abbr>TIFF</abbr> Modified Huffman Compression.
  *
  * @author  Martin Desruisseaux (Geomatys)
  */


(sis) 02/02: Move part of the `org.apache.sis.storage.geotiff.inflater` package to `org.apache.sis.io.stream.inflater` for sharing with GeoHEIF.

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 4a5efac0c6675b4d4f17e9d7c2384f38fa485676
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Jun 9 10:15:59 2026 +0200

    Move part of the `org.apache.sis.storage.geotiff.inflater` package
    to `org.apache.sis.io.stream.inflater` for sharing with GeoHEIF.
---
 .../org/apache/sis/storage/geotiff/DataSubset.java |  4 +--
 .../sis/storage/geotiff/inflater/CCITTRLE.java     |  3 +-
 .../geotiff/inflater/HorizontalPredictor.java      | 15 +++++-----
 .../sis/storage/geotiff/inflater/Inflater.java     | 15 ++++++----
 .../apache/sis/storage/geotiff/inflater/LZW.java   | 10 ++++++-
 .../sis/storage/geotiff/inflater/PackBits.java     |  3 +-
 .../storage/geotiff/inflater/PredictorChannel.java |  8 ++++--
 .../org.apache.sis.storage/main/module-info.java   |  4 +++
 .../io/stream/inflater/ComputedByteChannel.java}   | 16 ++++++-----
 .../apache/sis/io/stream}/inflater/Deflate.java    |  9 ++----
 .../sis/io/stream/inflater/InflaterChannel.java}   | 29 ++++++++++----------
 .../sis/io/stream/inflater/package-info.java       | 32 ++++++++++++++++++++++
 12 files changed, 99 insertions(+), 49 deletions(-)

diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataSubset.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataSubset.java
index 346440cfa0..f3591d0f4f 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataSubset.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataSubset.java
@@ -372,8 +372,8 @@ class DataSubset extends TiledGridCoverage {
                      * Tile not yet loaded. Add to a queue of tiles to load later.
                      * Notify the input channel about the ranges of bytes to read.
                      * This notification is redundant with the same notification
-                     * done in `CompressionChannel.setInputRegion(…)`, but doing
-                     * all notifications in advance gives a chance to group ranges.
+                     * done in `InflaterChannel.setInputRegion(…)`, but doing all
+                     * notifications in advance gives a chance to group ranges.
                      */
                     final Tile missing = new Tile(iterator, tileOffsets, includedBanks, numTiles);
                     missings[numMissings++] = missing;
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CCITTRLE.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CCITTRLE.java
index 7e748820cd..5877156e7f 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CCITTRLE.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CCITTRLE.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import org.apache.sis.storage.event.StoreListeners;
 import org.apache.sis.io.stream.ChannelDataInput;
+import org.apache.sis.io.stream.inflater.InflaterChannel;
 
 
 /**
@@ -44,7 +45,7 @@ import org.apache.sis.io.stream.ChannelDataInput;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
-final class CCITTRLE extends CompressionChannel {
+final class CCITTRLE extends InflaterChannel {
     /**
      * Modified Huffman tree for length of runs of white and black colors. This array is generated by
      * the {@code CCITTRLETest} class, which will also verifies that those values are still corrects.
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java
index cf7b381313..14bb7c2c69 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/HorizontalPredictor.java
@@ -19,6 +19,7 @@ package org.apache.sis.storage.geotiff.inflater;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import org.apache.sis.image.DataType;
+import org.apache.sis.io.stream.inflater.InflaterChannel;
 import org.apache.sis.pending.jdk.JDK13;
 
 
@@ -82,7 +83,7 @@ abstract class HorizontalPredictor extends PredictorChannel {
      * @param  width            number of pixels in the source image.
      * @param  sampleSize       number of bytes in a sample value.
      */
-    HorizontalPredictor(final CompressionChannel input, final int samplesPerPixel, final int width, final int sampleSize) {
+    HorizontalPredictor(final InflaterChannel input, final int samplesPerPixel, final int width, final int sampleSize) {
         super(input);
         sampleSizeM1   = sampleSize - Byte.BYTES;
         truncationMask = ~sampleSizeM1;
@@ -100,7 +101,7 @@ abstract class HorizontalPredictor extends PredictorChannel {
      * @param  width        number of pixels in the source image.
      * @return the predictor, or {@code null} if the given type is unsupported.
      */
-    static HorizontalPredictor create(final CompressionChannel input, final DataType dataType,
+    static HorizontalPredictor create(final InflaterChannel input, final DataType dataType,
             final int pixelStride, final int width)
     {
         switch (dataType.toPrimitive()) {
@@ -247,7 +248,7 @@ abstract class HorizontalPredictor extends PredictorChannel {
         /**
          * Creates a new predictor.
          */
-        Bytes(final CompressionChannel input, final int samplesPerPixel, final int width) {
+        Bytes(final InflaterChannel input, final int samplesPerPixel, final int width) {
             super(input, samplesPerPixel, width, Byte.BYTES);
             savedValues = new byte[samplesPerPixel];
         }
@@ -304,7 +305,7 @@ abstract class HorizontalPredictor extends PredictorChannel {
         /**
          * Creates a new predictor.
          */
-        Shorts(final CompressionChannel input, final int samplesPerPixel, final int width) {
+        Shorts(final InflaterChannel input, final int samplesPerPixel, final int width) {
             super(input, samplesPerPixel, width, Short.BYTES);
             savedValues = new short[samplesPerPixel];
         }
@@ -368,7 +369,7 @@ abstract class HorizontalPredictor extends PredictorChannel {
         /**
          * Creates a new predictor.
          */
-        Integers(final CompressionChannel input, final int samplesPerPixel, final int width) {
+        Integers(final InflaterChannel input, final int samplesPerPixel, final int width) {
             super(input, samplesPerPixel, width, Integer.BYTES);
             savedValues = new int[samplesPerPixel];
         }
@@ -432,7 +433,7 @@ abstract class HorizontalPredictor extends PredictorChannel {
         /**
          * Creates a new predictor.
          */
-        Floats(final CompressionChannel input, final int samplesPerPixel, final int width) {
+        Floats(final InflaterChannel input, final int samplesPerPixel, final int width) {
             super(input, samplesPerPixel, width, Float.BYTES);
             savedValues = new float[samplesPerPixel];
         }
@@ -496,7 +497,7 @@ abstract class HorizontalPredictor extends PredictorChannel {
         /**
          * Creates a new predictor.
          */
-        Doubles(final CompressionChannel input, final int samplesPerPixel, final int width) {
+        Doubles(final InflaterChannel input, final int samplesPerPixel, final int width) {
             super(input, samplesPerPixel, width, Double.BYTES);
             savedValues = new double[samplesPerPixel];
         }
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Inflater.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Inflater.java
index a79573bc04..659b447b13 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Inflater.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Inflater.java
@@ -28,6 +28,9 @@ import org.apache.sis.storage.geotiff.base.CompressionMethod;
 import org.apache.sis.storage.geotiff.base.Predictor;
 import org.apache.sis.storage.geotiff.base.Resources;
 import org.apache.sis.io.stream.ChannelDataInput;
+import org.apache.sis.io.stream.inflater.ComputedByteChannel;
+import org.apache.sis.io.stream.inflater.InflaterChannel;
+import org.apache.sis.io.stream.inflater.Deflate;
 import org.apache.sis.storage.event.StoreListeners;
 import static org.apache.sis.pending.jdk.JDK18.ceilDiv;
 
@@ -39,7 +42,7 @@ import static org.apache.sis.pending.jdk.JDK18.ceilDiv;
  *
  * <p>If a decompression algorithm can handle all above-cited aspects directly,
  * it can extend this class directly. If it would be too complicated, an easier
- * approach is to extend {@link CompressionChannel} instead and wrap that inflater
+ * approach is to extend {@link InflaterChannel} instead and wrap that inflater
  * in a {@link CopyFromBytes} subclass for managing the sub-region, subsampling
  * and band subset.</p>
  *
@@ -197,7 +200,7 @@ public abstract class Inflater implements Closeable {
             throws IOException, UnsupportedEncodingException
     {
         ArgumentChecks.ensureNonNull("input", input);
-        final CompressionChannel inflater;
+        final InflaterChannel inflater;
         switch (compression) {
             case LZW:      inflater = new LZW     (input, listeners); break;
             case DEFLATE:  inflater = new Deflate (input, listeners); break;
@@ -213,7 +216,7 @@ public abstract class Inflater implements Closeable {
                 throw unsupportedEncoding(listeners, Resources.Keys.UnsupportedCompressionMethod_1, compression);
             }
         }
-        final PixelChannel channel;
+        final ComputedByteChannel channel;
         switch (predictor) {
             case NONE: {
                 channel = inflater;
@@ -261,8 +264,8 @@ public abstract class Inflater implements Closeable {
          * will perform a seek operation. As a consequence the buffer content become invalid and
          * must be emptied.
          */
-        if (input.channel instanceof PixelChannel) {
-            ((PixelChannel) input.channel).setInputRegion(start, byteCount);
+        if (input.channel instanceof ComputedByteChannel) {
+            ((ComputedByteChannel) input.channel).setInputRegion(start, byteCount);
             input.refresh(start);
         }
     }
@@ -311,7 +314,7 @@ public abstract class Inflater implements Closeable {
      */
     @Override
     public final void close() throws IOException {
-        if (input.channel instanceof PixelChannel) {
+        if (input.channel instanceof ComputedByteChannel) {
             input.channel.close();
         }
     }
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/LZW.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/LZW.java
index e0141af165..532fd83821 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/LZW.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/LZW.java
@@ -22,6 +22,7 @@ import java.io.EOFException;
 import java.nio.ByteBuffer;
 import org.apache.sis.storage.geotiff.base.Resources;
 import org.apache.sis.io.stream.ChannelDataInput;
+import org.apache.sis.io.stream.inflater.InflaterChannel;
 import org.apache.sis.storage.event.StoreListeners;
 
 
@@ -36,7 +37,7 @@ import org.apache.sis.storage.event.StoreListeners;
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Rémi Maréchal (Geomatys)
  */
-final class LZW extends CompressionChannel {
+final class LZW extends InflaterChannel {
     /**
      * A 12 bits code meaning that we have exhausted the 4093 available codes
      * and must reset the table to the initial set of 9 bits code.
@@ -471,6 +472,13 @@ final class LZW extends CompressionChannel {
         return target.position() - start;
     }
 
+    /**
+     * Returns the resources for error messages.
+     */
+    private Resources resources() {
+        return Resources.forLocale(listeners.getLocale());
+    }
+
     /**
      * The exception to throw if the decompression process encounters data that it cannot process.
      */
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PackBits.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PackBits.java
index cb3ce2ab5a..d29b7b6b4f 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PackBits.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PackBits.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import org.apache.sis.storage.event.StoreListeners;
 import org.apache.sis.io.stream.ChannelDataInput;
+import org.apache.sis.io.stream.inflater.InflaterChannel;
 
 
 /**
@@ -28,7 +29,7 @@ import org.apache.sis.io.stream.ChannelDataInput;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
-final class PackBits extends CompressionChannel {
+final class PackBits extends InflaterChannel {
     /**
      * Number of bytes to copy literally from the input.
      * Only one of {@code literalCount} and {@link #duplicatedCount} can be non-zero.
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PredictorChannel.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PredictorChannel.java
index 223382a214..e80589f39e 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PredictorChannel.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PredictorChannel.java
@@ -20,6 +20,8 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.pending.jdk.JDK13;
+import org.apache.sis.io.stream.inflater.ComputedByteChannel;
+import org.apache.sis.io.stream.inflater.InflaterChannel;
 
 
 /**
@@ -29,11 +31,11 @@ import org.apache.sis.pending.jdk.JDK13;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
-abstract class PredictorChannel extends PixelChannel {
+abstract class PredictorChannel extends ComputedByteChannel {
     /**
      * The channel from which to read data.
      */
-    private final CompressionChannel input;
+    private final InflaterChannel input;
 
     /**
      * If {@link #read(ByteBuffer)} could not process some trailing bytes,
@@ -52,7 +54,7 @@ abstract class PredictorChannel extends PixelChannel {
      *
      * @param  input  the channel that decompress data.
      */
-    protected PredictorChannel(final CompressionChannel input) {
+    protected PredictorChannel(final InflaterChannel input) {
         this.input = input;
         deferred = ArraysExt.EMPTY_BYTE;
     }
diff --git a/endorsed/src/org.apache.sis.storage/main/module-info.java b/endorsed/src/org.apache.sis.storage/main/module-info.java
index 4a43ba85e5..0155e9b867 100644
--- a/endorsed/src/org.apache.sis.storage/main/module-info.java
+++ b/endorsed/src/org.apache.sis.storage/main/module-info.java
@@ -92,6 +92,10 @@ module org.apache.sis.storage {
             org.apache.sis.console,
             org.apache.sis.gui;                         // In the "optional" sub-project.
 
+    exports org.apache.sis.io.stream.inflater to
+            org.apache.sis.storage.geotiff,
+            org.apache.sis.storage.geoheif;             // In the "incubator" sub-project.
+
     exports org.apache.sis.storage.xml to
             org.apache.sis.storage.xml,
             org.apache.sis.gui;                         // In the "optional" sub-project.
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PixelChannel.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/ComputedByteChannel.java
similarity index 78%
rename from endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PixelChannel.java
rename to endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/ComputedByteChannel.java
index 971a653279..cddd8c803b 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/PixelChannel.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/ComputedByteChannel.java
@@ -14,18 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.storage.geotiff.inflater;
+package org.apache.sis.io.stream.inflater;
 
 import java.io.IOException;
 import java.nio.channels.ReadableByteChannel;
 
 
 /**
- * A channel of pixel values after all steps have been completed.
- * The steps may be:
+ * Base class of channels providing values that are computed on-the-fly.
+ * The computation typically uses another channel as its source.
+ * Examples:
  *
  * <ul>
- *   <li>Decompression alone, in which case this class is a subtype of {@link CompressionChannel}.</li>
+ *   <li>Decompression alone, in which case this class is a subtype of {@link InflaterChannel}.</li>
  *   <li>Decompression followed by some mathematical operation applied on the data after decompression.
  *       In that case this class is a subtype of {@link PredictorChannel}.</li>
  * </ul>
@@ -34,15 +35,16 @@ import java.nio.channels.ReadableByteChannel;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
-abstract class PixelChannel implements ReadableByteChannel {
+public abstract class ComputedByteChannel implements ReadableByteChannel {
     /**
      * Creates a new channel.
      */
-    protected PixelChannel() {
+    protected ComputedByteChannel() {
     }
 
     /**
-     * Prepares this channel for reading a new tile or a new band of a planar image.
+     * Prepares this channel for reading a new block of data.
+     * A block may be, for example, a tile or a band of a tile.
      *
      * @param  start      stream position where to start reading.
      * @param  byteCount  number of bytes to read from the input.
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Deflate.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/Deflate.java
similarity index 90%
rename from endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Deflate.java
rename to endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/Deflate.java
index d8fa212a5e..49d7bd0eef 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/Deflate.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/Deflate.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.storage.geotiff.inflater;
+package org.apache.sis.io.stream.inflater;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -31,7 +31,7 @@ import org.apache.sis.io.stream.ChannelDataInput;
  * @author  Rémi Marechal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  */
-final class Deflate extends CompressionChannel {
+public final class Deflate extends InflaterChannel {
     /**
      * Access to the ZLIB compression library.
      * Must be released by call to {@link Inflater#end()} after decompression is completed.
@@ -45,9 +45,6 @@ final class Deflate extends CompressionChannel {
      *
      * @param  input      the source of data to decompress.
      * @param  listeners  object where to report warnings.
-     * @param  start      stream position where to start reading.
-     * @param  byteCount  number of bytes to read from the input.
-     * @throws IOException if the stream cannot be seek to the given start position.
      */
     public Deflate(final ChannelDataInput input, final StoreListeners listeners) {
         super(input, listeners);
@@ -55,7 +52,7 @@ final class Deflate extends CompressionChannel {
     }
 
     /**
-     * Prepares this inflater for reading a new tile or a new band of a tile.
+     * Prepares this channel for reading a new block of data.
      *
      * @param  start      stream position where to start reading.
      * @param  byteCount  number of bytes to read from the input.
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CompressionChannel.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/InflaterChannel.java
similarity index 85%
rename from endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CompressionChannel.java
rename to endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/InflaterChannel.java
index e24163771d..16d81de18f 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/inflater/CompressionChannel.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/InflaterChannel.java
@@ -14,14 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.storage.geotiff.inflater;
+package org.apache.sis.io.stream.inflater;
 
 import java.util.Arrays;
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.nio.BufferOverflowException;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.storage.StorageConnector;
-import org.apache.sis.storage.geotiff.base.Resources;
 import org.apache.sis.io.stream.ChannelDataInput;
 import org.apache.sis.storage.event.StoreListeners;
 import org.apache.sis.pending.jdk.JDK18;
@@ -35,7 +35,7 @@ import org.apache.sis.pending.jdk.JDK18;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
-abstract class CompressionChannel extends PixelChannel {
+public abstract class InflaterChannel extends ComputedByteChannel {
     /**
      * Desired size of the buffer where to temporarily copy decompressed data.
      * The actual buffer size may become larger (but not smaller)
@@ -66,13 +66,13 @@ abstract class CompressionChannel extends PixelChannel {
      * @param  input      the source of data to decompress.
      * @param  listeners  object where to report warnings.
      */
-    protected CompressionChannel(final ChannelDataInput input, final StoreListeners listeners) {
+    protected InflaterChannel(final ChannelDataInput input, final StoreListeners listeners) {
         this.input     = input;
         this.listeners = listeners;
     }
 
     /**
-     * Prepares this inflater for reading a new tile or a new band of a tile.
+     * Prepares this channel for reading a new block of data.
      *
      * @param  start      stream position where to start reading.
      * @param  byteCount  number of bytes to read from the input.
@@ -108,7 +108,7 @@ abstract class CompressionChannel extends PixelChannel {
      * @throws IOException if an error occurred while filling the buffer with initial data.
      * @return the data input for uncompressed data.
      */
-    final ChannelDataInput createDataInput(final PixelChannel channel, final int scanlineStride, final boolean directBuffer)
+    public final ChannelDataInput createDataInput(final ComputedByteChannel channel, final int scanlineStride, final boolean directBuffer)
             throws IOException
     {
         final int capacity;
@@ -127,9 +127,15 @@ abstract class CompressionChannel extends PixelChannel {
 
     /**
      * Copies the given byte <var>n</var> times in the given buffer.
+     * This is a convenience method for an operation frequently found in different compression algorithms.
+     *
+     * @param  target  where to append the bytes.
+     * @param  value   the byte to repeat.
+     * @param  count   number of time to repeat the given value.
+     * @throws BufferOverflowException if {@code count} is greater than the remaining space in the buffer.
      */
-    static void repeat(final ByteBuffer target, final byte b, int n) {
-        while (--n >= 0) target.put(b);
+    protected static void repeat(final ByteBuffer target, final byte value, int count) {
+        while (--count >= 0) target.put(value);
     }
 
     /**
@@ -149,11 +155,4 @@ abstract class CompressionChannel extends PixelChannel {
     public void close() {
         // Do NOT close `input`.
     }
-
-    /**
-     * Returns the resources for error messages.
-     */
-    final Resources resources() {
-        return Resources.forLocale(listeners.getLocale());
-    }
 }
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/package-info.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/package-info.java
new file mode 100644
index 0000000000..e1d7c0a718
--- /dev/null
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/inflater/package-info.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Utility classes for the implementation of data stores that need to decompress block of data.
+ *
+ * <STRONG>Do not use!</STRONG>
+ *
+ * This package is for internal use by <abbr>SIS</abbr> only.
+ * Classes in this package may change in incompatible ways in any future version without notice.
+ *
+ * <p>More implementations of the base classes in this package are provided in other modules such as GeoTIFF.
+ * Some of these implementations may move to this package in the future if there is a need to share compression
+ * algorithms.</p>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ */
+package org.apache.sis.io.stream.inflater;