/* ImageInputStream.java
   Copyright (C) 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.imageio.stream;

import java.io.DataInput;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteOrder;


/**
 * An input stream for use by {@link javax.imageio.ImageReader
 * ImageReaders}.
 *
 * @since 1.4
 *
 * @author Sascha Brawer (brawer@dandelis.ch)
 */
public interface ImageInputStream
  extends DataInput
{
  void setByteOrder(ByteOrder order);

  ByteOrder getByteOrder();
  
  int read()
    throws IOException;

  int read(byte[] b)
    throws IOException;

  int read(byte[] b, int offset, int length)
    throws IOException;


  /**
   * Reads up to a specified number of bytes, and modifies a
   * {@link IIOByteBuffer} to hold the read data.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   *
   * @param buf an <code>IIOByteBuffer</code> that will hold the read
   * data.
   *
   * @param numBytes the maximum number of bytes to read.
   *
   * @throws IndexOutOfBoundsException if <code>numBytes</code> is
   * negative.
   *
   * @throws NullPointerException if <code>buf</code> is
   * <code>null</code>.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   */
  void readBytes(IIOByteBuffer buf, int numBytes)
    throws IOException;


  /**
   * Reads a byte and checks whether or not its value is zero.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before the byte is read.
   *
   * @throws EOFException if the input stream is at its end.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readBit()
   * @see #readByte()
   * @see #readFully(byte[], int, int)
   */
  boolean readBoolean()
    throws IOException;


  /**
   * Reads a signed byte.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   *
   * @throws EOFException if the input stream is at its end.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readUnsignedByte()
   * @see #readFully(byte[], int, int)
   */
  byte readByte()
    throws IOException;


  /**
   * Reads an unsigned byte.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   *
   * @throws EOFException if the input stream is at its end.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readByte()
   * @see #readFully(byte[], int, int)
   */
  int readUnsignedByte()
    throws IOException;


  /**
   * Reads an signed 16-bit integer. If necessary, the value gets
   * converted from the stream&#x2019;s {@linkplain #getByteOrder()
   * current byte order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @throws EOFException if the input stream ends before all two
   * bytes were read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readUnsignedShort()
   * @see #readChar()
   * @see #readFully(short[], int, int)
   */
  short readShort()
    throws IOException;


  /**
   * Reads an unsigned 16-bit integer. If necessary, the value gets
   * converted from the stream&#x2019;s {@linkplain #getByteOrder()
   * current byte order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * <p>This method does the same as {@link #readChar()}.
   *
   * @throws EOFException if the input stream ends before all two
   * bytes were read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readShort()
   * @see #readChar()
   * @see #readFully(char[], int, int)
   */
  int readUnsignedShort()
    throws IOException;


  /**
   * Reads an unsigned 16-bit integer. If necessary, the value gets
   * converted from the stream&#x2019;s {@linkplain #getByteOrder()
   * current byte order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * <p>This method does the same as {@link #readUnsignedShort()}.
   *
   * @throws EOFException if the input stream ends before all two
   * bytes were read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readFully(char[], int, int)
   */
  char readChar()
    throws IOException;


  /**
   * Reads a signed 32-bit integer. If necessary, the value gets
   * converted from the stream&#x2019;s {@linkplain #getByteOrder()
   * current byte order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @throws EOFException if the input stream ends before all four
   * bytes were read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readUnsignedInt()
   * @see #readFully(int[], int, int)
   */
  int readInt()
    throws IOException;


  /**
   * Reads an unsigned 32-bit integer. If necessary, the value gets
   * converted from the stream&#x2019;s {@linkplain #getByteOrder()
   * current byte order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @throws EOFException if the input stream ends before all four
   * bytes were read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readInt()
   * @see #readFully(int[], int, int)
   */
  long readUnsignedInt()
    throws IOException;


  /**
   * Reads a signed 64-bit integer. If necessary, the value gets
   * converted from the stream&#x2019;s {@linkplain #getByteOrder()
   * current byte order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @throws EOFException if the input stream ends before all eight
   * bytes were read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readFully(long[], int, int)
   */
  long readLong()
    throws IOException;


  /**
   * Reads an IEEE 32-bit single-precision floating point number. If
   * necessary, the value gets converted from the stream&#x2019;s
   * {@linkplain #getByteOrder() current byte order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @throws EOFException if the input stream ends before all four
   * bytes were read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readFully(float[], int, int)
   */
  float readFloat()
    throws IOException;


  /**
   * Reads an IEEE 64-bit double-precision floating point number. If
   * necessary, the value gets converted from the stream&#x2019;s
   * {@linkplain #getByteOrder() current byte order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @throws EOFException if the input stream ends before all eight
   * bytes were read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readFully(double[], int, int)
   */
  double readDouble()
    throws IOException;

  String readLine()
    throws IOException;

  String readUTF()
    throws IOException;


  /**
   * Reads a sequence of signed 8-bit integers into a
   * <code>byte[]</code> array.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @param b an array for storing the read values.
   *
   * @param offset the index of the first element in <code>b</code>
   * that will hold read data.
   *
   * @param numBytes the number of bytes to read.
   *
   * @throws IndexOutOfBoundsException if <code>offset</code> or
   * <code>numBytes</code> is negative, or if <code>offset +
   * numBytes</code> exceeds <code>b.length</code>.
   *
   * @throws NullPointerException if <code>b</code> is
   * <code>null</code>.
   *
   * @throws EOFException if the input stream ends before all content
   * was read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readByte()
   */
  void readFully(byte[] b, int offset, int numBytes)
    throws IOException;


  /**
   * Reads a sequence of signed 8-bit integers into a
   * <code>byte[]</code> array.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @param b an array for storing the read values.
   *
   * @throws NullPointerException if <code>b</code> is
   * <code>null</code>.
   *
   * @throws EOFException if the input stream ends before all content
   * was read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readByte()
   * @see #readFully(byte[], int, int)
   */
  void readFully(byte[] b)
    throws IOException;


  /**
   * Reads a sequence of signed 16-bit integers into a
   * <code>short[]</code> array.  If necessary, values are converted
   * from the stream&#x2019;s {@linkplain #getByteOrder() current byte
   * order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @param s an array for storing the read values.
   *
   * @param offset the index of the first element in <code>s</code>
   * that will hold read data.
   *
   * @param numShorts the number of signed 16-bit integers to read
   * (which is one half of the number of bytes).
   *
   * @throws IndexOutOfBoundsException if <code>offset</code> or
   * <code>numShorts</code> is negative, or if <code>offset +
   * numShorts</code> exceeds <code>s.length</code>.
   *
   * @throws NullPointerException if <code>s</code> is
   * <code>null</code>.
   *
   * @throws EOFException if the input stream ends before all content
   * was read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readShort()
   */
  void readFully(short[] s, int offset, int numShorts)
    throws IOException;


  /**
   * Reads a sequence of unsigned 16-bit integers into a
   * <code>char[]</code> array.  If necessary, values are converted
   * from the stream&#x2019;s {@linkplain #getByteOrder() current byte
   * order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @param c an array for storing the read values.
   *
   * @param offset the index of the first element in <code>c</code>
   * that will hold read data.
   *
   * @param numChars the number of unsigned 16-bit integers to read
   * (which is one half of the number of bytes).
   *
   * @throws IndexOutOfBoundsException if <code>offset</code> or
   * <code>numChars</code> is negative, or if <code>offset +
   * numChars</code> exceeds <code>c.length</code>.
   *
   * @throws NullPointerException if <code>c</code> is
   * <code>null</code>.
   *
   * @throws EOFException if the input stream ends before all content
   * was read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readChar()
   */
  void readFully(char[] c, int offset, int numChars)
    throws IOException;


  /**
   * Reads a sequence of signed 32-bit integers into a
   * <code>long[]</code> array.  If necessary, values are converted
   * from the stream&#x2019;s {@linkplain #getByteOrder() current byte
   * order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @param i an array for storing the read values.
   *
   * @param offset the index of the first element in <code>i</code>
   * that will hold read data.
   *
   * @param numInts the number of signed 32-bit integers to read
   * (which is one fourth of the number of bytes).
   *
   * @throws IndexOutOfBoundsException if <code>offset</code> or
   * <code>numInts</code> is negative, or if <code>offset +
   * numInts</code> exceeds <code>i.length</code>.
   *
   * @throws NullPointerException if <code>i</code> is
   * <code>null</code>.
   *
   * @throws EOFException if the input stream ends before all content
   * was read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readInt()
   */
  void readFully(int[] i, int offset, int numInts)
    throws IOException;


  /**
   * Reads a sequence of signed 64-bit integers into a
   * <code>long[]</code> array.  If necessary, values are converted
   * from the stream&#x2019;s {@linkplain #getByteOrder() current byte
   * order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @param l an array for storing the read values.
   *
   * @param offset the index of the first element in <code>l</code>
   * that will hold read data.
   *
   * @param numLongs the number of signed 64-bit integers to read
   * (which is one eight of the number of bytes).
   *
   * @throws IndexOutOfBoundsException if <code>offset</code> or
   * <code>numLongs</code> is negative, or if <code>offset +
   * numLongs</code> exceeds <code>l.length</code>.
   *
   * @throws NullPointerException if <code>l</code> is
   * <code>null</code>.
   *
   * @throws EOFException if the input stream ends before all content
   * was read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readLong()
   */
  void readFully(long[] l, int offset, int numLongs)
    throws IOException;


  /**
   * Reads a sequence of IEEE 32-bit single-precision floating point
   * numbers into a <code>float[]</code> array.  If necessary, values
   * are converted from the stream&#x2019;s {@linkplain
   * #getByteOrder() current byte order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @param d an array for storing the read values.
   *
   * @param offset the index of the first element in <code>d</code>
   * that will hold read data.
   *
   * @param numFloats the number of IEEE 32-bit single-precision
   * floating point numbers to read (which is one fourth of the number
   * of bytes).
   *
   * @throws IndexOutOfBoundsException if <code>offset</code> or
   * <code>numFloats</code> is negative, or if <code>offset +
   * numFloats</code> exceeds <code>f.length</code>.
   *
   * @throws NullPointerException if <code>f</code> is
   * <code>null</code>.
   *
   * @throws EOFException if the input stream ends before all content
   * was read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readFloat()
   */
  void readFully(float[] f, int offset, int numFloats)
    throws IOException;


  /**
   * Reads a sequence of IEEE 64-bit double-precision floating point
   * numbers into a <code>double[]</code> array.  If necessary, values
   * are converted from the stream&#x2019;s {@linkplain
   * #getByteOrder() current byte order}.
   *
   * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
   * before any data is read.
   * 
   * @param d an array for storing the read values.
   *
   * @param offset the index of the first element in <code>d</code>
   * that will hold read data.
   *
   * @param numDoubles the number of IEEE 64-bit double-precision
   * floating point numbers to read (which is one eight of the number
   * of bytes).
   *
   * @throws IndexOutOfBoundsException if <code>offset</code> or
   * <code>numDoubles</code> is negative, or if <code>offset +
   * numDoubles</code> exceeds <code>d.length</code>.
   *
   * @throws NullPointerException if <code>d</code> is
   * <code>null</code>.
   *
   * @throws EOFException if the input stream ends before all content
   * was read.
   *
   * @throws IOException if some general problem happens with
   * accessing data.
   *
   * @see #readDouble()
   */
  void readFully(double[] d, int offset, int numDoubles)
    throws IOException;

  long getStreamPosition()
    throws IOException;

  int getBitOffset()
    throws IOException;

  void setBitOffset(int bitOffset)
    throws IOException;

  int readBit()
    throws IOException;

  long readBits(int numBits)
    throws IOException;

  long length()
    throws IOException;

  int skipBytes(int numBytes)
    throws IOException;

  long skipBytes(long numBytes)
    throws IOException;

  void seek(long pos)
    throws IOException;

  void mark();

  void reset()
    throws IOException;

  void flushBefore(long pos)
    throws IOException;

  void flush()
    throws IOException;

  long getFlushedPosition();

  boolean isCached();

  boolean isCachedMemory();

  boolean isCachedFile();

  void close()
    throws IOException;
}
