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 <contact.tinf...@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();