kinow commented on a change in pull request #165:
URL: https://github.com/apache/commons-imaging/pull/165#discussion_r706486666
##########
File path:
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/ImageDataReader.java
##########
@@ -519,8 +516,55 @@ protected void applyPredictorToBlock(final int width,
final int height, final in
return samples;
}
+ protected int[] unpackIntSamples(
+ final int width,
+ final int height,
+ final int scansize,
+ final byte[] bytes,
+ final int predictor,
+ final int bitsPerSample,
+ final ByteOrder byteOrder)
+ throws ImageReadException {
Review comment:
`ImageReadException` never thrown, I think we can remove it from here.
##########
File path:
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/ImageDataReader.java
##########
@@ -519,8 +516,55 @@ protected void applyPredictorToBlock(final int width,
final int height, final in
return samples;
}
+ protected int[] unpackIntSamples(
Review comment:
Javadoc comment, documenting this new method?
##########
File path:
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderTiled.java
##########
@@ -321,19 +336,68 @@ public TiffRasterData readRasterData(final Rectangle
subImage)
final int tile = iRow * nColumnsOfTiles + iCol;
final byte[] compressed = imageData.tiles[tile].getData();
final byte[] decompressed = decompress(compressed, compression,
- bytesPerTile, tileWidth, tileLength);
+ bytesPerTile, tileWidth, tileLength);
final int x = iCol * tileWidth;
final int y = iRow * tileLength;
+
final int[] blockData = unpackFloatingPointSamples(
- tileWidth, tileLength, tileWidth,
- decompressed,
- predictor, bitsPerPixel, byteOrder);
+ tileWidth, tileLength, tileWidth,
+ decompressed,
+ predictor, bitsPerPixel, byteOrder);
transferBlockToRaster(x, y, tileWidth, tileLength, blockData,
- xRaster, yRaster, rasterWidth, rasterHeight, rasterData);
+ xRaster, yRaster, rasterWidth, rasterHeight,
rasterDataFloat);
}
}
-
- return new TiffRasterData(rasterWidth, rasterHeight, rasterData);
+ return new TiffRasterDataFloat(rasterWidth, rasterHeight,
rasterDataFloat);
}
+ private TiffRasterData readRasterDataInt(final Rectangle subImage)
+ throws ImageReadException, IOException {
+ final int bitsPerRow = tileWidth * bitsPerPixel;
+ final int bytesPerRow = (bitsPerRow + 7) / 8;
+ final int bytesPerTile = bytesPerRow * tileLength;
+ int xRaster;
+ int yRaster;
+ int rasterWidth;
+ int rasterHeight;
+ if (subImage != null) {
+ xRaster = subImage.x;
+ yRaster = subImage.y;
+ rasterWidth = subImage.width;
+ rasterHeight = subImage.height;
+ } else {
+ xRaster = 0;
+ yRaster = 0;
+ rasterWidth = width;
+ rasterHeight = height;
+ }
+ int[] rasterDataInt = new int[rasterWidth * rasterHeight];
+
+ // tileWidth is the width of the tile
+ // tileLength is the height of the tile
+ final int col0 = xRaster / tileWidth;
+ final int col1 = (xRaster + rasterWidth - 1) / tileWidth;
+ final int row0 = yRaster / tileLength;
+ final int row1 = (yRaster + rasterHeight - 1) / tileLength;
Review comment:
Unrelated to this change too, but `tileLength`... shouldn't it be
`tileHeight`?
##########
File path:
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderTiled.java
##########
@@ -286,7 +288,20 @@ public ImageBuilder readImageData(final Rectangle
subImageSpecification,
@Override
public TiffRasterData readRasterData(final Rectangle subImage)
- throws ImageReadException, IOException {
+ throws ImageReadException, IOException {
+ switch (sampleFormat) {
+ case TiffTagConstants.SAMPLE_FORMAT_VALUE_IEEE_FLOATING_POINT:
Review comment:
Code is excellent here @gwlucastrig , but out of curiosity, do you know
why we have `SAMPLE_FORMAT_VALUE_IEEE_FLOATING_POINT` and
`SAMPLE_FORMAT_VALUE_IEEE_FLOATING_POINT_1`? That's probably from the
specification, but since we don't have any javadocs in the constants I can't
recall the reason for it.
##########
File path:
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderStrips.java
##########
@@ -390,16 +405,69 @@ public TiffRasterData readRasterData(final Rectangle
subImage)
final byte[] compressed = imageData.getImageData(strip).getData();
final byte[] decompressed = decompress(compressed, compression,
- bytesPerStrip, width, rowsInThisStrip);
+ bytesPerStrip, width, rowsInThisStrip);
final int[] blockData = unpackFloatingPointSamples(
- width, (int) rowsInThisStrip, width,
- decompressed,
- predictor, bitsPerPixel, byteOrder);
+ width,
+ (int) rowsInThisStrip,
Review comment:
Unnecessary casting.
##########
File path:
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderStrips.java
##########
@@ -390,16 +405,69 @@ public TiffRasterData readRasterData(final Rectangle
subImage)
final byte[] compressed = imageData.getImageData(strip).getData();
final byte[] decompressed = decompress(compressed, compression,
- bytesPerStrip, width, rowsInThisStrip);
+ bytesPerStrip, width, rowsInThisStrip);
final int[] blockData = unpackFloatingPointSamples(
- width, (int) rowsInThisStrip, width,
- decompressed,
- predictor, bitsPerPixel, byteOrder);
+ width,
+ (int) rowsInThisStrip,
+ width,
+ decompressed,
+ predictor, bitsPerPixel, byteOrder);
transferBlockToRaster(0, yStrip, width, (int) rowsInThisStrip,
blockData,
- xRaster, yRaster, rasterWidth, rasterHeight, rasterData);
+ xRaster, yRaster, rasterWidth, rasterHeight,
rasterDataFloat);
}
- return new TiffRasterData(rasterWidth, rasterHeight, rasterData);
+ return new TiffRasterDataFloat(rasterWidth, rasterHeight,
rasterDataFloat);
}
+ private TiffRasterData readRasterDataInt(final Rectangle subImage)
+ throws ImageReadException, IOException {
+ int xRaster;
+ int yRaster;
+ int rasterWidth;
+ int rasterHeight;
+ if (subImage != null) {
+ xRaster = subImage.x;
+ yRaster = subImage.y;
+ rasterWidth = subImage.width;
+ rasterHeight = subImage.height;
+ } else {
+ xRaster = 0;
+ yRaster = 0;
+ rasterWidth = width;
+ rasterHeight = height;
+ }
+
+ int[] rasterDataInt = new int[rasterWidth * rasterHeight];
+
+ // the legacy code is optimized to the reading of whole
+ // strips (except for the last strip in the image, which can
+ // be a partial). So create a working image with compatible
+ // dimensions and read that. Later on, the working image
+ // will be sub-imaged to the proper size.
+ // strip0 and strip1 give the indices of the strips containing
+ // the first and last rows of pixels in the subimage
+ final int strip0 = yRaster / rowsPerStrip;
+ final int strip1 = (yRaster + rasterHeight - 1) / rowsPerStrip;
+
+ for (int strip = strip0; strip <= strip1; strip++) {
+ final int yStrip = strip * rowsPerStrip;
+ final int rowsRemaining = height - yStrip;
+ final int rowsInThisStrip = Math.min(rowsRemaining, rowsPerStrip);
+ final int bytesPerRow = (bitsPerPixel * width + 7) / 8;
+ final int bytesPerStrip = rowsInThisStrip * bytesPerRow;
+
+ final byte[] compressed = imageData.getImageData(strip).getData();
+ final byte[] decompressed = decompress(compressed, compression,
+ bytesPerStrip, width, rowsInThisStrip);
+ final int[] blockData = unpackIntSamples(
+ width,
+ (int) rowsInThisStrip,
Review comment:
Unnecessary casting.
##########
File path:
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/ImageDataReader.java
##########
@@ -602,6 +646,87 @@ void transferBlockToRaster(final int xBlock, final int
yBlock,
}
}
+ /**
+ * Transfer samples obtained from the TIFF file to an integer raster.
+ * @param xBlock coordinate of block relative to source data
+ * @param yBlock coordinate of block relative to source data
+ * @param blockWidth width of block, in pixels
+ * @param blockHeight height of block in pixels
+ * @param blockData the data for the block
+ * @param xRaster coordinate of raster relative to source data
+ * @param yRaster coordinate of raster relative to source data
+ * @param rasterWidth width of the raster (always smaller than source data)
+ * @param rasterHeight height of the raster (always smaller than source
+ * data)
+ * @param rasterData the raster data.
+ */
+ void transferBlockToRaster(final int xBlock, final int yBlock,
+ final int blockWidth, final int blockHeight, final int[] blockData,
+ final int xRaster, final int yRaster,
+ final int rasterWidth, final int rasterHeight, final int[] rasterData)
{
+
+ // xR0, yR0 are the coordinates within the raster (upper-left corner)
+ // xR1, yR1 are ONE PAST the coordinates of the lower-right corner
+ int xR0 = xBlock - xRaster; // xR0, yR0 coordinates relative to
+ int yR0 = yBlock - yRaster; // the raster
+ int xR1 = xR0 + blockWidth;
+ int yR1 = yR0 + blockHeight;
+ if (xR0 < 0) {
+ xR0 = 0;
+ }
+ if (yR0 < 0) {
+ yR0 = 0;
+ }
+ if (xR1 > rasterWidth) {
+ xR1 = rasterWidth;
+ }
+ if (yR1 > rasterHeight) {
+ yR1 = rasterHeight;
+ }
+
+ // Recall that the above logic may have adjusted xR0, xY0 so that
+ // they are not necessarily point to the source pixel at xRaster,
yRaster
+ // we compute xSource = xR0+xRaster.
+ // xOffset = xSource-xBlock
+ // since the block cannot be accessed with a negative offset,
+ // we check for negatives and adjust xR0, yR0 upward as necessary
+ int xB0 = xR0 + xRaster - xBlock;
+ int yB0 = yR0 + yRaster - yBlock;
+ if (xB0 < 0) {
+ xR0 -= xB0;
+ xB0 = 0;
+ }
+ if (yB0 < 0) {
+ yR0 -= yB0;
+ yB0 = 0;
+ }
+
+ int w = xR1 - xR0;
+ int h = yR1 - yR0;
+ if (w <= 0 || h <= 0) {
+ // The call to this method put the block outside the
Review comment:
s/put/puts?
##########
File path:
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderStrips.java
##########
@@ -390,16 +405,69 @@ public TiffRasterData readRasterData(final Rectangle
subImage)
final byte[] compressed = imageData.getImageData(strip).getData();
final byte[] decompressed = decompress(compressed, compression,
- bytesPerStrip, width, rowsInThisStrip);
+ bytesPerStrip, width, rowsInThisStrip);
final int[] blockData = unpackFloatingPointSamples(
- width, (int) rowsInThisStrip, width,
- decompressed,
- predictor, bitsPerPixel, byteOrder);
+ width,
+ (int) rowsInThisStrip,
+ width,
+ decompressed,
+ predictor, bitsPerPixel, byteOrder);
transferBlockToRaster(0, yStrip, width, (int) rowsInThisStrip,
blockData,
Review comment:
Also unnecessary casting, but not in this PR.
##########
File path:
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderStrips.java
##########
@@ -390,16 +405,69 @@ public TiffRasterData readRasterData(final Rectangle
subImage)
final byte[] compressed = imageData.getImageData(strip).getData();
final byte[] decompressed = decompress(compressed, compression,
- bytesPerStrip, width, rowsInThisStrip);
+ bytesPerStrip, width, rowsInThisStrip);
final int[] blockData = unpackFloatingPointSamples(
- width, (int) rowsInThisStrip, width,
- decompressed,
- predictor, bitsPerPixel, byteOrder);
+ width,
+ (int) rowsInThisStrip,
+ width,
+ decompressed,
+ predictor, bitsPerPixel, byteOrder);
transferBlockToRaster(0, yStrip, width, (int) rowsInThisStrip,
blockData,
- xRaster, yRaster, rasterWidth, rasterHeight, rasterData);
+ xRaster, yRaster, rasterWidth, rasterHeight,
rasterDataFloat);
}
- return new TiffRasterData(rasterWidth, rasterHeight, rasterData);
+ return new TiffRasterDataFloat(rasterWidth, rasterHeight,
rasterDataFloat);
}
+ private TiffRasterData readRasterDataInt(final Rectangle subImage)
+ throws ImageReadException, IOException {
+ int xRaster;
+ int yRaster;
+ int rasterWidth;
+ int rasterHeight;
+ if (subImage != null) {
+ xRaster = subImage.x;
+ yRaster = subImage.y;
+ rasterWidth = subImage.width;
+ rasterHeight = subImage.height;
+ } else {
+ xRaster = 0;
+ yRaster = 0;
+ rasterWidth = width;
+ rasterHeight = height;
+ }
+
+ int[] rasterDataInt = new int[rasterWidth * rasterHeight];
+
+ // the legacy code is optimized to the reading of whole
+ // strips (except for the last strip in the image, which can
+ // be a partial). So create a working image with compatible
+ // dimensions and read that. Later on, the working image
+ // will be sub-imaged to the proper size.
+ // strip0 and strip1 give the indices of the strips containing
+ // the first and last rows of pixels in the subimage
+ final int strip0 = yRaster / rowsPerStrip;
+ final int strip1 = (yRaster + rasterHeight - 1) / rowsPerStrip;
+
+ for (int strip = strip0; strip <= strip1; strip++) {
+ final int yStrip = strip * rowsPerStrip;
+ final int rowsRemaining = height - yStrip;
+ final int rowsInThisStrip = Math.min(rowsRemaining, rowsPerStrip);
+ final int bytesPerRow = (bitsPerPixel * width + 7) / 8;
+ final int bytesPerStrip = rowsInThisStrip * bytesPerRow;
+
+ final byte[] compressed = imageData.getImageData(strip).getData();
+ final byte[] decompressed = decompress(compressed, compression,
+ bytesPerStrip, width, rowsInThisStrip);
+ final int[] blockData = unpackIntSamples(
+ width,
+ (int) rowsInThisStrip,
+ width,
+ decompressed,
+ predictor, bitsPerPixel, byteOrder);
+ transferBlockToRaster(0, yStrip, width, (int) rowsInThisStrip,
blockData,
Review comment:
Unnecessary casting.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]