mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 03:55:28 -04:00
Fixed DCX off-by one issue + minor optimization.
This commit is contained in:
parent
6113ae1c9c
commit
2a40bdb14b
@ -65,16 +65,16 @@ final class DCXHeader {
|
||||
int count = 0;
|
||||
do {
|
||||
offsets[count] = imageInput.readInt();
|
||||
count++;
|
||||
}
|
||||
while (offsets[count - 1] != 0 && count < offsets.length);
|
||||
while (offsets[count] != 0 && count++ < offsets.length);
|
||||
|
||||
return new DCXHeader(count == offsets.length ? offsets : Arrays.copyOf(offsets, count));
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "DCXHeader{" +
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DCXHeader[" +
|
||||
"offsetTable=" + Arrays.toString(offsetTable) +
|
||||
'}';
|
||||
']';
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,6 @@ import javax.imageio.event.IIOReadWarningListener;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -50,14 +49,16 @@ import java.nio.ByteOrder;
|
||||
import java.util.Iterator;
|
||||
|
||||
public final class DCXImageReader extends ImageReaderBase {
|
||||
// TODO: Delegate listeners with correct index!
|
||||
|
||||
final static boolean DEBUG = "true".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.imageio.plugins.dcx.debug"));
|
||||
|
||||
private DCXHeader header;
|
||||
|
||||
private int index = -1;
|
||||
private PCXImageReader readerDelegate;
|
||||
private ProgressDelegator progressDelegator;
|
||||
|
||||
public DCXImageReader(final ImageReaderSpi provider) {
|
||||
DCXImageReader(final ImageReaderSpi provider) {
|
||||
super(provider);
|
||||
readerDelegate = new PCXImageReader(provider);
|
||||
|
||||
@ -70,62 +71,73 @@ public final class DCXImageReader extends ImageReaderBase {
|
||||
readerDelegate.addIIOReadWarningListener(progressDelegator);
|
||||
}
|
||||
|
||||
@Override protected void resetMembers() {
|
||||
@Override
|
||||
protected void resetMembers() {
|
||||
header = null;
|
||||
|
||||
index = -1;
|
||||
readerDelegate.reset();
|
||||
installListeners();
|
||||
}
|
||||
|
||||
@Override public void dispose() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
|
||||
readerDelegate.dispose();
|
||||
readerDelegate = null;
|
||||
}
|
||||
|
||||
@Override public int getWidth(final int imageIndex) throws IOException {
|
||||
@Override
|
||||
public int getWidth(final int imageIndex) throws IOException {
|
||||
initIndex(imageIndex);
|
||||
|
||||
return readerDelegate.getWidth(0);
|
||||
}
|
||||
|
||||
@Override public int getHeight(final int imageIndex) throws IOException {
|
||||
@Override
|
||||
public int getHeight(final int imageIndex) throws IOException {
|
||||
initIndex(imageIndex);
|
||||
|
||||
return readerDelegate.getHeight(0);
|
||||
}
|
||||
|
||||
@Override public ImageTypeSpecifier getRawImageType(final int imageIndex) throws IOException {
|
||||
@Override
|
||||
public ImageTypeSpecifier getRawImageType(final int imageIndex) throws IOException {
|
||||
initIndex(imageIndex);
|
||||
|
||||
return readerDelegate.getRawImageType(0);
|
||||
}
|
||||
|
||||
@Override public Iterator<ImageTypeSpecifier> getImageTypes(final int imageIndex) throws IOException {
|
||||
@Override
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(final int imageIndex) throws IOException {
|
||||
initIndex(imageIndex);
|
||||
|
||||
return readerDelegate.getImageTypes(0);
|
||||
}
|
||||
|
||||
@Override public BufferedImage read(final int imageIndex, final ImageReadParam param) throws IOException {
|
||||
@Override
|
||||
public BufferedImage read(final int imageIndex, final ImageReadParam param) throws IOException {
|
||||
initIndex(imageIndex);
|
||||
|
||||
return readerDelegate.read(imageIndex, param);
|
||||
}
|
||||
|
||||
@Override public IIOMetadata getImageMetadata(final int imageIndex) throws IOException {
|
||||
@Override
|
||||
public IIOMetadata getImageMetadata(final int imageIndex) throws IOException {
|
||||
initIndex(imageIndex);
|
||||
|
||||
return readerDelegate.getImageMetadata(0);
|
||||
}
|
||||
|
||||
@Override public synchronized void abort() {
|
||||
@Override
|
||||
public synchronized void abort() {
|
||||
super.abort();
|
||||
readerDelegate.abort();
|
||||
}
|
||||
|
||||
@Override public int getNumImages(final boolean allowSearch) throws IOException {
|
||||
@Override
|
||||
public int getNumImages(final boolean allowSearch) throws IOException {
|
||||
readHeader();
|
||||
|
||||
return header.getCount();
|
||||
@ -134,9 +146,11 @@ public final class DCXImageReader extends ImageReaderBase {
|
||||
private void initIndex(final int imageIndex) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
|
||||
imageInput.seek(header.getOffset(imageIndex));
|
||||
progressDelegator.index = imageIndex;
|
||||
readerDelegate.setInput(new SubImageInputStream(imageInput, Long.MAX_VALUE));
|
||||
if (index != imageIndex) {
|
||||
imageInput.seek(header.getOffset(imageIndex));
|
||||
index = imageIndex;
|
||||
readerDelegate.setInput(new SubImageInputStream(imageInput, Long.MAX_VALUE));
|
||||
}
|
||||
}
|
||||
|
||||
private void readHeader() throws IOException {
|
||||
@ -145,7 +159,11 @@ public final class DCXImageReader extends ImageReaderBase {
|
||||
if (header == null) {
|
||||
imageInput.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
||||
header = DCXHeader.read(imageInput);
|
||||
// System.err.println("header: " + header);
|
||||
|
||||
if (DEBUG) {
|
||||
System.err.println("header: " + header);
|
||||
}
|
||||
|
||||
imageInput.flushBefore(imageInput.getStreamPosition());
|
||||
}
|
||||
|
||||
@ -153,11 +171,9 @@ public final class DCXImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
private class ProgressDelegator extends ProgressListenerBase implements IIOReadWarningListener {
|
||||
private int index;
|
||||
|
||||
@Override
|
||||
public void imageComplete(ImageReader source) {
|
||||
processImageComplete();
|
||||
processImageComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -190,7 +206,6 @@ public final class DCXImageReader extends ImageReaderBase {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
DCXImageReader reader = new DCXImageReader(null);
|
||||
|
||||
|
@ -45,7 +45,8 @@ public final class DCXImageReaderSpi extends ImageReaderSpiBase {
|
||||
super(new DCXProviderInfo());
|
||||
}
|
||||
|
||||
@Override public boolean canDecodeInput(final Object source) throws IOException {
|
||||
@Override
|
||||
public boolean canDecodeInput(final Object source) throws IOException {
|
||||
if (!(source instanceof ImageInputStream)) {
|
||||
return false;
|
||||
}
|
||||
@ -64,15 +65,18 @@ public final class DCXImageReaderSpi extends ImageReaderSpiBase {
|
||||
stream.setByteOrder(originalByteOrder);
|
||||
}
|
||||
}
|
||||
finally{
|
||||
finally {
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public ImageReader createReaderInstance(final Object extension) throws IOException {
|
||||
@Override
|
||||
public ImageReader createReaderInstance(final Object extension) throws IOException {
|
||||
return new DCXImageReader(this);
|
||||
}
|
||||
|
||||
@Override public String getDescription(final Locale locale) {
|
||||
@Override
|
||||
public String getDescription(final Locale locale) {
|
||||
return "Multi-page PCX fax document (DCX) image reader";
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
@ -29,13 +29,21 @@
|
||||
package com.twelvemonkeys.imageio.plugins.dcx;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
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.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* DCXImageReaderTest
|
||||
*
|
||||
@ -82,4 +90,20 @@ public class DCXImageReaderTest extends ImageReaderAbstractTest<DCXImageReader>
|
||||
"image/dcx", "image/x-dcx"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCount() throws IOException {
|
||||
try (ImageInputStream input = ImageIO.createImageInputStream(getClassLoaderResource("/dcx/input.dcx"))) {
|
||||
DCXImageReader reader = createReader();
|
||||
reader.setInput(input);
|
||||
|
||||
assertEquals(1, reader.getNumImages(true));
|
||||
assertEquals(70, reader.getWidth(0));
|
||||
assertEquals(46, reader.getHeight(0));
|
||||
|
||||
BufferedImage image = reader.read(0);
|
||||
|
||||
assertNotNull(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user