/*
* $Id$
*
* Copyright (c) 2009 by Joel Uckelman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License (LGPL) as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, copies are available
* at http://www.opensource.org.
*/
package VASSAL.tools.image;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
class PNGChunkSkipInputStream extends InputStream {
public PNGChunkSkipInputStream(Set<Integer> skip, InputStream in)
throws IOException {
this.skip = skip;
this.in = new DataInputStream(in);
if (!PNGDecoder.decodeSignature(this.in)) throw new IOException();
bout = new ByteArrayOutputStream();
out = new DataOutputStream(bout);
out.writeLong(PNGDecoder.sig);
flipBuffer();
}
protected final Set<Integer> skip;
protected final DataInputStream in;
protected ByteArrayInputStream bin;
protected final ByteArrayOutputStream bout;
protected final DataOutputStream out;
protected boolean seenIEND = false;
public int available() throws IOException {
return bin.available();
}
public void close() throws IOException {
in.close();
}
public void mark(int readlimit) {}
public boolean markSupported() {
return false;
}
public int read() throws IOException {
final byte[] b = new byte[1];
return read(b) == -1 ? -1 : b[0];
}
public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
public int read(byte[] b, int off, int len) throws IOException {
int ret = bin.read(b, off, len);
if (ret == -1 && !seenIEND) {
PNGDecoder.Chunk ch;
do {
ch = PNGDecoder.decodeChunk(in);
if (ch.type == PNGDecoder.IEND) seenIEND = true;
} while (skip.contains(ch.type));
encodeChunk(ch);
flipBuffer();
ret = bin.read(b, off, len);
}
return ret;
}
protected void encodeChunk(PNGDecoder.Chunk ch) throws IOException {
// write chunk data length
out.writeInt(ch.data.length);
// write chunk type
out.writeInt(ch.type);
// write data
out.write(ch.data);
// write checksum
out.writeInt((int) ch.crc);
}
protected void flipBuffer() throws IOException {
out.flush();
bin = new ByteArrayInputStream(bout.toByteArray());
bout.reset();
}
public void reset() throws IOException {
throw new IOException();
}
public long skip(long n) throws IOException {
throw new IOException();
}
/*
public static void main(String[] args) throws Exception {
final InputStream fin = new PNGChunkSkipInputStream(
java.util.Collections.singleton(PNGDecoder.iTXt),
new java.io.FileInputStream("iTXt.png")
);
VASSAL.tools.io.IOUtils.copy(fin, System.out);
fin.close();
}
*/
}