public abstract class ImageCodec extends Operation
ImageCodec codec = new BMPCodec(); // BMPCodec is just an example codec.setFile("image.bmp", CodecMode.LOAD); codec.process(); PixelImage image = codec.getImage();
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();
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 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.
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(java.io.RandomAccessFile, net.sourceforge.jiu.codecs.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)
.
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
).
Modifier and Type | Field and Description |
---|---|
private boolean |
boundsAvail |
private int |
boundsHeight |
private int |
boundsWidth |
private int |
boundsX1 |
private int |
boundsX2 |
private int |
boundsY1 |
private int |
boundsY2 |
private java.util.Vector |
comments |
private java.io.DataInput |
din |
private java.io.DataOutput |
dout |
private int |
dpiX |
private int |
dpiY |
private PixelImage |
image |
private int |
imageIndex |
private java.io.InputStream |
in |
private CodecMode |
mode |
private java.io.OutputStream |
out |
private java.io.RandomAccessFile |
raf |
Constructor and Description |
---|
ImageCodec()
This constructor will be called by descendants.
|
Modifier and Type | Method and Description |
---|---|
void |
appendComment(java.lang.String comment)
Appends a comment to the internal list of comments.
|
void |
checkBounds(int width,
int height)
If bounds were defined for this codec, this method tests if the
bounds rectangle fits into the rectangle
(0, 0) / (width - 1, height - 1) . |
void |
checkImageResolution()
If an image object was provided to be used for loading via
setImage(net.sourceforge.jiu.data.PixelImage) ,
this method checks if its resolution is the same as the bounds' resolution. |
void |
close()
Calls the close method of all input and output I/O objects
that were given to this object.
|
int |
getBoundsHeight()
Returns the height of the rectangle specified by bounds.
|
int |
getBoundsWidth()
Returns the width of the rectangle specified by bounds.
|
int |
getBoundsX1()
Returns x coordinate of the upper left corner of the bounds.
|
int |
getBoundsX2()
Returns x coordinate of the lower right corner of the bounds.
|
int |
getBoundsY1()
Returns y coordinate of the upper left corner of the bounds.
|
int |
getBoundsY2()
Returns y coordinate of the lower right corner of the bounds.
|
java.lang.String |
getComment(int index)
Returns a comment from the internal list of comments.
|
java.io.DataInput |
getDataInput()
|
java.io.DataOutput |
getDataOutput()
|
int |
getDpiX()
Returns the horizontal physical resolution of the image associated
with this codec.
|
int |
getDpiY()
Returns the vertical physical resolution of the image associated
with this codec.
|
java.lang.String[] |
getFileExtensions()
Returns all file extensions that are typical for this file format.
|
abstract java.lang.String |
getFormatName()
Returns the name of the file format supported by this codec.
|
PixelImage |
getImage()
Returns the image object stored in this codec.
|
int |
getImageIndex()
Returns the zero-based index of the image to be loaded.
|
java.io.DataInput |
getInputAsDataInput()
Returns a
DataInput object if one was specified
using setDataInput(DataInput) ,
or creates a DataInputStream if an
InputStream was specified,
or returns a RandomAccessFile if one was specified
(RandomAccessFile implements DataInput). |
java.io.InputStream |
getInputStream()
Returns an
InputStream object that was given to
this codec via setInputStream(InputStream)
(or null otherwise). |
abstract java.lang.String[] |
getMimeTypes()
Return the MIME
(Multipurpose Internet Mail Extensions) type strings for this format, or
null
if none are available. |
CodecMode |
getMode()
Returns the mode this codec is in.
|
int |
getNumComments()
Returns the current number of comments in the internal comment list.
|
java.io.DataOutput |
getOutputAsDataOutput()
Attempts to return an output object as a
DataOutput object. |
java.io.OutputStream |
getOutputStream()
Returns an
OutputStream object that was given to
this codec via setOutputStream(OutputStream)
(or null otherwise). |
java.io.RandomAccessFile |
getRandomAccessFile()
Returns a
RandomAccessFile object that was given to
this codec via setRandomAccessFile(RandomAccessFile, CodecMode)
(or null otherwise). |
boolean |
hasBounds()
Returns if bounds have been specified.
|
protected void |
initModeFromIOObjects() |
abstract boolean |
isLoadingSupported()
Returns if this codec is able to load images in the file format supported by this codec.
|
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.
|
abstract boolean |
isSavingSupported()
Returns if this codec is able to save images in the file format supported by this codec.
|
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.
|
void |
removeAllComments()
Removes all entries from the internal list of comments.
|
void |
removeBounds()
If bounds were set using
setBounds(int, int, int, int) , these
bounds are no longer regarded after the call to this method. |
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.
|
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 . |
void |
setDataInput(java.io.DataInput dataInput)
Specifies a DataInput object to be used for loading.
|
void |
setDataOutput(java.io.DataOutput dataOutput)
Sets a
DataOutput object to be used for saving
an image. |
void |
setDpi(int horizontalDpi,
int verticalDpi)
Sets the DPI values to be stored in the file to the argument values.
|
void |
setFile(java.io.File file,
CodecMode codecMode)
Gives a File object and a codec mode to this codec and attempts
to initialize the appropriate I/O objects.
|
void |
setFile(java.lang.String fileName,
CodecMode codecMode)
Gives a file name and codec mode to the codec which will then
try to create the corresponding I/O object.
|
void |
setImage(PixelImage img)
Give an image to this codec to be used for loading an image into it
or saving the image.
|
void |
setImageIndex(int index)
Sets the index of the image to be loaded to the argument value
(which must be zero or larger).
|
void |
setInputStream(java.io.InputStream inputStream)
An
InputStream can be given to this codec using this method. |
void |
setOutputStream(java.io.OutputStream outputStream)
A method to give an
OutputStream to this codec to be used
for saving an image. |
void |
setRandomAccessFile(java.io.RandomAccessFile randomAccessFile,
CodecMode codecMode)
A method to give a
RandomAccessFile to this codec to be used
for loading or saving an image. |
java.lang.String |
suggestFileExtension(PixelImage image)
Attempts to suggest a filename extension.
|
addProgressListener, addProgressListeners, getAbort, process, removeProgressListener, setAbort, setProgress, setProgress
private int boundsX1
private int boundsY1
private int boundsX2
private int boundsY2
private boolean boundsAvail
private int boundsWidth
private int boundsHeight
private java.util.Vector comments
private int dpiX
private int dpiY
private java.io.DataInput din
private java.io.DataOutput dout
private PixelImage image
private int imageIndex
private java.io.InputStream in
private CodecMode mode
private java.io.OutputStream out
private java.io.RandomAccessFile raf
public ImageCodec()
public void appendComment(java.lang.String comment)
comment
- the comment to be addedpublic void checkBounds(int width, int height) throws WrongParameterException
(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.WrongParameterException
public void checkImageResolution() throws WrongParameterException
setImage(net.sourceforge.jiu.data.PixelImage)
,
this method checks if its resolution is the same as the bounds' resolution.
If the two differ, a WrongParameterException
is thrown.WrongParameterException
- if image resolution and bounds dimension differpublic void close()
DataInput
and DataOutput
have not).public int getBoundsX1()
setBounds(int, int, int, int)
,
otherwise the return value is undefined.public int getBoundsX2()
setBounds(int, int, int, int)
,
otherwise the return value is undefined.public int getBoundsY1()
setBounds(int, int, int, int)
,
otherwise the return value is undefined.public int getBoundsY2()
setBounds(int, int, int, int)
,
otherwise the return value is undefined.public int getBoundsHeight()
setBounds(int, int, int, int)
,
otherwise the return value is undefined.
This equals getBoundsY2()
- getBoundsY1()
+ 1.public int getBoundsWidth()
setBounds(int, int, int, int)
,
otherwise the return value is undefined.
This equals getBoundsX2()
- getBoundsX1()
+ 1.public java.lang.String getComment(int index)
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 returnedgetNumComments()
,
appendComment(java.lang.String)
,
removeAllComments()
public java.io.DataInput getDataInput()
public java.io.DataOutput getDataOutput()
public int getDpiX()
setDpi(int, int)
.getDpiY()
public int getDpiY()
setDpi(int, int)
.getDpiX()
public java.lang.String[] getFileExtensions()
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.public abstract java.lang.String getFormatName()
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)
.public PixelImage getImage()
setImage(PixelImage)
or it was created by the codec
itself during a loading operation.public int getImageIndex()
public java.io.DataInput getInputAsDataInput()
DataInput
object if one was specified
using setDataInput(DataInput)
,
or creates a DataInputStream
if an
InputStream
was specified,
or returns a RandomAccessFile
if one was specified
(RandomAccessFile implements DataInput).
If neither of those has been given to this object, null
is returned.null
public java.io.InputStream getInputStream()
InputStream
object that was given to
this codec via setInputStream(InputStream)
(or null
otherwise).public abstract java.lang.String[] getMimeTypes()
null
if none are available.public CodecMode getMode()
null
, so that the codec will have to find out
itself what to do.public int getNumComments()
public java.io.DataOutput getOutputAsDataOutput()
DataOutput
object.public java.io.OutputStream getOutputStream()
OutputStream
object that was given to
this codec via setOutputStream(OutputStream)
(or null
otherwise).public java.io.RandomAccessFile getRandomAccessFile()
RandomAccessFile
object that was given to
this codec via setRandomAccessFile(RandomAccessFile, CodecMode)
(or null
otherwise).public boolean hasBounds()
removeBounds()
,
setBounds(int, int, int, int)
protected void initModeFromIOObjects() throws MissingParameterException
MissingParameterException
public abstract boolean isLoadingSupported()
true
is returned this does not necessarily mean that all files in this
format can be read, but at least some.public abstract boolean isSavingSupported()
true
is returned this does not necessarily mean that all types files in this
format can be written, but at least some.public boolean isRowRequired(int row)
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 checkedpublic boolean isTileRequired(int x1, int y1, int x2, int y2)
true
.x1
- y1
- x2
- y2
- public void removeAllComments()
public void removeBounds()
setBounds(int, int, int, int)
, these
bounds are no longer regarded after the call to this method.public void setBounds(int x1, int y1, int x2, int y2)
public void setBoundsIfNecessary(int width, int height)
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 savedpublic void setDataInput(java.io.DataInput dataInput)
dataInput
- DataInput object to be used for loading an imagepublic void setDataOutput(java.io.DataOutput dataOutput)
DataOutput
object to be used for saving
an image.dataOutput
- the object to be used for outputpublic void setDpi(int horizontalDpi, int verticalDpi)
public void setFile(java.io.File file, CodecMode codecMode) throws java.io.IOException, UnsupportedCodecModeException
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 filejava.io.IOException
UnsupportedCodecModeException
public void setFile(java.lang.String fileName, CodecMode codecMode) throws java.io.IOException, UnsupportedCodecModeException
fileName
- name of the file to be used for loading or savingcodecMode
- defines whether file is to be used for loading or savingjava.io.IOException
UnsupportedCodecModeException
public void setImage(PixelImage img)
img
- image object to save or to load data intopublic void setImageIndex(int index)
index
- int index value (zero-based) of the image to be loadedjava.lang.IllegalArgumentException
- if the argument is negativepublic void setInputStream(java.io.InputStream inputStream)
InputStream
can be given to this codec using this method.inputStream
- InputStream object to read frompublic void setOutputStream(java.io.OutputStream outputStream)
OutputStream
to this codec to be used
for saving an image.outputStream
- the output stream to be used by this codecpublic void setRandomAccessFile(java.io.RandomAccessFile randomAccessFile, CodecMode codecMode)
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 savingpublic java.lang.String suggestFileExtension(PixelImage image)
PNMCodec
).
This default implementation always returns null
.image
- the image that is to be written to a filenull
if no file extension can be recommended