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;
|
int count = 0;
|
||||||
do {
|
do {
|
||||||
offsets[count] = imageInput.readInt();
|
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));
|
return new DCXHeader(count == offsets.length ? offsets : Arrays.copyOf(offsets, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public String toString() {
|
@Override
|
||||||
return "DCXHeader{" +
|
public String toString() {
|
||||||
|
return "DCXHeader[" +
|
||||||
"offsetTable=" + Arrays.toString(offsetTable) +
|
"offsetTable=" + Arrays.toString(offsetTable) +
|
||||||
'}';
|
']';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ import javax.imageio.event.IIOReadWarningListener;
|
|||||||
import javax.imageio.metadata.IIOMetadata;
|
import javax.imageio.metadata.IIOMetadata;
|
||||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||||
import javax.imageio.spi.ImageReaderSpi;
|
import javax.imageio.spi.ImageReaderSpi;
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -50,14 +49,16 @@ import java.nio.ByteOrder;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
public final class DCXImageReader extends ImageReaderBase {
|
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 DCXHeader header;
|
||||||
|
|
||||||
|
private int index = -1;
|
||||||
private PCXImageReader readerDelegate;
|
private PCXImageReader readerDelegate;
|
||||||
private ProgressDelegator progressDelegator;
|
private ProgressDelegator progressDelegator;
|
||||||
|
|
||||||
public DCXImageReader(final ImageReaderSpi provider) {
|
DCXImageReader(final ImageReaderSpi provider) {
|
||||||
super(provider);
|
super(provider);
|
||||||
readerDelegate = new PCXImageReader(provider);
|
readerDelegate = new PCXImageReader(provider);
|
||||||
|
|
||||||
@ -70,62 +71,73 @@ public final class DCXImageReader extends ImageReaderBase {
|
|||||||
readerDelegate.addIIOReadWarningListener(progressDelegator);
|
readerDelegate.addIIOReadWarningListener(progressDelegator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected void resetMembers() {
|
@Override
|
||||||
|
protected void resetMembers() {
|
||||||
header = null;
|
header = null;
|
||||||
|
|
||||||
|
index = -1;
|
||||||
readerDelegate.reset();
|
readerDelegate.reset();
|
||||||
installListeners();
|
installListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void dispose() {
|
@Override
|
||||||
|
public void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|
||||||
readerDelegate.dispose();
|
readerDelegate.dispose();
|
||||||
readerDelegate = null;
|
readerDelegate = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getWidth(final int imageIndex) throws IOException {
|
@Override
|
||||||
|
public int getWidth(final int imageIndex) throws IOException {
|
||||||
initIndex(imageIndex);
|
initIndex(imageIndex);
|
||||||
|
|
||||||
return readerDelegate.getWidth(0);
|
return readerDelegate.getWidth(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getHeight(final int imageIndex) throws IOException {
|
@Override
|
||||||
|
public int getHeight(final int imageIndex) throws IOException {
|
||||||
initIndex(imageIndex);
|
initIndex(imageIndex);
|
||||||
|
|
||||||
return readerDelegate.getHeight(0);
|
return readerDelegate.getHeight(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public ImageTypeSpecifier getRawImageType(final int imageIndex) throws IOException {
|
@Override
|
||||||
|
public ImageTypeSpecifier getRawImageType(final int imageIndex) throws IOException {
|
||||||
initIndex(imageIndex);
|
initIndex(imageIndex);
|
||||||
|
|
||||||
return readerDelegate.getRawImageType(0);
|
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);
|
initIndex(imageIndex);
|
||||||
|
|
||||||
return readerDelegate.getImageTypes(0);
|
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);
|
initIndex(imageIndex);
|
||||||
|
|
||||||
return readerDelegate.read(imageIndex, param);
|
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);
|
initIndex(imageIndex);
|
||||||
|
|
||||||
return readerDelegate.getImageMetadata(0);
|
return readerDelegate.getImageMetadata(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public synchronized void abort() {
|
@Override
|
||||||
|
public synchronized void abort() {
|
||||||
super.abort();
|
super.abort();
|
||||||
readerDelegate.abort();
|
readerDelegate.abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getNumImages(final boolean allowSearch) throws IOException {
|
@Override
|
||||||
|
public int getNumImages(final boolean allowSearch) throws IOException {
|
||||||
readHeader();
|
readHeader();
|
||||||
|
|
||||||
return header.getCount();
|
return header.getCount();
|
||||||
@ -134,10 +146,12 @@ public final class DCXImageReader extends ImageReaderBase {
|
|||||||
private void initIndex(final int imageIndex) throws IOException {
|
private void initIndex(final int imageIndex) throws IOException {
|
||||||
checkBounds(imageIndex);
|
checkBounds(imageIndex);
|
||||||
|
|
||||||
|
if (index != imageIndex) {
|
||||||
imageInput.seek(header.getOffset(imageIndex));
|
imageInput.seek(header.getOffset(imageIndex));
|
||||||
progressDelegator.index = imageIndex;
|
index = imageIndex;
|
||||||
readerDelegate.setInput(new SubImageInputStream(imageInput, Long.MAX_VALUE));
|
readerDelegate.setInput(new SubImageInputStream(imageInput, Long.MAX_VALUE));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void readHeader() throws IOException {
|
private void readHeader() throws IOException {
|
||||||
assertInput();
|
assertInput();
|
||||||
@ -145,7 +159,11 @@ public final class DCXImageReader extends ImageReaderBase {
|
|||||||
if (header == null) {
|
if (header == null) {
|
||||||
imageInput.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
imageInput.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
||||||
header = DCXHeader.read(imageInput);
|
header = DCXHeader.read(imageInput);
|
||||||
// System.err.println("header: " + header);
|
|
||||||
|
if (DEBUG) {
|
||||||
|
System.err.println("header: " + header);
|
||||||
|
}
|
||||||
|
|
||||||
imageInput.flushBefore(imageInput.getStreamPosition());
|
imageInput.flushBefore(imageInput.getStreamPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,8 +171,6 @@ public final class DCXImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class ProgressDelegator extends ProgressListenerBase implements IIOReadWarningListener {
|
private class ProgressDelegator extends ProgressListenerBase implements IIOReadWarningListener {
|
||||||
private int index;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void imageComplete(ImageReader source) {
|
public void imageComplete(ImageReader source) {
|
||||||
processImageComplete();
|
processImageComplete();
|
||||||
@ -190,7 +206,6 @@ public final class DCXImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
DCXImageReader reader = new DCXImageReader(null);
|
DCXImageReader reader = new DCXImageReader(null);
|
||||||
|
|
||||||
|
@ -45,7 +45,8 @@ public final class DCXImageReaderSpi extends ImageReaderSpiBase {
|
|||||||
super(new DCXProviderInfo());
|
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)) {
|
if (!(source instanceof ImageInputStream)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -69,10 +70,13 @@ public final class DCXImageReaderSpi extends ImageReaderSpiBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public ImageReader createReaderInstance(final Object extension) throws IOException {
|
@Override
|
||||||
|
public ImageReader createReaderInstance(final Object extension) throws IOException {
|
||||||
return new DCXImageReader(this);
|
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";
|
return "Multi-page PCX fax document (DCX) image reader";
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
@ -29,13 +29,21 @@
|
|||||||
package com.twelvemonkeys.imageio.plugins.dcx;
|
package com.twelvemonkeys.imageio.plugins.dcx;
|
||||||
|
|
||||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import javax.imageio.spi.ImageReaderSpi;
|
import javax.imageio.spi.ImageReaderSpi;
|
||||||
|
import javax.imageio.stream.ImageInputStream;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DCXImageReaderTest
|
* DCXImageReaderTest
|
||||||
*
|
*
|
||||||
@ -82,4 +90,20 @@ public class DCXImageReaderTest extends ImageReaderAbstractTest<DCXImageReader>
|
|||||||
"image/dcx", "image/x-dcx"
|
"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