NetBPM clean-up, fixes and better tests.

This commit is contained in:
Harald Kuhr 2020-10-23 19:25:54 +02:00
parent 6ffcb88872
commit 0a9e2df5de
26 changed files with 471 additions and 173 deletions

View File

@ -122,12 +122,16 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
boolean found = false;
while (pReaders.hasNext()) {
ImageReader reader = pReaders.next();
if (reader.getClass() == pReaderClass) {
if (reader.getClass() == pReaderClass && isOurProvider(reader.getOriginatingProvider())) {
found = true;
}
}
assertTrue(String.format("%s not installed for %s", pReaderClass.getSimpleName(), pFormat), found);
assertTrue(String.format("%s not provided by %s for '%s'", pReaderClass.getSimpleName(), provider.getClass().getSimpleName(), pFormat), found);
}
private boolean isOurProvider(final ImageReaderSpi spi) {
return provider.getClass().isInstance(spi);
}
@Test

View File

@ -30,6 +30,8 @@
package com.twelvemonkeys.imageio.plugins.pnm;
import com.twelvemonkeys.imageio.ImageWriterBase;
import org.w3c.dom.NodeList;
import javax.imageio.IIOImage;
@ -40,27 +42,30 @@ import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.DataBuffer;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Locale;
import static java.nio.charset.StandardCharsets.UTF_8;
abstract class HeaderWriter {
protected static final Charset UTF8 = Charset.forName("UTF8");
protected final ImageOutputStream imageOutput;
protected HeaderWriter(final ImageOutputStream imageOutput) {
this.imageOutput = imageOutput;
}
public static void write(final IIOImage image, final ImageWriterSpi provider, final ImageOutputStream imageOutput) throws IOException {
// TODO: This is somewhat sketchy...
if (provider.getFormatNames()[0].equals("pam")) {
new PAMHeaderWriter(imageOutput).writeHeader(image, provider);
public static void write(final IIOImage image, final ImageWriterBase writer, final ImageOutputStream imageOutput) throws IOException {
createHeaderWriter(writer.getFormatName(), imageOutput).writeHeader(image, writer.getOriginatingProvider());
}
private static HeaderWriter createHeaderWriter(final String formatName, final ImageOutputStream imageOutput) {
if (formatName.equals("pam")) {
return new PAMHeaderWriter(imageOutput);
}
else if (provider.getFormatNames()[0].equals("pnm")) {
new PNMHeaderWriter(imageOutput).writeHeader(image, provider);
else if (formatName.equals("pnm")) {
return new PNMHeaderWriter(imageOutput);
}
else {
throw new AssertionError("Unsupported provider: " + provider);
throw new AssertionError("Unsupported format: " + formatName);
}
}
@ -101,7 +106,7 @@ abstract class HeaderWriter {
protected final void writeComments(final IIOMetadata metadata, final ImageWriterSpi provider) throws IOException {
// TODO: Only write creator if not already present
imageOutput.write(String.format("# CREATOR: %s %s\n", provider.getVendorName(), provider.getDescription(Locale.getDefault())).getBytes(UTF8));
imageOutput.write(String.format("# CREATOR: %s %s\n", provider.getVendorName(), provider.getDescription(Locale.getDefault())).getBytes(UTF_8));
// Comments from metadata
if (metadata != null && metadata.isStandardMetadataFormatSupported()) {
@ -111,7 +116,7 @@ abstract class HeaderWriter {
for (int i = 0; i < textEntries.getLength(); i++) {
// TODO: Write on the format "# KEYWORD: value" (if keyword != comment)?
IIOMetadataNode textEntry = (IIOMetadataNode) textEntries.item(i);
imageOutput.write(String.format("# %s", textEntry.getAttribute("value")).getBytes(UTF8));
imageOutput.write(String.format("# %s", textEntry.getAttribute("value")).getBytes(UTF_8));
}
}
}

View File

@ -66,7 +66,7 @@ final class PAMHeaderParser extends HeaderParser {
int depth = -1;
int maxVal = -1;
TupleType tupleType = null;
List<String> comments = new ArrayList<String>();
List<String> comments = new ArrayList<>();
String line;
while ((line = input.readLine()) != null && !line.startsWith(ENDHDR)) {

View File

@ -35,6 +35,8 @@ import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.ImageOutputStream;
import java.io.IOException;
import static java.nio.charset.StandardCharsets.UTF_8;
final class PAMHeaderWriter extends HeaderWriter {
public PAMHeaderWriter(final ImageOutputStream imageOutput) {
super(imageOutput);
@ -48,14 +50,14 @@ final class PAMHeaderWriter extends HeaderWriter {
// Comments
writeComments(image.getMetadata(), provider);
// Write width/height and number of channels
imageOutput.write(String.format("WIDTH %s\nHEIGHT %s\n", getWidth(image), getHeight(image)).getBytes(UTF8));
imageOutput.write(String.format("DEPTH %s\n", getNumBands(image)).getBytes(UTF8));
imageOutput.write(String.format("WIDTH %s\nHEIGHT %s\n", getWidth(image), getHeight(image)).getBytes(UTF_8));
imageOutput.write(String.format("DEPTH %s\n", getNumBands(image)).getBytes(UTF_8));
// TODO: maxSample (8 or16 bit)
imageOutput.write(String.format("MAXVAL %s\n", getMaxVal(image)).getBytes(UTF8));
imageOutput.write(String.format("MAXVAL %s\n", getMaxVal(image)).getBytes(UTF_8));
// TODO: Determine tuple type based on input color model and image data
TupleType tupleType = getNumBands(image) > 3 ? TupleType.RGB_ALPHA : TupleType.RGB;
imageOutput.write(String.format("TUPLTYPE %s\nENDHDR\n", tupleType).getBytes(UTF8));
imageOutput.write(String.format("TUPLTYPE %s\nENDHDR\n", tupleType).getBytes(UTF_8));
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2020, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.pnm;
import com.twelvemonkeys.imageio.spi.ImageReaderSpiBase;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.io.IOException;
import java.util.Locale;
public final class PAMImageReaderSpi extends ImageReaderSpiBase {
/**
* Creates a {@code PAMImageReaderSpi}.
*/
public PAMImageReaderSpi() {
super(new PAMProviderInfo());
}
@Override
public boolean canDecodeInput(final Object source) throws IOException {
if (!(source instanceof ImageInputStream)) {
return false;
}
ImageInputStream stream = (ImageInputStream) source;
stream.mark();
try {
return stream.readShort() == PNM.PAM && stream.readInt() != PNM.XV_THUMBNAIL_MAGIC;
}
finally {
stream.reset();
}
}
@Override
public ImageReader createReaderInstance(final Object extension) {
return new PNMImageReader(this);
}
@Override
public String getDescription(final Locale locale) {
return "NetPBM Portable Arbitrary Map (PAM) image reader";
}
}

View File

@ -30,39 +30,19 @@
package com.twelvemonkeys.imageio.plugins.pnm;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.imageio.spi.ImageWriterSpiBase;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.ImageOutputStream;
import java.util.Locale;
public final class PAMImageWriterSpi extends ImageWriterSpi {
public final class PAMImageWriterSpi extends ImageWriterSpiBase {
/**
* Creates a {@code PAMImageWriterSpi}.
*/
public PAMImageWriterSpi() {
this(new PNMProviderInfo());
}
private PAMImageWriterSpi(final ProviderInfo pProviderInfo) {
super(
pProviderInfo.getVendorName(),
pProviderInfo.getVersion(),
new String[] {"pam", "PAM"},
new String[] {"pam"},
new String[] {
// No official IANA record exists, these are conventional
"image/x-portable-arbitrarymap" // PAM
},
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriter",
new Class[] {ImageOutputStream.class},
new String[] {"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReaderSpi"},
true, null, null, null, null,
true, null, null, null, null
);
super(new PAMProviderInfo());
}
public boolean canEncodeImage(final ImageTypeSpecifier pType) {

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2020, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.pnm;
import com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfo;
/**
* PAMProviderInfo.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: harald.kuhr$
* @version $Id: PAMProviderInfo.java,v 1.0 20/03/15 harald.kuhr Exp$
*/
class PAMProviderInfo extends ReaderWriterProviderInfo {
public PAMProviderInfo() {
super(PAMProviderInfo.class,
new String[] {
"pam",
"PAM"
},
new String[] {"pam"},
new String[] {
// No official IANA record exists, these are conventional
"image/x-portable-arbitrarymap"
},
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReader",
new String[] {
"com.twelvemonkeys.imageio.plugins.pnm.PAMImageReaderSpi",
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReaderSpi"
},
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriter",
new String[] {
"com.twelvemonkeys.imageio.plugins.pnm.PAMImageWriterSpi",
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriterSpi"
},
true, // supports standard stream metadata
null, null, // native stream format name and class
null, null, // extra stream formats
true, // supports standard image metadata
null, null,
null, null // extra image metadata formats
);
}
}

View File

@ -71,7 +71,7 @@ final class PFMHeaderParser extends HeaderParser {
int height = 0;
float maxSample = tupleType == TupleType.BLACKANDWHITE_WHITE_IS_ZERO ? 1 : 0; // PBM has no maxSample line
List<String> comments = new ArrayList<String>();
List<String> comments = new ArrayList<>();
while (width == 0 || height == 0 || maxSample == 0) {
String line = input.readLine();

View File

@ -60,7 +60,7 @@ final class PNMHeader {
this.maxSample = isTrue(tupleType.isValidMaxSample(maxSample), maxSample, "maxSample out of range: %d");
this.maxSampleFloat = this.maxSample;
this.comments = Collections.unmodifiableList(new ArrayList<String>(comments));
this.comments = Collections.unmodifiableList(new ArrayList<>(comments));
byteOrder = ByteOrder.BIG_ENDIAN;
}
@ -76,7 +76,7 @@ final class PNMHeader {
this.maxSampleFloat = maxSample;
this.byteOrder = byteOrder;
this.comments = Collections.unmodifiableList(new ArrayList<String>(comments));
this.comments = Collections.unmodifiableList(new ArrayList<>(comments));
}
private boolean isValidFileType(final short fileType) {

View File

@ -68,7 +68,7 @@ final class PNMHeaderParser extends HeaderParser {
int height = 0;
int maxSample = tupleType == TupleType.BLACKANDWHITE_WHITE_IS_ZERO ? 1 : 0; // PBM has no maxSample line
List<String> comments = new ArrayList<String>();
List<String> comments = new ArrayList<>();
while (width == 0 || height == 0 || maxSample == 0) {
String line = input.readLine();

View File

@ -35,6 +35,8 @@ import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.ImageOutputStream;
import java.io.IOException;
import static java.nio.charset.StandardCharsets.UTF_8;
final class PNMHeaderWriter extends HeaderWriter {
public PNMHeaderWriter(final ImageOutputStream imageOutput) {
super(imageOutput);
@ -52,11 +54,11 @@ final class PNMHeaderWriter extends HeaderWriter {
writeComments(image.getMetadata(), provider);
// Dimensions (width/height)
imageOutput.write(String.format("%s %s\n", getWidth(image), getHeight(image)).getBytes(HeaderWriter.UTF8));
imageOutput.write(String.format("%s %s\n", getWidth(image), getHeight(image)).getBytes(UTF_8));
// MaxSample
if (type != PNM.PBM) {
imageOutput.write(String.format("%s\n", getMaxVal(image)).getBytes(HeaderWriter.UTF8));
imageOutput.write(String.format("%s\n", getMaxVal(image)).getBytes(UTF_8));
}
}
}

View File

@ -170,7 +170,7 @@ public final class PNMImageReader extends ImageReaderBase {
public Iterator<ImageTypeSpecifier> getImageTypes(final int imageIndex) throws IOException {
ImageTypeSpecifier rawType = getRawImageType(imageIndex);
List<ImageTypeSpecifier> specifiers = new ArrayList<ImageTypeSpecifier>();
List<ImageTypeSpecifier> specifiers = new ArrayList<>();
switch (header.getTupleType()) {
case RGB:

View File

@ -30,51 +30,20 @@
package com.twelvemonkeys.imageio.plugins.pnm;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.imageio.spi.ImageReaderSpiBase;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import java.io.IOException;
import java.util.Locale;
public final class PNMImageReaderSpi extends ImageReaderSpi {
public final class PNMImageReaderSpi extends ImageReaderSpiBase {
/**
* Creates a {@code PNMImageReaderSpi}.
*/
public PNMImageReaderSpi() {
this(new PNMProviderInfo());
}
private PNMImageReaderSpi(final ProviderInfo providerInfo) {
super(
providerInfo.getVendorName(),
providerInfo.getVersion(),
new String[] {
"pnm", "pbm", "pgm", "ppm", "pam", "pfm",
"PNM", "PBM", "PGM", "PPM", "PAM", "PFM"
},
new String[] {"pbm", "pgm", "ppm", "pam", "pfm"},
new String[] {
// No official IANA record exists, these are conventional
"image/x-portable-pixmap",
"image/x-portable-anymap",
"image/x-portable-arbitrarymap" // PAM
},
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReader",
new Class[] {ImageInputStream.class},
new String[] {
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriterSpi",
"com.twelvemonkeys.imageio.plugins.pnm.PAMImageWriterSpi"
},
true, // supports standard stream metadata
null, null, // native stream format name and class
null, null, // extra stream formats
true, // supports standard image metadata
null, null,
null, null // extra image metadata formats
);
super(new PNMProviderInfo());
}
@Override
@ -100,8 +69,6 @@ public final class PNMImageReaderSpi extends ImageReaderSpi {
case PNM.PFM_GRAY:
case PNM.PFM_RGB:
return true;
case PNM.PAM:
return stream.readInt() != PNM.XV_THUMBNAIL_MAGIC;
default:
return false;
}
@ -112,12 +79,12 @@ public final class PNMImageReaderSpi extends ImageReaderSpi {
}
@Override
public ImageReader createReaderInstance(final Object extension) throws IOException {
public ImageReader createReaderInstance(final Object extension) {
return new PNMImageReader(this);
}
@Override
public String getDescription(final Locale locale) {
return "NetPBM Portable Any Map (PNM and PAM) image reader";
return "NetPBM Portable Any Map (PNM) image reader";
}
}

View File

@ -69,7 +69,7 @@ public final class PNMImageWriter extends ImageWriterBase {
// TODO: Issue warning if streamMetadata is non-null?
// TODO: Issue warning if IIOImage contains thumbnails or other data we can't store?
HeaderWriter.write(image, getOriginatingProvider(), imageOutput);
HeaderWriter.write(image, this, imageOutput);
// TODO: Sub region
// TODO: Subsampling

View File

@ -30,15 +30,13 @@
package com.twelvemonkeys.imageio.plugins.pnm;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.imageio.spi.ImageWriterSpiBase;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.ImageOutputStream;
import java.util.Locale;
public final class PNMImageWriterSpi extends ImageWriterSpi {
public final class PNMImageWriterSpi extends ImageWriterSpiBase {
// TODO: Consider one Spi for each sub-format, as it makes no sense for the writer to write PPM if client code requested PBM or PGM format.
// ...Then again, what if user asks for PNM? :-P
@ -47,29 +45,7 @@ public final class PNMImageWriterSpi extends ImageWriterSpi {
* Creates a {@code PNMImageWriterSpi}.
*/
public PNMImageWriterSpi() {
this(new PNMProviderInfo());
}
private PNMImageWriterSpi(final ProviderInfo pProviderInfo) {
super(
pProviderInfo.getVendorName(),
pProviderInfo.getVersion(),
new String[] {
"pnm", "pbm", "pgm", "ppm",
"PNM", "PBM", "PGM", "PPM"
},
new String[] {"pbm", "pgm", "ppm"},
new String[] {
// No official IANA record exists, these are conventional
"image/x-portable-pixmap",
"image/x-portable-anymap"
},
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriter",
new Class[] {ImageOutputStream.class},
new String[] {"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReaderSpi"},
true, null, null, null, null,
true, null, null, null, null
);
super(new PNMProviderInfo());
}
public boolean canEncodeImage(final ImageTypeSpecifier pType) {

View File

@ -30,7 +30,7 @@
package com.twelvemonkeys.imageio.plugins.pnm;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfo;
/**
* PNMProviderInfo.
@ -39,11 +39,35 @@ import com.twelvemonkeys.imageio.spi.ProviderInfo;
* @author last modified by $Author: harald.kuhr$
* @version $Id: PNMProviderInfo.java,v 1.0 20/03/15 harald.kuhr Exp$
*/
class PNMProviderInfo extends ProviderInfo {
// NOTE: Because the ReaderSpi and the two WriterSpis supports different formats,
// we don't use the standard ImageReaderWriterProviderInfo superclass here.
class PNMProviderInfo extends ReaderWriterProviderInfo {
public PNMProviderInfo() {
super(PNMProviderInfo.class.getPackage());
super(PNMProviderInfo.class,
new String[] {
"pnm", "pbm", "pgm", "ppm","pfm",
"PNM", "PBM", "PGM", "PPM", "PFM"
},
new String[] {"pbm", "pgm", "ppm", "pfm"},
new String[] {
// No official IANA record exists, these are conventional
"image/x-portable-pixmap",
"image/x-portable-anymap",
},
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReader",
new String[] {
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReaderSpi",
"com.twelvemonkeys.imageio.plugins.pnm.PAMImageReaderSpi"
},
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriter",
new String[] {
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriterSpi",
"com.twelvemonkeys.imageio.plugins.pnm.PAMImageWriterSpi"
},
true, // supports standard stream metadata
null, null, // native stream format name and class
null, null, // extra stream formats
true, // supports standard image metadata
null, null,
null, null // extra image metadata formats
);
}
}

View File

@ -36,7 +36,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
final class Plain16BitDecoder extends InputStream {
private final BufferedReader reader;
@ -45,7 +45,7 @@ final class Plain16BitDecoder extends InputStream {
private int leftOver = -1;
public Plain16BitDecoder(final InputStream in) {
reader = new BufferedReader(new InputStreamReader(in, Charset.forName("ASCII")));
reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.US_ASCII));
}
@Override

View File

@ -43,6 +43,7 @@ final class Plain1BitDecoder extends InputStream {
this.samplesPerRow = samplesPerRow;
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public int read() throws IOException {
// Each 0 or 1 represents one bit, whitespace is ignored. Padded to byte boundary for each row.

View File

@ -36,7 +36,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
final class Plain8BitDecoder extends InputStream {
private final BufferedReader reader;
@ -44,7 +44,7 @@ final class Plain8BitDecoder extends InputStream {
private StringTokenIterator currentLine;
public Plain8BitDecoder(final InputStream in) {
reader = new BufferedReader(new InputStreamReader(in, Charset.forName("ASCII")));
reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.US_ASCII));
}
@Override

View File

@ -34,9 +34,9 @@ import java.awt.*;
enum TupleType {
// Official:
/** B/W, but uses 1 byte (8 bits) per pixel. Black is zero (oposite of PBM) */
/** B/W, but uses 1 byte (8 bits) per pixel. Black is zero (opposite of PBM) */
BLACKANDWHITE(1, 1, PNM.MAX_VAL_1BIT, Transparency.OPAQUE),
/** B/W + bit mask, uses 2 bytes per pixel. Black is zero (oposite of PBM) */
/** B/W + bit mask, uses 2 bytes per pixel. Black is zero (opposite of PBM) */
BLACKANDWHITE_ALPHA(2, PNM.MAX_VAL_1BIT, PNM.MAX_VAL_1BIT, Transparency.BITMASK),
/** Grayscale, as PGM. */
GRAYSCALE(1, 2, PNM.MAX_VAL_16BIT, Transparency.OPAQUE),
@ -80,5 +80,4 @@ enum TupleType {
public boolean isValidMaxSample(int maxSample) {
return maxSample >= minMaxSample && maxSample <= maxMaxSample;
}
}

View File

@ -1 +1,2 @@
com.twelvemonkeys.imageio.plugins.pnm.PNMImageReaderSpi
com.twelvemonkeys.imageio.plugins.pnm.PAMImageReaderSpi

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2020, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.pnm;
import org.junit.Test;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ImageWriterSpi;
import static com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfoTest.assertClassExists;
import static com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfoTest.assertClassesExist;
import static org.junit.Assert.assertNotNull;
/**
* PAMImageReaderSpiTest.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: harald.kuhr$
* @version $Id: PAMImageReaderSpiTest.java,v 1.0 02/06/16 harald.kuhr Exp$
*/
public class PAMImageReaderSpiTest {
private final ImageReaderSpi spi = new PAMImageReaderSpi();
@Test
public void getPluginClassName() {
assertClassExists(spi.getPluginClassName(), ImageReader.class);
}
@Test
public void getImageWriterSpiNames() {
assertClassesExist(spi.getImageWriterSpiNames(), ImageWriterSpi.class);
}
@Test
public void getInputTypes() {
assertNotNull(spi.getInputTypes());
}
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2020, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.pnm;
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
import org.junit.Test;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class PAMImageReaderTest extends ImageReaderAbstractTest<PNMImageReader> {
@Override
protected ImageReaderSpi createProvider() {
return new PAMImageReaderSpi();
}
@Override
protected List<TestData> getTestData() {
return Arrays.asList(
new TestData(getClassLoaderResource("/pam/lena.pam"), new Dimension(128, 128)), // P7 RGB
new TestData(getClassLoaderResource("/pam/rgba.pam"), new Dimension(4, 2)) // P7 RGB_ALPHA
);
}
@Override
protected List<String> getFormatNames() {
return Arrays.asList(
"pam",
"PAM"
);
}
@Override
protected List<String> getSuffixes() {
return Collections.singletonList(
"pam"
);
}
@Override
protected List<String> getMIMETypes() {
return Collections.singletonList(
"image/x-portable-arbitrarymap"
);
}
@Test
public void testRGBAVsReference() throws IOException {
ImageReader reader = createReader();
TestData data = new TestData(getClassLoaderResource("/pam/rgba.pam"), new Dimension(4, 2));
reader.setInput(data.getInputStream());
BufferedImage expected = new BufferedImage(4, 2, BufferedImage.TYPE_4BYTE_ABGR);
expected.setRGB(0, 0, new Color(0, 0, 255).getRGB());
expected.setRGB(1, 0, new Color(0, 255, 0).getRGB());
expected.setRGB(2, 0, new Color(255, 0, 0).getRGB());
expected.setRGB(3, 0, new Color(255, 255, 255).getRGB());
expected.setRGB(0, 1, new Color(0, 0, 255, 127).getRGB());
expected.setRGB(1, 1, new Color(0, 255, 0, 127).getRGB());
expected.setRGB(2, 1, new Color(255, 0, 0, 127).getRGB());
expected.setRGB(3, 1, new Color(255, 255, 255, 127).getRGB());
assertImageDataEquals("Images differ from reference", expected, reader.read(0));
}
@Test
public void testXVThumbNotIncorrectlyRecognizedAsPAM() throws IOException {
assertTrue("Should recognize PAM format", provider.canDecodeInput(new TestData(getClassLoaderResource("/pam/rgba.pam"), new Dimension()).getInputStream())); // Sanity
assertFalse("Should distinguish xv-thumbs from PAM format", provider.canDecodeInput(new TestData(getClassLoaderResource("/xv-thumb/xv-thumb.xvt"), new Dimension()).getInputStream()));
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2020, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.pnm;
import com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfo;
import com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfoTest;
/**
* PAMProviderInfoTest.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: harald.kuhr$
* @version $Id: PAMProviderInfoTest.java,v 1.0 02/06/16 harald.kuhr Exp$
*/
public class PAMProviderInfoTest extends ReaderWriterProviderInfoTest {
@Override
protected ReaderWriterProviderInfo createProviderInfo() {
return new PAMProviderInfo();
}
}

View File

@ -41,9 +41,6 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class PNMImageReaderTest extends ImageReaderAbstractTest<PNMImageReader> {
@Override
protected ImageReaderSpi createProvider() {
@ -60,8 +57,6 @@ public class PNMImageReaderTest extends ImageReaderAbstractTest<PNMImageReader>
new TestData(getClassLoaderResource("/pgm/feep16.pgm"), new Dimension(24, 7)), // P2 (PGM PLAIN, 16 bits/sample)
new TestData(getClassLoaderResource("/pgm/house.l.pgm"), new Dimension(367, 241)), // P5 (PGM RAW)
new TestData(getClassLoaderResource("/ppm/lighthouse_rgb48.ppm"), new Dimension(768, 512)), // P6 (PPM RAW, 16 bits/sample)
new TestData(getClassLoaderResource("/pam/lena.pam"), new Dimension(128, 128)), // P7 RGB
new TestData(getClassLoaderResource("/pam/rgba.pam"), new Dimension(4, 2)), // P7 RGB_ALPHA
new TestData(getClassLoaderResource("/pfm/memorial.pfm"), new Dimension(512, 768)) // PF (32 bits/sample, floating point)
);
}
@ -69,15 +64,15 @@ public class PNMImageReaderTest extends ImageReaderAbstractTest<PNMImageReader>
@Override
protected List<String> getFormatNames() {
return Arrays.asList(
"pnm", "pbm", "pgm", "ppm", "pam",
"PNM", "PBM", "PGM", "PPM", "PAM"
"pnm", "pbm", "pgm", "ppm", "pfm",
"PNM", "PBM", "PGM", "PPM", "PFM"
);
}
@Override
protected List<String> getSuffixes() {
return Arrays.asList(
"pbm", "pgm", "ppm", "pam"
"pbm", "pgm", "ppm", "pfm"
);
}
@ -85,8 +80,7 @@ public class PNMImageReaderTest extends ImageReaderAbstractTest<PNMImageReader>
protected List<String> getMIMETypes() {
return Arrays.asList(
"image/x-portable-pixmap",
"image/x-portable-anymap",
"image/x-portable-arbitrarymap"
"image/x-portable-anymap"
);
}
@ -108,31 +102,4 @@ public class PNMImageReaderTest extends ImageReaderAbstractTest<PNMImageReader>
assertImageDataEquals("Images differ from reference", expected, reader.read(0));
}
@Test
public void testRGBAVsReference() throws IOException {
ImageReader reader = createReader();
TestData data = new TestData(getClassLoaderResource("/pam/rgba.pam"), new Dimension(4, 2));
reader.setInput(data.getInputStream());
BufferedImage expected = new BufferedImage(4, 2, BufferedImage.TYPE_4BYTE_ABGR);
expected.setRGB(0, 0, new Color(0, 0, 255).getRGB());
expected.setRGB(1, 0, new Color(0, 255, 0).getRGB());
expected.setRGB(2, 0, new Color(255, 0, 0).getRGB());
expected.setRGB(3, 0, new Color(255, 255, 255).getRGB());
expected.setRGB(0, 1, new Color(0, 0, 255, 127).getRGB());
expected.setRGB(1, 1, new Color(0, 255, 0, 127).getRGB());
expected.setRGB(2, 1, new Color(255, 0, 0, 127).getRGB());
expected.setRGB(3, 1, new Color(255, 255, 255, 127).getRGB());
assertImageDataEquals("Images differ from reference", expected, reader.read(0));
}
@Test
public void testXVThumbNotIncorrectlyRecognizedAsPAM() throws IOException {
assertTrue("Should recognize PAM format", provider.canDecodeInput(new TestData(getClassLoaderResource("/pam/rgba.pam"), new Dimension()).getInputStream())); // Sanity
assertFalse("Should distinguish xv-thumbs from PAM format", provider.canDecodeInput(new TestData(getClassLoaderResource("/xv-thumb/xv-thumb.xvt"), new Dimension()).getInputStream()));
}
}

View File

@ -30,9 +30,8 @@
package com.twelvemonkeys.imageio.plugins.pnm;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfo;
import com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfoTest;
/**
* PNMProviderInfoTest.
@ -41,11 +40,9 @@ import static org.junit.Assert.assertNotNull;
* @author last modified by $Author: harald.kuhr$
* @version $Id: PNMProviderInfoTest.java,v 1.0 02/06/16 harald.kuhr Exp$
*/
public class PNMProviderInfoTest {
@Test
public void vendorVersion() {
PNMProviderInfo providerInfo = new PNMProviderInfo();
assertNotNull(providerInfo.getVendorName());
assertNotNull(providerInfo.getVersion());
public class PNMProviderInfoTest extends ReaderWriterProviderInfoTest {
@Override
protected ReaderWriterProviderInfo createProviderInfo() {
return new PNMProviderInfo();
}
}