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 420b428372 Documentation about assertions. 420b428372 is described below commit 420b428372fc9260566cba5a2da6ea728242023a Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Wed Feb 8 19:18:23 2023 +0100 Documentation about assertions. --- .../java/org/apache/sis/image/MaskedImage.java | 2 +- .../org/apache/sis/image/PixelIteratorTest.java | 4 +- .../org/apache/sis/geometry/AbstractEnvelope.java | 16 +++++--- .../org/apache/sis/geometry/GeneralEnvelope.java | 10 +++-- .../sis/referencing/AbstractIdentifiedObject.java | 1 + .../java/org/apache/sis/referencing/Builder.java | 2 + .../operation/transform/AbstractMathTransform.java | 1 + .../internal/util/ArgumentCheckByAssertion.java | 39 ++++++++++++++++++++ .../main/java/org/apache/sis/measure/Range.java | 43 ++++++++++++---------- .../org/apache/sis/storage/geotiff/DataCube.java | 2 +- .../org/apache/sis/storage/geotiff/DataSubset.java | 2 +- 11 files changed, 89 insertions(+), 33 deletions(-) diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java b/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java index 3e719ec1e6..addef959d3 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java +++ b/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java @@ -177,7 +177,7 @@ final class MaskedImage extends SourceAlignedImage { * int pixel = (element >>> shift) & 1; * } * - * <h4>Pre-conditions</h4> + * <h4>Preconditions</h4> * The {@link #getMaskTiles()} method must have been invoked at least once before this method. */ private synchronized ByteBuffer getMask() { diff --git a/core/sis-feature/src/test/java/org/apache/sis/image/PixelIteratorTest.java b/core/sis-feature/src/test/java/org/apache/sis/image/PixelIteratorTest.java index bc8e753886..5628502e9a 100644 --- a/core/sis-feature/src/test/java/org/apache/sis/image/PixelIteratorTest.java +++ b/core/sis-feature/src/test/java/org/apache/sis/image/PixelIteratorTest.java @@ -152,7 +152,7 @@ public class PixelIteratorTest extends TestCase { * Creates a {@code WritableRaster} to use as the source of test data. * The raster is filled with arbitrary sample values. * - * <h4>Pre-conditions</h4> + * <h4>Preconditions</h4> * Before invocation, the {@link #xmin}, {@link #ymin}, {@link #width}, {@link #height} and {@link #numBands} * fields must be initialized. * @@ -211,7 +211,7 @@ public class PixelIteratorTest extends TestCase { * Creates a {@code RenderedImage} to use as the source of test data. * The image is filled with arbitrary sample values. * - * <h4>Pre-conditions</h4> + * <h4>Preconditions</h4> * Before invocation, the {@link #xmin}, {@link #ymin}, {@link #width}, {@link #height}, * {@link #tileWidth}, {@link #tileHeight} and {@link #numBands} fields must be initialized. * diff --git a/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java b/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java index afd4ee9d8c..d1b0902fad 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java @@ -44,6 +44,7 @@ import org.apache.sis.io.wkt.Formatter; import org.apache.sis.io.wkt.FormattableObject; import org.apache.sis.internal.referencing.WKTUtilities; import org.apache.sis.internal.referencing.TemporalAccessor; +import org.apache.sis.internal.util.ArgumentCheckByAssertion; import org.apache.sis.referencing.IdentifiedObjects; import org.apache.sis.measure.Range; import org.apache.sis.math.Vector; @@ -745,7 +746,7 @@ public abstract class AbstractEnvelope extends FormattableObject implements Enve * If it least one coordinate value in the given point is {@link Double#NaN NaN}, * then this method returns {@code false}. * - * <h4>Pre-conditions</h4> + * <h4>Preconditions</h4> * This method assumes that the specified point uses a CRS equivalent to this envelope CRS. * For performance reasons, it will no be verified unless Java assertions are enabled. * @@ -760,6 +761,7 @@ public abstract class AbstractEnvelope extends FormattableObject implements Enve * @throws MismatchedDimensionException if the specified point does not have the expected number of dimensions. * @throws AssertionError if assertions are enabled and the envelopes have mismatched CRS. */ + @ArgumentCheckByAssertion public boolean contains(final DirectPosition position) throws MismatchedDimensionException { ensureNonNull("position", position); final int dimension = getDimension(); @@ -796,7 +798,7 @@ public abstract class AbstractEnvelope extends FormattableObject implements Enve * * <blockquote><pre>{@linkplain #contains(Envelope, boolean) contains}(envelope, <b>true</b>)</pre></blockquote> * - * <h4>Pre-conditions</h4> + * <h4>Preconditions</h4> * This method assumes that the specified envelope uses the same CRS than this envelope. * For performance reasons, it will no be verified unless Java assertions are enabled. * @@ -816,6 +818,7 @@ public abstract class AbstractEnvelope extends FormattableObject implements Enve * * @since 0.4 */ + @ArgumentCheckByAssertion public boolean contains(final Envelope envelope) throws MismatchedDimensionException { return contains(envelope, true); } @@ -826,7 +829,7 @@ public abstract class AbstractEnvelope extends FormattableObject implements Enve * envelope, then this method returns {@code true} only if {@code edgesInclusive} * is {@code true}. * - * <p>This method is subject to the same pre-conditions than {@link #contains(Envelope)}, + * <p>This method is subject to the same preconditions than {@link #contains(Envelope)}, * and handles envelopes crossing the anti-meridian in the same way.</p> * * @param envelope the envelope to test for inclusion. @@ -837,6 +840,7 @@ public abstract class AbstractEnvelope extends FormattableObject implements Enve * * @see #intersects(Envelope, boolean) */ + @ArgumentCheckByAssertion public boolean contains(final Envelope envelope, final boolean edgesInclusive) throws MismatchedDimensionException { ensureNonNull("envelope", envelope); final int dimension = getDimension(); @@ -924,7 +928,7 @@ public abstract class AbstractEnvelope extends FormattableObject implements Enve * * <blockquote><pre>{@linkplain #intersects(Envelope, boolean) intersects}(envelope, <b>false</b>)</pre></blockquote> * - * <h4>Pre-conditions</h4> + * <h4>Preconditions</h4> * This method assumes that the specified envelope uses the same CRS than this envelope. * For performance reasons, it will no be verified unless Java assertions are enabled. * @@ -941,6 +945,7 @@ public abstract class AbstractEnvelope extends FormattableObject implements Enve * * @since 0.4 */ + @ArgumentCheckByAssertion public boolean intersects(final Envelope envelope) throws MismatchedDimensionException { return intersects(envelope, false); } @@ -958,7 +963,7 @@ public abstract class AbstractEnvelope extends FormattableObject implements Enve * <em>or</em> touch each other.</li> * </ul> * - * This method is subject to the same pre-conditions than {@link #intersects(Envelope)}, + * This method is subject to the same preconditions than {@link #intersects(Envelope)}, * and handles envelopes crossing the anti-meridian in the same way. * * @param envelope the envelope to test for intersection. @@ -971,6 +976,7 @@ public abstract class AbstractEnvelope extends FormattableObject implements Enve * @see #contains(Envelope, boolean) * @see #equals(Envelope, double, boolean) */ + @ArgumentCheckByAssertion public boolean intersects(final Envelope envelope, final boolean touch) throws MismatchedDimensionException { ensureNonNull("envelope", envelope); final int dimension = getDimension(); diff --git a/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java b/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java index 5a56f97871..ec72334dee 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java @@ -38,6 +38,7 @@ import org.opengis.metadata.extent.GeographicBoundingBox; import org.apache.sis.internal.referencing.TemporalAccessor; import org.apache.sis.internal.referencing.AxisDirections; import org.apache.sis.internal.referencing.Resources; +import org.apache.sis.internal.util.ArgumentCheckByAssertion; import org.apache.sis.util.resources.Errors; import org.apache.sis.referencing.CRS; import org.apache.sis.referencing.IdentifiedObjects; @@ -549,7 +550,7 @@ public class GeneralEnvelope extends ArrayEnvelope implements Cloneable, Seriali * with the added point as an argument will return {@code true}, except if one of the point * coordinates was {@link Double#NaN} in which case the corresponding coordinate has been ignored.</p> * - * <h4>Pre-conditions</h4> + * <h4>Preconditions</h4> * This method assumes that the specified point uses a CRS equivalent to this envelope CRS. * For performance reasons, it will no be verified unless Java assertions are enabled. * @@ -568,6 +569,7 @@ public class GeneralEnvelope extends ArrayEnvelope implements Cloneable, Seriali * @throws MismatchedDimensionException if the given point does not have the expected number of dimensions. * @throws AssertionError if assertions are enabled and the envelopes have mismatched CRS. */ + @ArgumentCheckByAssertion public void add(final DirectPosition position) throws MismatchedDimensionException { ensureNonNull("position", position); final int beginIndex = beginIndex(); @@ -626,7 +628,7 @@ public class GeneralEnvelope extends ArrayEnvelope implements Cloneable, Seriali * Adds an envelope object to this envelope. * The resulting envelope is the union of the two {@code Envelope} objects. * - * <h4>Pre-conditions</h4> + * <h4>Preconditions</h4> * This method assumes that the specified envelope uses a CRS equivalent to this envelope CRS. * For performance reasons, it will no be verified unless Java assertions are enabled. * @@ -670,6 +672,7 @@ public class GeneralEnvelope extends ArrayEnvelope implements Cloneable, Seriali * @see Envelopes#union(Envelope...) * @see org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox#add(GeographicBoundingBox) */ + @ArgumentCheckByAssertion public void add(final Envelope envelope) throws MismatchedDimensionException { ensureNonNull("envelope", envelope); final int beginIndex = beginIndex(); @@ -782,7 +785,7 @@ public class GeneralEnvelope extends ArrayEnvelope implements Cloneable, Seriali /** * Sets this envelope to the intersection of this envelope with the specified one. * - * <h4>Pre-conditions</h4> + * <h4>Preconditions</h4> * This method assumes that the specified envelope uses a CRS equivalent to this envelope CRS. * For performance reasons, it will no be verified unless Java assertions are enabled. * @@ -826,6 +829,7 @@ public class GeneralEnvelope extends ArrayEnvelope implements Cloneable, Seriali * @see Envelopes#intersect(Envelope...) * @see org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox#intersect(GeographicBoundingBox) */ + @ArgumentCheckByAssertion public void intersect(final Envelope envelope) throws MismatchedDimensionException { ensureNonNull("envelope", envelope); final int beginIndex = beginIndex(); diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java index 1f9d776561..7d93057d3c 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java @@ -793,6 +793,7 @@ public class AbstractIdentifiedObject extends FormattableObject implements Ident * Subclasses shall override {@link #computeHashCode()} instead of this method. * * @return the hash code value. This value may change in any future Apache SIS version. + * @throws AssertionError if assertions are enabled and the value computed by {@link #computeHashCode()} changed. */ @Override public final int hashCode() { // No need to synchronize; ok if invoked twice. diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java index 4873b76a95..9b7ff7ef60 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java @@ -216,6 +216,8 @@ public abstract class Builder<B extends Builder<B>> { /** * Creates a new builder. + * + * @throws AssertionError if assertions are enabled and the {@code <B>} type is not the type of {@code this}. */ protected Builder() { assert verifyParameterizedType(getClass()); diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java index eec70e40c4..28b3f9776c 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java @@ -953,6 +953,7 @@ public abstract class AbstractMathTransform extends FormattableObject * * @param object the object to compare with this transform. * @return {@code true} if the given object is a transform of the same class and using the same parameter values. + * @throws AssertionError if assertions are enabled and the objects are equal but their hash codes are different. */ @Override public final boolean equals(final Object object) { diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/util/ArgumentCheckByAssertion.java b/core/sis-utility/src/main/java/org/apache/sis/internal/util/ArgumentCheckByAssertion.java new file mode 100644 index 0000000000..fc7dc2f4ba --- /dev/null +++ b/core/sis-utility/src/main/java/org/apache/sis/internal/util/ArgumentCheckByAssertion.java @@ -0,0 +1,39 @@ +/* + * 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. + */ +package org.apache.sis.internal.util; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * Marker annotation for public methods which use assertions for validating users arguments. + * This is not recommended for public API, but we do that in a few places where unconditional + * argument checks may be too expensive. This annotation is used for tracking those methods. + * + * @author Martin Desruisseaux (Geomatys) + * @version 1.4 + * @since 1.4 + */ +@Target({ + ElementType.METHOD, + ElementType.CONSTRUCTOR}) +@Retention(RetentionPolicy.SOURCE) +public @interface ArgumentCheckByAssertion { +} diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java b/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java index a22c730c59..6e63f3f36b 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java @@ -23,6 +23,7 @@ import java.util.FormattableFlags; import java.io.Serializable; import javax.measure.Unit; import org.apache.sis.internal.util.Strings; +import org.apache.sis.internal.util.ArgumentCheckByAssertion; import org.apache.sis.util.collection.CheckedContainer; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.Emptiable; @@ -132,24 +133,26 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer< * Creates a new range bounded by the given endpoint values. * If the given minimum value is greater than the maximum value, then the range {@linkplain #isEmpty() is empty}. * - * <div class="note"><b>Assertion:</b> + * <h4>Assertion</h4> * This constructor verifies the {@code minValue} and {@code maxValue} arguments type if Java assertions * are enabled. This verification is not performed in normal execution because theoretically unnecessary - * unless Java generic types have been tricked.</div> + * unless Java generic types have been tricked. * * @param elementType the base type of the range elements. * @param minValue the minimal value, or {@code null} if none. * @param isMinIncluded {@code true} if the minimal value is inclusive, or {@code false} if exclusive. * @param maxValue the maximal value, or {@code null} if none. * @param isMaxIncluded {@code true} if the maximal value is inclusive, or {@code false} if exclusive. + * @throws AssertionError if assertions are enabled and the given values are not compatible with the given type. */ + @ArgumentCheckByAssertion public Range(final Class<E> elementType, final E minValue, final boolean isMinIncluded, final E maxValue, final boolean isMaxIncluded) { ArgumentChecks.ensureNonNull("elementType", elementType); /* - * The 'isMin/Maxincluded' flags must be forced to 'false' if 'minValue' or 'maxValue' + * The `isMin/Maxincluded` flags must be forced to `false` if `minValue` or `maxValue` * are null. This is required for proper working of algorithms implemented in this class. */ this.elementType = elementType; @@ -164,11 +167,11 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer< * Creates a new range using the same element type than this range. This method will * be overridden by subclasses in order to create a range of a more specific type. * - * <div class="note"><b>API note:</b> + * <h4>API note</h4> * This method is invoked by all operations (union, intersection, <i>etc.</i>) that may create a new range. * But despite this fact, the return type of those methods are nailed down to {@code Range} (i.e. subclasses * shall not override the above-cited operations with covariant return type) because those operations may return - * the given argument directly, and we have no guarantees on the type of those arguments.</div> + * the given argument directly, and we have no guarantees on the type of those arguments. */ Range<E> create(final E minValue, final boolean isMinIncluded, final E maxValue, final boolean isMaxIncluded) @@ -268,9 +271,9 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer< * {@linkplain #getMaxValue() maximum value}, or if they are equal while * at least one of them is exclusive. * - * <div class="note"><b>API note:</b> + * <h4>API note</h4> * This method is final because often used by the internal implementation. - * Making the method final ensures that the other methods behave consistently.</div> + * Making the method final ensures that the other methods behave consistently. * * @return {@code true} if this range is empty. */ @@ -326,8 +329,8 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer< * We consistently use min/maxValue.compareTo(value) in this class rather than * the opposite argument order (namely value.compareTo(min/maxValue)) in the * hope to reduce the risk of inconsistent behavior if usera pass different - * sub-classes for the 'value' argument with different implementations of the - * 'compareTo' method. Intead than using those user implementations, we always + * sub-classes for the `value` argument with different implementations of the + * `compareTo` method. Intead than using those user implementations, we always * use the implementations provided by min/maxValue. */ if (minValue != null) { @@ -372,8 +375,8 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer< * * However, we still have a little bit of additional checks to perform for the * inclusion status of both ranges. Since the same checks will be needed for - * intersection methods, we factor out the comparisons in 'compareMinTo' and - * 'compareMaxTo' methods. + * intersection methods, we factor out the comparisons in `compareMinTo` and + * `compareMaxTo` methods. */ return (compareMinTo(range.minValue, range.isMinIncluded ? 0 : -1) <= 0) && (compareMaxTo(range.maxValue, range.isMaxIncluded ? 0 : +1) >= 0); @@ -411,7 +414,7 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer< * so instead of extracting the minimal and maximal values directly, we will * find which range contains the highest minimal value, and which range contains * the smallest maximal value. If we find the same range in both case (which can - * be either 'this' or 'range), return that range. Otherwise we need to create a + * be either `this` or `range`), return that range. Otherwise we need to create a * new one. */ final Range<E> intersect, min, max; @@ -469,8 +472,8 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer< */ public Range<E>[] subtract(final Range<E> range) { /* - * Implementation note: never store the 'range' argument value in the array - * returned by 'newArray(int)', otherwise we may get an ArrayStoreException. + * Implementation note: never store the `range` argument value in the array + * returned by `newArray(int)`, otherwise we may get an ArrayStoreException. */ final Range<E> subtract; if (!intersects(range)) { @@ -524,7 +527,7 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer< private int compareMinTo(final E value, int position) { /* * Check for infinite values. If the given value is infinite, it can be either positive or - * negative infinity, which we can infer from the 'position' argument. Note that 'position' + * negative infinity, which we can infer from the `position` argument. Note that `position` * cannot be 0 in such case, since infinities are always exclusive in this class. */ if (minValue == null) { @@ -543,14 +546,14 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer< return c; } /* - * The two values are equal. If the 'minValue' of this range is inclusive, then the given - * 'value' is directly at the "right" place (the beginning of the interior of this range), - * so the 'position' argument gives directly the position of the "true minValue" relative + * The two values are equal. If the `minValue` of this range is inclusive, then the given + * `value` is directly at the "right" place (the beginning of the interior of this range), + * so the `position` argument gives directly the position of the "true minValue" relative * to the interior of the other range. * - * But if 'minValue' is exclusive, then the "true minValue" of this range is one position + * But if `minValue` is exclusive, then the "true minValue" of this range is one position * to the right (where "position" is a counter for an infinitely small quantity, similar - * to 'dx' in calculus). The effect is to return 0 if the given 'value' is also exclusive + * to `dx` in calculus). The effect is to return 0 if the given `value` is also exclusive * and lower than the interior of the other range (position == -1), and a positive value * in all other cases. */ diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataCube.java b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataCube.java index 5e4de6565d..fc2a2679f4 100644 --- a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataCube.java +++ b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataCube.java @@ -219,7 +219,7 @@ abstract class DataCube extends TiledGridResource implements ResourceOnFileSyste } /* * The `DataSubset` parent class is the most efficient but has many limitations - * documented in the javadoc of its `readSlice(…)` method. If any pre-condition + * 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)) { diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataSubset.java b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataSubset.java index fa795ad802..043a3df5d4 100644 --- a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataSubset.java +++ b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataSubset.java @@ -482,7 +482,7 @@ class DataSubset extends TiledGridCoverage implements Localized { final int[] subsampling, final Point location) throws IOException, DataStoreException { final DataType type = getDataType(); - final int sampleSize = type.size(); // Assumed same as `SampleModel.getSampleSize(…)` by pre-conditions. + final int sampleSize = type.size(); // Assumed same as `SampleModel.getSampleSize(…)` by preconditions. final long width = subtractExact(upper[X_DIMENSION], lower[X_DIMENSION]); final long height = subtractExact(upper[Y_DIMENSION], lower[Y_DIMENSION]); /*