/*
* ImageI/O-Ext - OpenSource Java Image translation Library
* http://www.geo-solutions.it/
* https://imageio-ext.dev.java.net/
* (C) 2007 - 2008, GeoSolutions
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* 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
* Lesser General Public License for more details.
*/
package org.esa.s1tbx.io;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.stream.ImageOutputStreamImpl;
import java.io.File;
import java.io.IOException;
import java.nio.ByteOrder;
/**
* An implementation of {@link ImageOutputStream} that take its output on a
* {@link File}.
*
* @author Daniele Romagnoli, GeoSolutions
* @author Simone Giannecchini, GeoSolutions
*/
public final class FileImageOutputStreamExtImpl extends ImageOutputStreamImpl
implements ImageOutputStream {
protected EnhancedRandomAccessFile eraf;
protected File file;
private boolean isClosed = false;
public static ImageOutputStream createOutputStream(final File file) throws IOException {
return new FileImageOutputStreamExtImpl(file);
//return new FileImageOutputStream(file);
}
/**
* A constructor which accepts a File as input.
*
* @param file eraf
* @throws IOException
*/
public FileImageOutputStreamExtImpl(File file)
throws IOException {
this.file = file;
eraf = new EnhancedRandomAccessFile(file, "rw");
// NOTE: this must be done accordingly to what ImageInputStreamImpl
// does, otherwise some ImageREader subclasses might not work.
this.eraf.setByteOrder(ByteOrder.BIG_ENDIAN);
}
/**
* A constructor which accepts a File as input.
*
* @param file eraf
* @param bufSize
* @throws IOException
*/
public FileImageOutputStreamExtImpl(File file, int bufSize)
throws IOException {
this.file = file;
eraf = new EnhancedRandomAccessFile(file, "rw", bufSize);
// NOTE: this must be done accordingly to what ImageInputStreamImpl
// does, otherwise some ImageREader subclasses might not work.
this.eraf.setByteOrder(ByteOrder.BIG_ENDIAN);
}
@Override
public int read() throws IOException {
//checkClosed();
bitOffset = 0;
int val = eraf.read();
if (val != -1) {
++streamPos;
}
return val;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
//checkClosed();
bitOffset = 0;
int nbytes = eraf.read(b, off, len);
if (nbytes != -1) {
streamPos += nbytes;
}
return nbytes;
}
@Override
public void write(int b) throws IOException {
//checkClosed();
flushBits();
eraf.write(b);
++streamPos;
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
//checkClosed();
flushBits();
eraf.writeBytes(b, off, len);
streamPos += len;
}
@Override
public long length() {
try {
//checkClosed();
return eraf.length();
} catch (IOException e) {
return -1L;
}
}
/**
* Sets the current stream position and resets the bit offset to 0. It is
* legal to seeking past the end of the eraf; an <code>EOFException</code>
* will be thrown only if a read is performed. The eraf length will not be
* increased until a write is performed.
*
* @throws IndexOutOfBoundsException if <code>pos</code> is smaller than the flushed
* position.
* @throws IOException if any other I/O error occurs.
*/
@Override
public void seek(long pos) throws IOException {
//checkClosed();
if (pos < flushedPos) {
throw new IndexOutOfBoundsException("IndexOutOfBounds pos < flushedPos! " + pos + " < " + flushedPos);
}
bitOffset = 0;
streamPos = eraf.seek(pos);
}
/**
* Closes the underlying {@link EnhancedRandomAccessFile}.
*
* @throws IOException in case something bad happens.
*/
@Override
public void close() throws IOException {
try {
if (!isClosed) {
super.close();
eraf.close();
}
} finally {
isClosed = true;
}
}
/**
* Retrieves the {@link File} we are connected to.
*/
public File getFile() {
return file;
}
/**
* Disposes this {@link FileImageInputStreamExtImpl} by closing its
* underlying {@link EnhancedRandomAccessFile}.
*/
public void dispose() {
try {
close();
} catch (IOException e) {
//
}
}
/**
* Provides a simple description for this {@link ImageOutputStream}.
*
* @return a simple description for this {@link ImageOutputStream}.
*/
@Override
public String toString() {
return "FileImageOutputStreamExtImpl which points to " + this.file.toString();
}
}