mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-10-04 11:26:44 -04:00
@@ -45,6 +45,7 @@ final class PNMHeader {
|
||||
private final TupleType tupleType;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final float maxSampleFloat;
|
||||
private final int maxSample;
|
||||
|
||||
private final List<String> comments;
|
||||
@@ -57,6 +58,7 @@ final class PNMHeader {
|
||||
this.height = isTrue(height > 0, height, "height must be greater than: %d");
|
||||
isTrue(depth == tupleType.getSamplesPerPixel(), depth, String.format("incorrect depth for %s, expected %d: %d", tupleType, tupleType.getSamplesPerPixel(), depth));
|
||||
this.maxSample = isTrue(tupleType.isValidMaxSample(maxSample), maxSample, "maxSample out of range: %d");
|
||||
this.maxSampleFloat = this.maxSample;
|
||||
|
||||
this.comments = Collections.unmodifiableList(new ArrayList<String>(comments));
|
||||
|
||||
@@ -70,7 +72,8 @@ final class PNMHeader {
|
||||
this.height = isTrue(height > 0, height, "height must be greater than: %d");
|
||||
isTrue(depth == tupleType.getSamplesPerPixel(), depth, String.format("incorrect depth for %s, expected %d: %d", tupleType, tupleType.getSamplesPerPixel(), depth));
|
||||
|
||||
this.maxSample = -1;
|
||||
this.maxSample = 1;
|
||||
this.maxSampleFloat = maxSample;
|
||||
this.byteOrder = byteOrder;
|
||||
|
||||
this.comments = Collections.unmodifiableList(new ArrayList<String>(comments));
|
||||
@@ -118,11 +121,8 @@ final class PNMHeader {
|
||||
if (maxSample <= PNM.MAX_VAL_16BIT) {
|
||||
return 16;
|
||||
}
|
||||
if ((maxSample & 0xffffffffL) <= PNM.MAX_VAL_32BIT) {
|
||||
return 32;
|
||||
}
|
||||
|
||||
throw new AssertionError("maxSample exceeds 32 bit");
|
||||
return 32;
|
||||
}
|
||||
|
||||
public int getTransferType() {
|
||||
@@ -135,11 +135,8 @@ final class PNMHeader {
|
||||
if (maxSample <= PNM.MAX_VAL_16BIT) {
|
||||
return DataBuffer.TYPE_USHORT;
|
||||
}
|
||||
if ((maxSample & 0xffffffffL) <= PNM.MAX_VAL_32BIT) {
|
||||
return DataBuffer.TYPE_INT;
|
||||
}
|
||||
|
||||
throw new AssertionError("maxSample exceeds 32 bit");
|
||||
return DataBuffer.TYPE_INT;
|
||||
}
|
||||
|
||||
public List<String> getComments() {
|
||||
|
@@ -49,11 +49,13 @@ import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.twelvemonkeys.imageio.util.IIOUtil.subsampleRow;
|
||||
|
||||
public final class PNMImageReader extends ImageReaderBase {
|
||||
// TODO: Allow reading unknown tuple types as Raster!
|
||||
// TODO: readAsRenderedImage?
|
||||
@@ -83,7 +85,7 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
|
||||
static String asASCII(final short type) {
|
||||
byte[] asciiBytes = {(byte) ((type >> 8) & 0xff), (byte) (type & 0xff)};
|
||||
return new String(asciiBytes, Charset.forName("ASCII"));
|
||||
return new String(asciiBytes, StandardCharsets.US_ASCII);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -150,7 +152,6 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
|
||||
default:
|
||||
// TODO: Allow reading unknown tuple types as Raster!
|
||||
|
||||
throw new AssertionError("Unknown PNM tuple type: " + header.getTupleType());
|
||||
}
|
||||
}
|
||||
@@ -261,7 +262,7 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
for (int y = 0; y < height; y++) {
|
||||
switch (transferType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
readRowByte(destRaster, clippedRow, colorConvert, rowDataByte, samplesPerPixel, input, y, srcRegion, xSub, ySub);
|
||||
readRowByte(destRaster, clippedRow, colorConvert, rowDataByte, header.getBitsPerSample(), samplesPerPixel, input, y, srcRegion, xSub, ySub);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
readRowUShort(destRaster, clippedRow, rowDataUShort, samplesPerPixel, input, y, srcRegion, xSub, ySub);
|
||||
@@ -339,7 +340,7 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
Raster rowRaster,
|
||||
final ColorConvertOp colorConvert,
|
||||
final byte[] rowDataByte,
|
||||
final int samplesPerPixel,
|
||||
final int bitsPerSample, final int samplesPerPixel,
|
||||
final DataInput input, final int y,
|
||||
final Rectangle srcRegion,
|
||||
final int xSub, final int ySub) throws IOException {
|
||||
@@ -352,7 +353,9 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
input.readFully(rowDataByte);
|
||||
|
||||
// Subsample (horizontal)
|
||||
subsampleHorizontal(rowDataByte, rowDataByte.length, samplesPerPixel, xSub);
|
||||
if (xSub > 1) {
|
||||
subsampleRow(rowDataByte, srcRegion.x, srcRegion.width, rowDataByte, 0, samplesPerPixel, bitsPerSample, xSub);
|
||||
}
|
||||
|
||||
normalize(rowDataByte, 0, rowDataByte.length / xSub);
|
||||
|
||||
@@ -379,7 +382,9 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
readFully(input, rowDataUShort);
|
||||
|
||||
// Subsample (horizontal)
|
||||
subsampleHorizontal(rowDataUShort, rowDataUShort.length, samplesPerPixel, xSub);
|
||||
if (xSub > 1) {
|
||||
subsampleRow(rowDataUShort, srcRegion.x, srcRegion.width, rowDataUShort, 0, samplesPerPixel, 16, xSub);
|
||||
}
|
||||
|
||||
normalize(rowDataUShort);
|
||||
|
||||
@@ -402,11 +407,14 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
readFully(input, rowDataFloat);
|
||||
|
||||
// Subsample (horizontal)
|
||||
subsampleHorizontal(rowDataFloat, rowDataFloat.length, samplesPerPixel, xSub);
|
||||
if (xSub > 1) {
|
||||
subsampleRow(rowDataFloat, srcRegion.x, srcRegion.width, rowDataFloat, 0, samplesPerPixel, 32, xSub);
|
||||
}
|
||||
|
||||
normalize(rowDataFloat);
|
||||
|
||||
int destY = (y - srcRegion.y) / ySub;
|
||||
// Note: PFM is stored bottom to top!
|
||||
int destY = destRaster.getHeight() - 1 - (y - srcRegion.y) / ySub;
|
||||
// TODO: ColorConvertOp if needed
|
||||
destRaster.setDataElements(0, destY, rowRaster);
|
||||
}
|
||||
@@ -437,19 +445,6 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SuspiciousSystemArraycopy")
|
||||
private void subsampleHorizontal(final Object data, final int length, final int samplesPerPixel, final int xSub) {
|
||||
if (xSub == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Super-special 1 bit subsampling handling for PBM
|
||||
|
||||
for (int x = 0; x < length / xSub; x += samplesPerPixel) {
|
||||
System.arraycopy(data, x * xSub, data, x, samplesPerPixel);
|
||||
}
|
||||
}
|
||||
|
||||
private void normalize(final byte[] rowData, final int start, final int length) {
|
||||
switch (header.getTupleType()) {
|
||||
case BLACKANDWHITE:
|
||||
@@ -484,13 +479,9 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
private void normalize(final float[] rowData) {
|
||||
// TODO: Do the real thing, find min/max and normalize to range 0...255? But only if not reading raster..? Only support reading as raster?
|
||||
// Normalize
|
||||
for (int i = 0; i < rowData.length; i++) {
|
||||
// if (rowData[i] > 275f /*header.getMaxSampleFloat()*/) {
|
||||
// System.out.println("rowData[" + i + "]: " + rowData[i]);
|
||||
// }
|
||||
// rowData[i] = rowData[i] / 275f /*header.getMaxSampleFloat()*/;
|
||||
rowData[i] = Math.min(1, rowData[i]); // Clamp
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -151,7 +151,10 @@ final class PNMMetadata extends AbstractMetadata {
|
||||
IIOMetadataNode dimension = new IIOMetadataNode("Dimension");
|
||||
|
||||
IIOMetadataNode imageOrientation = new IIOMetadataNode("ImageOrientation");
|
||||
imageOrientation.setAttribute("value", "Normal");
|
||||
imageOrientation.setAttribute("value",
|
||||
header.getFileType() == PNM.PFM_GRAY || header.getFileType() == PNM.PFM_RGB
|
||||
? "FlipH"
|
||||
: "Normal");
|
||||
dimension.appendChild(imageOrientation);
|
||||
|
||||
return dimension;
|
||||
|
Reference in New Issue
Block a user