The base class for
image codecs, operations to read images from or write them to streams.
A codec should support one file format only.
The word codec is derived from
enCOder DECoder.
Usage
The codecs differ quite a bit in what they support.
But here are two code snippets that demonstrate how to do loading and saving in general.
Load image
ImageCodec codec = new BMPCodec(); // BMPCodec is just an example
codec.setFile("image.bmp", CodecMode.LOAD);
codec.process();
PixelImage image = codec.getImage();
Save image
PixelImage image = ...; // the image to be saved
ImageCodec codec = new BMPCodec(); // BMPCodec is just an example
codec.setFile("image.bmp", CodecMode.SAVE);
codec.setImage(image);
codec.process();
I/O objects
There are several set and get methods for I/O objects, including
DataInput, DataOutput, InputStream, OutputStream and RandomAccessFile.
If you are just using the codec (and not developing one) make it easier
for yourself and use
setFile(String,CodecMode)
.
That way the picking of the right type of I/O class and the creation of a
buffered stream wrapper is done automatically.
Codecs have different requirements concerning I/O objects.
If an image is to be loaded, it's enough for some formats to linearly read
from an
java.io.InputStream
to load the image.
However, some formats (like TIFF) require random access.
When implementing a codec, take care that as many I/O classes as possible can be used.
If possible, call
getInputAsDataInput()
when loading and
getOutputAsDataOutput()
when saving.
That way, input / output streams, RandomAccessFiles and arbitrary DataInput / DataOutput objects
can be used.
Mode
Codecs can be used to save images or load them, or both.
As was g; by default, no mode (of enumeration type
CodecMode
)
is specified and
getMode()
returns
null
.
Mode only has two possible values,
CodecMode.LOAD
and
CodecMode.SAVE
.
In some cases, the codec can find out whether to load or save from the I/O objects
that were given to it; if it has an input stream, something must be loaded,
if it has an output stream, something is to be saved.
If a codec demands a
RandomAccessFile
, there is no way to find out
the mode automatically, that is why
setRandomAccessFile(RandomAccessFile,CodecMode)
also has an
argument of type
CodecMode
.
Bounds; to load or save only part of an image.
Defining bounds is optional; by default, the complete image is loaded
or saved (no bounds).
Using
setBounds(int,int,int,int)
, one can specify the
rectangle which will be loaded or saved.
PixelImage object; get and set methods for the image which is to be
loaded or saved.
If an image is to be loaded, a PixelImage object can optionally be specified so that the image will
be written to that object; image type and resolution must of course match the image
from input.
Normally, the codec will create the appropriate image object
itself.
If an image is to be saved, an image object
must be provided, otherwise there
is nothing to do.
Image index; the index of the image that is to be loaded (int value, default
is 0). For image formats that support more than one image in one stream, the index of the
image to be loaded (zero-based) can be specified using
setImageIndex(int)
.
Textual comments
Some file formats allow for the inclusion of textual comments, to
store a description, creator, copyright owner or anything else within the image
file without actually drawing that text on the image itself.
Some codecs support reading and writing of comments.
Other methods
Each file format must be able to return its name (
getFormatName()
) and
file extensions that are typical for it (
getFileExtensions()
).
A related method suggests a file extension for a given PixelImage object (
suggestFileExtension(PixelImage)
).
That method need not be implemented, the default version returns simply
null
.
However, it is encouraged that codec implementors provide this method as well.
Most file formats only have one typical extension (e. g.
.bmp
).
However, for a file format like PNM, the extension depends on the image type (a grayscale
image would end in
.pgm
, a color image in
.ppm
).
appendComment
public void appendComment(String comment)
Appends a comment to the internal list of comments.
If the argument comment is non-null, it will be added to the internal
list of comment strings.
comment
- the comment to be added
checkBounds
public void checkBounds(int width,
int height)
throws WrongParameterException
If bounds were defined for this codec, this method tests if the
bounds rectangle fits into the rectangle
(0, 0) / (width - 1, height - 1)
.
If the bounds are incorrect, a
WrongParameterException
is thrown, otherwise nothing happens.
To be used within codecs that support the bounds concept.
close
public void close()
Calls the close method of all input and output I/O objects
that were given to this object.
Catches and ignores any IOException objects that may be
thrown in the process.
Note that not all I/O objects have a close method (e.g. java.io.DataInput
and java.io.DataOutput
have not).
getBoundsHeight
public int getBoundsHeight()
- height of bounds rectangle
getBoundsWidth
public int getBoundsWidth()
- width of bounds rectangle
getBoundsX1
public int getBoundsX1()
Returns x coordinate of the upper left corner of the bounds.
Bounds must have been specified using
setBounds(int,int,int,int)
,
otherwise the return value is undefined.
- x coordinate of the upper left corner of the bounds
getBoundsX2
public int getBoundsX2()
Returns x coordinate of the lower right corner of the bounds.
Bounds must have been specified using
setBounds(int,int,int,int)
,
otherwise the return value is undefined.
- x coordinate of the lower right corner of the bounds
getBoundsY1
public int getBoundsY1()
Returns y coordinate of the upper left corner of the bounds.
Bounds must have been specified using
setBounds(int,int,int,int)
,
otherwise the return value is undefined.
- y coordinate of the upper left corner of the bounds
getBoundsY2
public int getBoundsY2()
Returns y coordinate of the lower right corner of the bounds.
Bounds must have been specified using
setBounds(int,int,int,int)
,
otherwise the return value is undefined.
- y coordinate of the lower right corner of the bounds
getComment
public String getComment(int index)
Returns a comment from the internal list of comments.
index
- the index of the comment to be returned, must be from
0
to getNumComments()
- 1
; if this is not
the case, null
will be returned
getDataInput
public DataInput getDataInput()
getDataOutput
public DataOutput getDataOutput()
getDpiX
public int getDpiX()
Returns the horizontal physical resolution of the image associated
with this codec.
This resolution value was either retrieved from an image file or
set via
setDpi(int,int)
.
- horizontal physical resolution in dpi
getDpiY
public int getDpiY()
Returns the vertical physical resolution of the image associated
with this codec.
This resolution value was either retrieved from an image file or
set via
setDpi(int,int)
.
- horizontal physical resolution in dpi
getFileExtensions
public String[] getFileExtensions()
Returns all file extensions that are typical for this file format.
The default implementation in ImageCodec returns null
.
The file extension strings should include a leading dot
and are supposed to be lower case (if that is allowed for
the given file format).
Example: {".jpg", ".jpeg"}
for the JPEG file format.
- String array with typical file extensions
getFormatName
public abstract String getFormatName()
Returns the name of the file format supported by this codec.
All classes extending
ImageCodec
must override this method.
When overriding, leave out any words in a particular language so
that this format name can be understood by everyone.
Usually it is enough to return the format creator plus a typical
abbreviation, e.g.
Microsoft BMP
or
Portable Anymap (PNM)
.
- name of the file format supported by this codec
getImage
public PixelImage getImage()
Returns the image object stored in this codec.
This is either an image given to this object via
setImage(PixelImage)
or it was created by the codec
itself during a loading operation.
- PixelImage object stored in this codec
getImageIndex
public int getImageIndex()
Returns the zero-based index of the image to be loaded.
Default is zero.
- zero-based image index value
getInputAsDataInput
public DataInput getInputAsDataInput()
Returns a
java.io.DataInput
object if one was specified
using
setDataInput(DataInput)
,
or creates a
java.io.DataInputStream
if an
java.io.InputStream
was specified,
or returns a
java.io.RandomAccessFile
if one was specified
(RandomAccessFile implements DataInput).
If neither of those has been given to this object,
null
is returned.
getInputStream
public InputStream getInputStream()
getMimeTypes
public abstract String[] getMimeTypes()
Return the
MIME
(Multipurpose Internet Mail Extensions) type strings for this format, or
null
if none are available.
- MIME type strings or null
getMode
public CodecMode getMode()
Returns the mode this codec is in.
Can be null
, so that the codec will have to find out
itself what to do.
- codec mode (load or save)
getNumComments
public int getNumComments()
Returns the current number of comments in the internal comment list.
- number of comments in the internal comment list
getOutputAsDataOutput
public DataOutput getOutputAsDataOutput()
Attempts to return an output object as a java.io.DataOutput
object.
- a DataOutput object or null if that was not possible
getOutputStream
public OutputStream getOutputStream()
getRandomAccessFile
public RandomAccessFile getRandomAccessFile()
hasBounds
public boolean hasBounds()
Returns if bounds have been specified.
- if bounds have been specified
isLoadingSupported
public abstract boolean isLoadingSupported()
Returns if this codec is able to load images in the file format supported by this codec.
If true
is returned this does not necessarily mean that all files in this
format can be read, but at least some.
isRowRequired
public boolean isRowRequired(int row)
Returns if an image row given by its number (zero-based) must be loaded
in the context of the current bounds.
Example: if vertical bounds have been set to 34 and 37, image rows 34 to
37 as arguments to this method would result in
true
, anything
else (e.g. 12 or 45) would result in
false
.
row
- the number of the row to be checked
- if row must be loaded, regarding the current bounds
isSavingSupported
public abstract boolean isSavingSupported()
Returns if this codec is able to save images in the file format supported by this codec.
If true
is returned this does not necessarily mean that all types files in this
format can be written, but at least some.
isTileRequired
public boolean isTileRequired(int x1,
int y1,
int x2,
int y2)
Returns if the tile formed by the argument coordinates
form a rectangle that overlaps with the bounds.
If no bounds were defined, returns true
.
- if the argument tile is required
removeAllComments
public void removeAllComments()
Removes all entries from the internal list of comments.
removeBounds
public void removeBounds()
setBounds
public void setBounds(int x1,
int y1,
int x2,
int y2)
Sets the bounds of a rectangular part of the image that
is to be loaded or saved, instead of the complete image.
setBoundsIfNecessary
public void setBoundsIfNecessary(int width,
int height)
If no bounds have been set (
hasBounds()
returns
false
),
this method will set the bounds to
0, 0, width - 1, height - 1
.
By calling this method somewhere in the codec, no distinction has to
be made for the two cases
bounds have been defined and
bounds have not been defined.
width
- width of the image to be loaded or savedheight
- height of the image to be loaded or saved
setDataInput
public void setDataInput(DataInput dataInput)
Specifies a DataInput object to be used for loading.
dataInput
- DataInput object to be used for loading an image
setDataOutput
public void setDataOutput(DataOutput dataOutput)
Sets a java.io.DataOutput
object to be used for saving
an image.
dataOutput
- the object to be used for output
setDpi
public void setDpi(int horizontalDpi,
int verticalDpi)
Sets the DPI values to be stored in the file to the argument values.
horizontalDpi
- horizontal physical resolution in DPI (dots per inch)verticalDpi
- vertical physical resolution in DPI (dots per inch)
setFile
public void setFile(File file,
CodecMode codecMode)
throws IOException,
UnsupportedCodecModeException
Gives a File object and a codec mode to this codec and attempts
to initialize the appropriate I/O objects.
Simply calls
setFile(String,CodecMode)
with the absolute
path of the File object.
file
- File object for the file to be usedcodecMode
- defines whether an image is to be loaded from or saved to the file
setFile
public void setFile(String fileName,
CodecMode codecMode)
throws IOException,
UnsupportedCodecModeException
Gives a file name and codec mode to the codec which will then
try to create the corresponding I/O object.
The default implementation in ImageCodec creates a DataInputStream object
wrapped around a BufferedInputStream wrapped around a FileInputStream for
CodecMode.LOAD.
Similar for CodecMode.SAVE: a DataOutputStream around a BufferedOutputStream
object around a FileOutputStream object.
Codecs that need different I/O objects must override this method
(some codecs may need random access and thus require a RandomAccessFile object).
fileName
- name of the file to be used for loading or savingcodecMode
- defines whether file is to be used for loading or saving
setImage
public void setImage(PixelImage img)
Give an image to this codec to be used for loading an image into it
or saving the image.
img
- image object to save or to load data into
setImageIndex
public void setImageIndex(int index)
Sets the index of the image to be loaded to the argument value
(which must be zero or larger).
index
- int index value (zero-based) of the image to be loaded
setInputStream
public void setInputStream(InputStream inputStream)
An java.io.InputStream
can be given to this codec using this method.
inputStream
- InputStream object to read from
setOutputStream
public void setOutputStream(OutputStream outputStream)
A method to give an java.io.OutputStream
to this codec to be used
for saving an image.
outputStream
- the output stream to be used by this codec
setRandomAccessFile
public void setRandomAccessFile(RandomAccessFile randomAccessFile,
CodecMode codecMode)
A method to give a java.io.RandomAccessFile
to this codec to be used
for loading or saving an image.
It is not possible to determine from a RandomAccessFile object whether it
was opened in read-only or read-and-write mode.
To let the codec know whether the object is to be used for loading or saving
the second argument is of type CodecMode.
randomAccessFile
- the file to be used for loading or savingcodecMode
- tells the codec whether the file is to be used for loading or saving
suggestFileExtension
public String suggestFileExtension(PixelImage image)
Attempts to suggest a filename extension.
The type of the argument image will be taken into consideration,
although this will be necessary for some file formats only (as an
example, PNM has different extensions for different image types, see
PNMCodec
).
This default implementation always returns
null
.
image
- the image that is to be written to a file
- the file extension, including a leading dot, or
null
if no file extension can be recommended