mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-02 19:15:29 -04:00
TMC-IOENC: Decoder implementation clean-up.
This commit is contained in:
parent
cd6e9ebbf5
commit
d1f00ce817
@ -50,13 +50,13 @@ abstract class AbstractRLEDecoder implements Decoder {
|
|||||||
protected int dstY;
|
protected int dstY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RLEDecoder. As RLE encoded BMP's may contain x and y deltas,
|
* Creates an RLEDecoder. As RLE encoded BMPs may contain x and y deltas,
|
||||||
* etc, we need to know height and width of the image.
|
* etc, we need to know height and width of the image.
|
||||||
*
|
*
|
||||||
* @param pWidth width of the image
|
* @param pWidth width of the image
|
||||||
* @param pHeight heigth of the image
|
* @param pHeight height of the image
|
||||||
*/
|
*/
|
||||||
AbstractRLEDecoder(int pWidth, int pHeight) {
|
AbstractRLEDecoder(final int pWidth, final int pHeight) {
|
||||||
width = pWidth;
|
width = pWidth;
|
||||||
int bytesPerRow = width;
|
int bytesPerRow = width;
|
||||||
int mod = bytesPerRow % 4;
|
int mod = bytesPerRow % 4;
|
||||||
@ -77,32 +77,32 @@ abstract class AbstractRLEDecoder implements Decoder {
|
|||||||
/**
|
/**
|
||||||
* Decodes one full row of image data.
|
* Decodes one full row of image data.
|
||||||
*
|
*
|
||||||
* @param pStream the input stream containint RLE data
|
* @param pStream the input stream containing RLE data
|
||||||
*
|
*
|
||||||
* @throws IOException if an I/O related exception ocurs while reading
|
* @throws IOException if an I/O related exception occurs while reading
|
||||||
*/
|
*/
|
||||||
protected abstract void decodeRow(InputStream pStream) throws IOException;
|
protected abstract void decodeRow(final InputStream pStream) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes as much data as possible, from the stream into the buffer.
|
* Decodes as much data as possible, from the stream into the buffer.
|
||||||
*
|
*
|
||||||
* @param pStream the input stream containing RLE data
|
* @param stream the input stream containing RLE data
|
||||||
* @param pBuffer the buffer to decode the data to
|
* @param buffer the buffer to decode the data to
|
||||||
*
|
*
|
||||||
* @return the number of bytes decoded from the stream, to the buffer
|
* @return the number of bytes decoded from the stream, to the buffer
|
||||||
*
|
*
|
||||||
* @throws IOException if an I/O related exception ocurs while reading
|
* @throws IOException if an I/O related exception ocurs while reading
|
||||||
*/
|
*/
|
||||||
public final int decode(InputStream pStream, ByteBuffer pBuffer) throws IOException {
|
public final int decode(final InputStream stream, final ByteBuffer buffer) throws IOException {
|
||||||
while (pBuffer.hasRemaining() && dstY >= 0) {
|
while (buffer.hasRemaining() && dstY >= 0) {
|
||||||
// NOTE: Decode only full rows, don't decode if y delta
|
// NOTE: Decode only full rows, don't decode if y delta
|
||||||
if (dstX == 0 && srcY == dstY) {
|
if (dstX == 0 && srcY == dstY) {
|
||||||
decodeRow(pStream);
|
decodeRow(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
int length = Math.min(row.length - dstX, pBuffer.remaining());
|
int length = Math.min(row.length - dstX, buffer.remaining());
|
||||||
// System.arraycopy(row, dstX, pBuffer, decoded, length);
|
// System.arraycopy(row, dstX, buffer, decoded, length);
|
||||||
pBuffer.put(row, 0, length);
|
buffer.put(row, 0, length);
|
||||||
dstX += length;
|
dstX += length;
|
||||||
// decoded += length;
|
// decoded += length;
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ abstract class AbstractRLEDecoder implements Decoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pBuffer.position();
|
return buffer.position();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -131,7 +131,7 @@ abstract class AbstractRLEDecoder implements Decoder {
|
|||||||
*
|
*
|
||||||
* @throws EOFException if {@code pByte} is negative
|
* @throws EOFException if {@code pByte} is negative
|
||||||
*/
|
*/
|
||||||
protected static int checkEOF(int pByte) throws EOFException {
|
protected static int checkEOF(final int pByte) throws EOFException {
|
||||||
if (pByte < 0) {
|
if (pByte < 0) {
|
||||||
throw new EOFException("Premature end of file");
|
throw new EOFException("Premature end of file");
|
||||||
}
|
}
|
||||||
|
@ -164,23 +164,23 @@ public final class Base64Decoder implements Decoder {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int decode(final InputStream pStream, final ByteBuffer pBuffer) throws IOException {
|
public int decode(final InputStream stream, final ByteBuffer buffer) throws IOException {
|
||||||
do {
|
do {
|
||||||
int k = 72;
|
int k = 72;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i + 4 < k; i += 4) {
|
for (i = 0; i + 4 < k; i += 4) {
|
||||||
if(!decodeAtom(pStream, pBuffer, 4)) {
|
if(!decodeAtom(stream, buffer, 4)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!decodeAtom(pStream, pBuffer, k - i)) {
|
if (!decodeAtom(stream, buffer, k - i)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (pBuffer.remaining() > 54); // 72 char lines should produce no more than 54 bytes
|
while (buffer.remaining() > 54); // 72 char lines should produce no more than 54 bytes
|
||||||
|
|
||||||
return pBuffer.position();
|
return buffer.position();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,11 +48,11 @@ import java.nio.ByteBuffer;
|
|||||||
public interface Decoder {
|
public interface Decoder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes up to {@code pBuffer.length} bytes from the given input stream,
|
* Decodes up to {@code buffer.length} bytes from the given input stream,
|
||||||
* into the given buffer.
|
* into the given buffer.
|
||||||
*
|
*
|
||||||
* @param pStream the input stream to decode data from
|
* @param stream the input stream to decode data from
|
||||||
* @param pBuffer buffer to store the read data
|
* @param buffer buffer to store the read data
|
||||||
*
|
*
|
||||||
* @return the total number of bytes read into the buffer, or {@code 0}
|
* @return the total number of bytes read into the buffer, or {@code 0}
|
||||||
* if there is no more data because the end of the stream has been reached.
|
* if there is no more data because the end of the stream has been reached.
|
||||||
@ -61,5 +61,5 @@ public interface Decoder {
|
|||||||
* @throws IOException if an I/O error occurs
|
* @throws IOException if an I/O error occurs
|
||||||
* @throws java.io.EOFException if a premature end-of-file is encountered
|
* @throws java.io.EOFException if a premature end-of-file is encountered
|
||||||
*/
|
*/
|
||||||
int decode(InputStream pStream, ByteBuffer pBuffer) throws IOException;
|
int decode(InputStream stream, ByteBuffer buffer) throws IOException;
|
||||||
}
|
}
|
||||||
|
@ -47,9 +47,6 @@ public final class DecoderStream extends FilterInputStream {
|
|||||||
protected final ByteBuffer buffer;
|
protected final ByteBuffer buffer;
|
||||||
protected final Decoder decoder;
|
protected final Decoder decoder;
|
||||||
|
|
||||||
// TODO: Consider replacing the wrapped input stream with a channel like this
|
|
||||||
// ReadableByteChannel inChannel = Channels.newChannel(stream);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new decoder stream and chains it to the
|
* Creates a new decoder stream and chains it to the
|
||||||
* input stream specified by the {@code pStream} argument.
|
* input stream specified by the {@code pStream} argument.
|
||||||
@ -77,6 +74,7 @@ public final class DecoderStream extends FilterInputStream {
|
|||||||
*/
|
*/
|
||||||
public DecoderStream(final InputStream pStream, final Decoder pDecoder, final int pBufferSize) {
|
public DecoderStream(final InputStream pStream, final Decoder pDecoder, final int pBufferSize) {
|
||||||
super(pStream);
|
super(pStream);
|
||||||
|
|
||||||
decoder = pDecoder;
|
decoder = pDecoder;
|
||||||
buffer = ByteBuffer.allocate(pBufferSize);
|
buffer = ByteBuffer.allocate(pBufferSize);
|
||||||
buffer.flip();
|
buffer.flip();
|
||||||
|
@ -78,20 +78,20 @@ public final class PackBits16Decoder implements Decoder {
|
|||||||
/**
|
/**
|
||||||
* Decodes bytes from the given input stream, to the given buffer.
|
* Decodes bytes from the given input stream, to the given buffer.
|
||||||
*
|
*
|
||||||
* @param pStream the stream to decode from
|
* @param stream the stream to decode from
|
||||||
* @param pBuffer a byte array, minimum 128 (or 129 if no-op is disabled)
|
* @param buffer a byte array, minimum 128 (or 129 if no-op is disabled)
|
||||||
* bytes long
|
* bytes long
|
||||||
* @return The number of bytes decoded
|
* @return The number of bytes decoded
|
||||||
*
|
*
|
||||||
* @throws java.io.IOException
|
* @throws java.io.IOException
|
||||||
*/
|
*/
|
||||||
public int decode(final InputStream pStream, final ByteBuffer pBuffer) throws IOException {
|
public int decode(final InputStream stream, final ByteBuffer buffer) throws IOException {
|
||||||
if (reachedEOF) {
|
if (reachedEOF) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int read = 0;
|
int read = 0;
|
||||||
final int max = pBuffer.capacity();
|
final int max = buffer.capacity();
|
||||||
|
|
||||||
while (read < max) {
|
while (read < max) {
|
||||||
int n;
|
int n;
|
||||||
@ -103,7 +103,7 @@ public final class PackBits16Decoder implements Decoder {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Start new run
|
// Start new run
|
||||||
int b = pStream.read();
|
int b = stream.read();
|
||||||
if (b < 0) {
|
if (b < 0) {
|
||||||
reachedEOF = true;
|
reachedEOF = true;
|
||||||
break;
|
break;
|
||||||
@ -127,18 +127,18 @@ public final class PackBits16Decoder implements Decoder {
|
|||||||
if (n >= 0) {
|
if (n >= 0) {
|
||||||
// Copy next n + 1 shorts literally
|
// Copy next n + 1 shorts literally
|
||||||
int len = 2 * (n + 1);
|
int len = 2 * (n + 1);
|
||||||
readFully(pStream, pBuffer, len);
|
readFully(stream, buffer, len);
|
||||||
read += len;
|
read += len;
|
||||||
}
|
}
|
||||||
// Allow -128 for compatibility, see above
|
// Allow -128 for compatibility, see above
|
||||||
else if (disableNoop || n != -128) {
|
else if (disableNoop || n != -128) {
|
||||||
// Replicate the next short -n + 1 times
|
// Replicate the next short -n + 1 times
|
||||||
byte value1 = readByte(pStream);
|
byte value1 = readByte(stream);
|
||||||
byte value2 = readByte(pStream);
|
byte value2 = readByte(stream);
|
||||||
|
|
||||||
for (int i = -n + 1; i > 0; i--) {
|
for (int i = -n + 1; i > 0; i--) {
|
||||||
pBuffer.put(value1);
|
buffer.put(value1);
|
||||||
pBuffer.put(value2);
|
buffer.put(value2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else NOOP (-128)
|
// else NOOP (-128)
|
||||||
|
@ -93,19 +93,19 @@ public final class PackBitsDecoder implements Decoder {
|
|||||||
/**
|
/**
|
||||||
* Decodes bytes from the given input stream, to the given buffer.
|
* Decodes bytes from the given input stream, to the given buffer.
|
||||||
*
|
*
|
||||||
* @param pStream the stream to decode from
|
* @param stream the stream to decode from
|
||||||
* @param pBuffer a byte array, minimum 128 (or 129 if no-op is disabled) bytes long
|
* @param buffer a byte array, minimum 128 (or 129 if no-op is disabled) bytes long
|
||||||
* @return The number of bytes decoded
|
* @return The number of bytes decoded
|
||||||
*
|
*
|
||||||
* @throws java.io.IOException
|
* @throws java.io.IOException
|
||||||
*/
|
*/
|
||||||
public int decode(final InputStream pStream, final ByteBuffer pBuffer) throws IOException {
|
public int decode(final InputStream stream, final ByteBuffer buffer) throws IOException {
|
||||||
if (reachedEOF) {
|
if (reachedEOF) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Don't decode more than single runs, because some writers add pad bytes inside the stream...
|
// TODO: Don't decode more than single runs, because some writers add pad bytes inside the stream...
|
||||||
while (pBuffer.hasRemaining()) {
|
while (buffer.hasRemaining()) {
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (splitRun) {
|
if (splitRun) {
|
||||||
@ -115,7 +115,7 @@ public final class PackBitsDecoder implements Decoder {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Start new run
|
// Start new run
|
||||||
int b = pStream.read();
|
int b = stream.read();
|
||||||
if (b < 0) {
|
if (b < 0) {
|
||||||
reachedEOF = true;
|
reachedEOF = true;
|
||||||
break;
|
break;
|
||||||
@ -124,12 +124,12 @@ public final class PackBitsDecoder implements Decoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Split run at or before max
|
// Split run at or before max
|
||||||
if (n >= 0 && n + 1 > pBuffer.remaining()) {
|
if (n >= 0 && n + 1 > buffer.remaining()) {
|
||||||
leftOfRun = n;
|
leftOfRun = n;
|
||||||
splitRun = true;
|
splitRun = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (n < 0 && -n + 1 > pBuffer.remaining()) {
|
else if (n < 0 && -n + 1 > buffer.remaining()) {
|
||||||
leftOfRun = n;
|
leftOfRun = n;
|
||||||
splitRun = true;
|
splitRun = true;
|
||||||
break;
|
break;
|
||||||
@ -138,15 +138,15 @@ public final class PackBitsDecoder implements Decoder {
|
|||||||
try {
|
try {
|
||||||
if (n >= 0) {
|
if (n >= 0) {
|
||||||
// Copy next n + 1 bytes literally
|
// Copy next n + 1 bytes literally
|
||||||
readFully(pStream, pBuffer, n + 1);
|
readFully(stream, buffer, n + 1);
|
||||||
}
|
}
|
||||||
// Allow -128 for compatibility, see above
|
// Allow -128 for compatibility, see above
|
||||||
else if (disableNoop || n != -128) {
|
else if (disableNoop || n != -128) {
|
||||||
// Replicate the next byte -n + 1 times
|
// Replicate the next byte -n + 1 times
|
||||||
byte value = readByte(pStream);
|
byte value = readByte(stream);
|
||||||
|
|
||||||
for (int i = -n + 1; i > 0; i--) {
|
for (int i = -n + 1; i > 0; i--) {
|
||||||
pBuffer.put(value);
|
buffer.put(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else NOOP (-128)
|
// else NOOP (-128)
|
||||||
@ -156,7 +156,7 @@ public final class PackBitsDecoder implements Decoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pBuffer.position();
|
return buffer.position();
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte readByte(final InputStream pStream) throws IOException {
|
static byte readByte(final InputStream pStream) throws IOException {
|
||||||
|
@ -32,7 +32,7 @@ import java.io.InputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements 4 bit RLE decoding as specifed by in the Windows BMP (aka DIB) file format.
|
* Implements 4 bit RLE decoding as specified by in the Windows BMP (aka DIB) file format.
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||||
@ -41,7 +41,7 @@ import java.io.IOException;
|
|||||||
// TODO: Move to other package or make public
|
// TODO: Move to other package or make public
|
||||||
final class RLE4Decoder extends AbstractRLEDecoder {
|
final class RLE4Decoder extends AbstractRLEDecoder {
|
||||||
|
|
||||||
public RLE4Decoder(int pWidth, int pHeight) {
|
public RLE4Decoder(final int pWidth, final int pHeight) {
|
||||||
super((pWidth + 1) / 2, pHeight);
|
super((pWidth + 1) / 2, pHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ import java.io.InputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements 8 bit RLE decoding as specifed by in the Windows BMP (aka DIB) file format.
|
* Implements 8 bit RLE decoding as specified by in the Windows BMP (aka DIB) file format.
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||||
@ -41,7 +41,7 @@ import java.io.IOException;
|
|||||||
// TODO: Move to other package or make public
|
// TODO: Move to other package or make public
|
||||||
final class RLE8Decoder extends AbstractRLEDecoder {
|
final class RLE8Decoder extends AbstractRLEDecoder {
|
||||||
|
|
||||||
public RLE8Decoder(int pWidth, int pHeight) {
|
public RLE8Decoder(final int pWidth, final int pHeight) {
|
||||||
super(pWidth, pHeight);
|
super(pWidth, pHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,17 +76,17 @@ final class InflateDecoder implements Decoder {
|
|||||||
buffer = new byte[1024];
|
buffer = new byte[1024];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int decode(final InputStream pStream, final ByteBuffer pBuffer) throws IOException {
|
public int decode(final InputStream stream, final ByteBuffer buffer) throws IOException {
|
||||||
try {
|
try {
|
||||||
int decoded;
|
int decoded;
|
||||||
|
|
||||||
while ((decoded = inflater.inflate(pBuffer.array(), pBuffer.arrayOffset(), pBuffer.capacity())) == 0) {
|
while ((decoded = inflater.inflate(buffer.array(), buffer.arrayOffset(), buffer.capacity())) == 0) {
|
||||||
if (inflater.finished() || inflater.needsDictionary()) {
|
if (inflater.finished() || inflater.needsDictionary()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inflater.needsInput()) {
|
if (inflater.needsInput()) {
|
||||||
fill(pStream);
|
fill(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user