You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ki...@apache.org on 2022/01/16 02:03:16 UTC
[commons-imaging] 16/24: [IMAGING-159] TIFF parameters implement single call to specify sub-image
This is an automated email from the ASF dual-hosted git repository.
kinow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-imaging.git
commit fe3199e9f1b78940119e1b66778066771b9f9095
Author: gwlucastrig <co...@gmail.com>
AuthorDate: Sun Aug 1 23:25:07 2021 -0400
[IMAGING-159] TIFF parameters implement single call to specify sub-image
---
.../imaging/formats/tiff/TiffImageParser.java | 41 +++------
.../formats/tiff/TiffImagingParameters.java | 102 ++++++++++++++++-----
.../formats/tiff/TiffFloatingPointReadTest.java | 5 +-
.../imaging/formats/tiff/TiffSubImageTest.java | 22 +----
4 files changed, 102 insertions(+), 68 deletions(-)
diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java
index 45fd84f..733f628 100644
--- a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java
+++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java
@@ -354,6 +354,9 @@ public class TiffImageParser extends ImageParser<TiffImagingParameters> implemen
byteSource, params, formatCompliance);
final List<TiffDirectory> directories = contents.directories;
+ if (directories == null) {
+ return false;
+ }
for (int d = 0; d < directories.size(); d++) {
final TiffDirectory directory = directories.get(d);
@@ -494,34 +497,20 @@ public class TiffImageParser extends ImageParser<TiffImagingParameters> implemen
private Rectangle checkForSubImage(
final TiffImagingParameters params)
throws ImageReadException {
- final Integer ix0 = params.getSubImageX();
- final Integer iy0 = params.getSubImageY();
- final Integer iwidth = params.getSubImageWidth();
- final Integer iheight = params.getSubImageHeight();
-
- if (ix0 == null && iy0 == null && iwidth == null && iheight == null) {
+ // the params class enforces a correct specification for the
+ // sub-image, but does not have knowledge of the actual
+ // dimensions of the image that is being read. This method
+ // returns the sub-image specification, if any, and leaves
+ // further tests to the calling module.
+ if (params.isSubImageSet()) {
+ final int ix0 = params.getSubImageX();
+ final int iy0 = params.getSubImageY();
+ final int iwidth = params.getSubImageWidth();
+ final int iheight = params.getSubImageHeight();
+ return new Rectangle(ix0, iy0, iwidth, iheight);
+ } else {
return null;
}
-
- final StringBuilder sb = new StringBuilder(32);
- if (ix0 == null) {
- sb.append(" x0,");
- }
- if (iy0 == null) {
- sb.append(" y0,");
- }
- if (iwidth == null) {
- sb.append(" width,");
- }
- if (iheight == null) {
- sb.append(" height,");
- }
- if (sb.length() > 0) {
- sb.setLength(sb.length() - 1);
- throw new ImageReadException("Incomplete subimage parameters, missing" + sb.toString());
- }
-
- return new Rectangle(ix0, iy0, iwidth, iheight);
}
protected BufferedImage getBufferedImage(final TiffDirectory directory,
diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImagingParameters.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImagingParameters.java
index b0d83c0..058e41e 100644
--- a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImagingParameters.java
+++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImagingParameters.java
@@ -40,22 +40,22 @@ public class TiffImagingParameters extends XmpImagingParameters {
/**
* X-coordinate of a sub-image.
*/
- private Integer subImageX = null;
+ private int subImageX;
/**
* Y-coordinate of a sub-image.
*/
- private Integer subImageY = null;
+ private int subImageY;
/**
* Width of a sub-image.
*/
- private Integer subImageWidth = null;
+ private int subImageWidth;
/**
* Height of a sub-image.
*/
- private Integer subImageHeight = null;
+ private int subImageHeight;
/**
* Specifies that an application-specified photometric interpreter
@@ -114,38 +114,98 @@ public class TiffImagingParameters extends XmpImagingParameters {
this.exif = exif;
}
- public Integer getSubImageX() {
- return subImageX;
+ /**
+ * Sets parameters for performing a partial read operation on an image. This
+ * method is useful for reducing memory and run-time overhead when accessing
+ * large source images.
+ * <p>
+ * Note that the corner x and y coordinates must be positive integers (zero
+ * or greater). The width and height must be greater than zero.
+ *
+ * @param x pixel coordinate of the upper-left corner of the source image,
+ * must be zero or greater.
+ * @param y pixel coordinate of the upper-left corner of the source image,
+ * must be zero or greater.
+ * @param width width of the image subset to be read, must be greater than
+ * zero.
+ * @param height height of the image subset to be read, must be greater than
+ * zero.
+ */
+ public void setSubImage(int x, int y, int width, int height) {
+ if (x < 0 || y < 0) {
+ throw new IllegalArgumentException(
+ "Invalid sub-image specification: negative x and y values not allowed");
+ }
+ if (width <= 0 || height <= 0) {
+ throw new IllegalArgumentException(
+ "Invalid sub-image specification width and height must be greater than zero");
+ }
+ subImageX = x;
+ subImageY = y;
+ subImageWidth = width;
+ subImageHeight = height;
}
- public void setSubImageX(Integer subImageX) {
- this.subImageX = subImageX;
+ /**
+ * Clears settings for sub-image. Subsequent read operations will retrieve
+ * the entire image.
+ */
+ public void clearSubImage() {
+ subImageWidth = 0;
+ subImageHeight = 0;
}
- public Integer getSubImageY() {
- return subImageY;
+ /**
+ * Indicates whether the application has set sub-image parameters.
+ *
+ * @return true if the sub-image parameters are set; otherwise, false.
+ */
+ public boolean isSubImageSet() {
+ return subImageWidth > 0 && subImageHeight > 0;
}
- public void setSubImageY(Integer subImageY) {
- this.subImageY = subImageY;
+ /**
+ * Gets the X coordinate of a sub-image. This setting is meaningful only if
+ * a sub-image is set.
+ *
+ * @return a positive integer
+ */
+ public int getSubImageX() {
+ return subImageX;
}
- public Integer getSubImageWidth() {
- return subImageWidth;
+ /**
+ * Gets the Y coordinate of a sub-image. This setting is meaningful only if
+ * a sub-image is set.
+ *
+ * @return a positive integer
+ */
+ public int getSubImageY() {
+ return subImageY;
}
- public void setSubImageWidth(Integer subImageWidth) {
- this.subImageWidth = subImageWidth;
+ /**
+ * Gets the width for a sub-image setting. For a sub-image setting to be
+ * meaningful, both the width and height must be set.
+ *
+ * @return if the sub-image feature is enabled, a value greater than zero;
+ * otherwise, zero.
+ */
+ public int getSubImageWidth() {
+ return subImageWidth;
}
- public Integer getSubImageHeight() {
+ /**
+ * Gets the height for a sub-image setting. For a sub-image setting to be
+ * meaningful, both the width and height must be set.
+ *
+ * @return if the sub-image feature is enabled, a value greater than zero;
+ * otherwise, zero.
+ */
+ public int getSubImageHeight() {
return subImageHeight;
}
- public void setSubImageHeight(Integer subImageHeight) {
- this.subImageHeight = subImageHeight;
- }
-
public PhotometricInterpreter getCustomPhotometricInterpreter() {
return customPhotometricInterpreter;
}
diff --git a/src/test/java/org/apache/commons/imaging/formats/tiff/TiffFloatingPointReadTest.java b/src/test/java/org/apache/commons/imaging/formats/tiff/TiffFloatingPointReadTest.java
index 2fbf933..644ff66 100644
--- a/src/test/java/org/apache/commons/imaging/formats/tiff/TiffFloatingPointReadTest.java
+++ b/src/test/java/org/apache/commons/imaging/formats/tiff/TiffFloatingPointReadTest.java
@@ -223,10 +223,7 @@ public class TiffFloatingPointReadTest {
private void checkSubImage(final File target, final TiffRasterData fullRaster, final int x0, final int y0, final int width, final int height){
try{
final TiffImagingParameters params = new TiffImagingParameters();
- params.setSubImageX(x0);
- params.setSubImageY(y0);
- params.setSubImageWidth(width);
- params.setSubImageHeight(height);
+ params.setSubImage(x0, y0, width, height);
final TiffRasterData partRaster = readRasterFromTIFF(target, params);
assertEquals(width, partRaster.getWidth(), "Invalid width in partial for " + target.getName());
assertEquals(height, partRaster.getHeight(), "Invalid height in partial for " + target.getName());
diff --git a/src/test/java/org/apache/commons/imaging/formats/tiff/TiffSubImageTest.java b/src/test/java/org/apache/commons/imaging/formats/tiff/TiffSubImageTest.java
index 9316f35..1f52ab0 100644
--- a/src/test/java/org/apache/commons/imaging/formats/tiff/TiffSubImageTest.java
+++ b/src/test/java/org/apache/commons/imaging/formats/tiff/TiffSubImageTest.java
@@ -42,10 +42,7 @@ public class TiffSubImageTest extends TiffBaseTest {
final BufferedImage src = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB);
final TiffImagingParameters params = new TiffImagingParameters();
final byte[] imageBytes = Imaging.writeImageToBytes(src, ImageFormats.TIFF, params);
- params.setSubImageX(0);
- params.setSubImageY(0);
- params.setSubImageWidth(2);
- params.setSubImageHeight(3);
+ params.setSubImage(0, 0, 2, 3);
final BufferedImage image = Imaging.getBufferedImage(imageBytes, params);
assertEquals(image.getWidth(), 2);
assertEquals(image.getHeight(), 3);
@@ -59,10 +56,7 @@ public class TiffSubImageTest extends TiffBaseTest {
final int height = referenceImage.getHeight();
final TiffImagingParameters params = new TiffImagingParameters();
- params.setSubImageX(0);
- params.setSubImageY(0);
- params.setSubImageWidth(width);
- params.setSubImageHeight(height);
+ params.setSubImage(0, 0, width, height);
final BufferedImage image = Imaging.getBufferedImage(target, params);
assertEquals(image.getWidth(), width, "Improper width when sub-imaging entire image");
@@ -79,13 +73,10 @@ public class TiffSubImageTest extends TiffBaseTest {
private void processBadParams(final File target, final int x, final int y, final int width, final int height, final String comment) throws IOException{
try{
final TiffImagingParameters params = new TiffImagingParameters();
- params.setSubImageX(x);
- params.setSubImageY(y);
- params.setSubImageWidth(width);
- params.setSubImageHeight(height);
+ params.setSubImage(x, y, width, height);
final BufferedImage image = Imaging.getBufferedImage(target, params);
fail("Reading TIFF sub-image failed to detect bad parameter: "+comment);
- }catch(final ImageReadException ire){
+ }catch(final ImageReadException | IllegalArgumentException ire){
// the test passed
}
}
@@ -102,10 +93,7 @@ public class TiffSubImageTest extends TiffBaseTest {
final int []rArgb = new int[rW*rH];
referenceImage.getRGB(0, 0, rW, rH, rArgb, 0, rW);
final TiffImagingParameters params = new TiffImagingParameters();
- params.setSubImageX(1);
- params.setSubImageY(1);
- params.setSubImageWidth(rW - 2);
- params.setSubImageHeight(rH - 2);
+ params.setSubImage(1, 1, rW-2, rH-2);
final BufferedImage image = Imaging.getBufferedImage(target, params);
final int iW = image.getWidth();
final int iH = image.getHeight();