public class PNGCodec extends ImageCodec
ImageLoader
or ToolkitLoader
which require only a single line of code and can load all formats
supported by JIU, including PNG.
PNGCodec codec = new PNGCodec(); codec.setFile("image.png", CodecMode.LOAD); codec.process(); PixelImage image = codec.getImage();
PNGCodec codec = new PNGCodec(); codec.setFile("out.png", CodecMode.SAVE); codec.setImage(image); codec.setCompressionLevel(Deflater.BEST_COMPRESSION); codec.appendComment("Copyright (c) 1992 John Doe"); // sets last modification time to current time codec.setModification(new GregorianCalendar( new SimpleTimeZone(0, "UTC"))); codec.process();
BilevelImage
objects,
2, 4 and 8 bit streams as Gray8Image
and 16 bit as
Gray16Image
objects.Paletted8Image
.RGB24Image
,
48 bit streams as RGB48Image
objects.BilevelImage
objects are stored as grayscale 1 bit PNG streams.Paletted8Image
objects are stored as indexed 8 bit PNG streams.
Images will always be stored as 8 bit files, even if the palette has only 16, 4 or 2 entries.
Gray8Image
objects are stored as 8 bit grayscale PNG streams.Gray16Image
objects are stored as 16 bit grayscale PNG streams.RGB24Image
objects are stored as 24 bit RGB truecolor PNG streams.RGB48Image
objects are stored as 48 bit RGB truecolor PNG streams.ImageCodec.setBounds(int, int, int, int)
, the codec will only load or save
part of an image.
pHYs
chunks.
Use ImageCodec.getDpiX()
and ImageCodec.getDpiY()
to retrieve that information.
after the call to process()
.tEXt
chunks and can be retrieved
with ImageCodec.getComment(int)
after the call to process()
.ImageCodec.setDpi(int, int)
)
is stored in a pHYs
chunk.ImageCodec.appendComment(java.lang.String)
) are stored as tEXt
chunks.
The keyword used is Comment
.
Each of the ImageCodec.getNumComments()
is stored in a chunk of its own.tIME
chunk.
Use setModification(Calendar)
to give a point in time to this codec.Constructor | Description |
---|---|
PNGCodec() |
Modifier and Type | Method | Description |
---|---|---|
private void |
allocateImage() |
Allocates the right image to private field
image ,
taking into consideration the fields width, height, precision and colorType. |
private void |
checkColorTypeAndPrecision() |
|
private int |
computeBytesPerRow(int numPixels) |
Computes a number of bytes for a given number of pixels,
regarding precision and availability of an alpha channel.
|
private int |
computeColumnsAdam7(int pass) |
|
private void |
fillRowBuffer(int y,
byte[] row,
int offs) |
|
private static String |
getChunkName(int chunk) |
Creates a four-letter String from the parameter, an
int
value, supposed to be storing a chunk name. |
String |
getFormatName() |
Returns the name of the file format supported by this codec.
|
String[] |
getMimeTypes() |
Return the MIME
(Multipurpose Internet Mail Extensions) type strings for this format, or
null
if none are available. |
private static int |
getPaeth(byte l,
byte u,
byte nw) |
|
private void |
inflateBytes(byte[] buffer,
int numBytes) |
|
boolean |
isLoadingSupported() |
Returns if this codec is able to load images in the file format supported by this codec.
|
boolean |
isSavingSupported() |
Returns if this codec is able to save images in the file format supported by this codec.
|
private void |
load() |
|
private void |
loadChunk() |
|
private void |
loadImage(long chunkSize) |
Load an image from the current position in the file.
|
private void |
loadImageHeader() |
Reads data from an IHDR chunk and initializes private fields with it.
|
private void |
loadImageInterlacedAdam7() |
|
private void |
loadImageNonInterlaced() |
|
private void |
loadPalette(long numEntries) |
|
static void |
main(String[] args) |
|
void |
process() |
This method does the actual work of the operation.
|
private int |
readFilterType() |
|
private void |
reverseFilter(int rowFilterType,
byte[] buffer,
byte[] prev,
int numBytes) |
|
private void |
save() |
|
private void |
saveChunk(int chunkType,
int chunkSize,
byte[] data) |
|
private void |
saveIendChunk() |
|
private void |
saveIhdrChunk() |
|
private void |
saveImage() |
|
private void |
saveImageNonInterlaced() |
|
private void |
savePhysChunk() |
|
private void |
savePlteChunk() |
|
private void |
saveTextChunks() |
|
private void |
saveTimeChunk() |
|
void |
setCompressionLevel(int newLevel) |
Sets the compression level to be used with the underlying
Deflater object which does the compression. |
void |
setCompressionStrategy(int newStrategy) |
Sets the compression strategy to be used with the underlying
Deflater object which does the compression. |
void |
setEncodingIdatSize(int newSize) |
Sets the size of IDAT chunks generated when encoding.
|
void |
setFile(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 |
setModification(Calendar time) |
Sets date and time of last modification of the image to be stored in a PNG stream
when saving.
|
private void |
skip(long num) |
Skips a number of bytes in the input stream.
|
private void |
storeInterlacedAdam7(int pass,
int y,
byte[] buffer) |
|
private void |
storeInterlacedAdam7Gray(int pass,
int y,
byte[] buffer) |
|
private void |
storeInterlacedAdam7GrayAlpha(int pass,
int y,
byte[] buffer) |
|
private void |
storeInterlacedAdam7Indexed(int pass,
int y,
byte[] buffer) |
|
private void |
storeInterlacedAdam7Rgb(int pass,
int y,
byte[] buffer) |
|
private void |
storeInterlacedAdam7RgbAlpha(int pass,
int y,
byte[] buffer) |
|
private void |
storeNonInterlaced(int y,
byte[] buffer) |
|
private void |
storeNonInterlacedGray(int y,
byte[] buffer) |
|
private void |
storeNonInterlacedGrayAlpha(int y,
byte[] buffer) |
|
private void |
storeNonInterlacedIndexed(int y,
byte[] buffer) |
|
private void |
storeNonInterlacedRgb(int y,
byte[] buffer) |
|
private void |
storeNonInterlacedRgbAlpha(int y,
byte[] buffer) |
|
String |
suggestFileExtension(PixelImage image) |
Attempts to suggest a filename extension.
|
appendComment, checkBounds, checkImageResolution, close, getBoundsHeight, getBoundsWidth, getBoundsX1, getBoundsX2, getBoundsY1, getBoundsY2, getComment, getDataInput, getDataOutput, getDpiX, getDpiY, getFileExtensions, getImage, getImageIndex, getInputAsDataInput, getInputStream, getMode, getNumComments, getOutputAsDataOutput, getOutputStream, getRandomAccessFile, hasBounds, initModeFromIOObjects, isRowRequired, isTileRequired, removeAllComments, removeBounds, setBounds, setBoundsIfNecessary, setDataInput, setDataOutput, setDpi, setFile, setImage, setImageIndex, setInputStream, setOutputStream, setRandomAccessFile
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
addProgressListener, addProgressListeners, getAbort, removeProgressListener, setAbort, setProgress, setProgress
private final int CHUNK_CRC32_IEND
private final int CHUNK_SIZE_IHDR
private final int CHUNK_TYPE_IDAT
private final int CHUNK_TYPE_IEND
private final int CHUNK_TYPE_IHDR
private final int CHUNK_TYPE_PHYS
private final int CHUNK_TYPE_PLTE
private final int CHUNK_TYPE_TEXT
private final int CHUNK_TYPE_TIME
private final int COLOR_TYPE_GRAY
private final int COLOR_TYPE_GRAY_ALPHA
private final int COLOR_TYPE_INDEXED
private final int COLOR_TYPE_RGB
private final int COLOR_TYPE_RGB_ALPHA
private final int COLOR_TYPE_ALPHA
private final int FILTER_TYPE_NONE
private final int FILTER_TYPE_SUB
private final int FILTER_TYPE_UP
private final int FILTER_TYPE_AVERAGE
private final int FILTER_TYPE_PAETH
private final int COMPRESSION_DEFLATE
private final int INTERLACING_NONE
private final int INTERLACING_ADAM7
private final int FILTERING_ADAPTIVE
private final int MAX_TEXT_SIZE
private final int ADAM7_NUM_PASSES
private final int DEFAULT_ENCODING_MIN_IDAT_SIZE
private final int[] ADAM7_COLUMN_INCREMENT
private final int[] ADAM7_FIRST_COLUMN
private final int[] ADAM7_FIRST_ROW
private final int[] ADAM7_ROW_INCREMENT
private final byte[] MAGIC_BYTES
private boolean alpha
private byte[][] buffers
private int bpp
private CRC32 checksum
private CheckedInputStream checkedIn
private int chunkCounter
private int colorType
private int compressionType
private int currentBufferIndex
private int deflateLevel
private int deflateStrategy
private int encodingMinIdatSize
private int filterType
private boolean hasIhdr
private int height
private IntegerImage image
private DataInputStream in
private InflaterInputStream infl
private int interlaceType
private Calendar modification
private int numChannels
private DataOutput out
private Palette palette
private int precision
private int previousBufferIndex
private int width
private void allocateImage() throws InvalidFileStructureException, UnsupportedTypeException
image
,
taking into consideration the fields width, height, precision and colorType.
Assumes that an IHDR chunk has been read and the above mentioned
fields have been initialized and checked for their validity.private void checkColorTypeAndPrecision() throws UnsupportedTypeException
precision
and colorType
.
A lot of combinations possibly found in an IHDR chunk
are invalid.
Also initializes alpha
and numChannels
.UnsupportedTypeException
- if an invalid combination
of precision and colorType is foundprivate int computeBytesPerRow(int numPixels)
numPixels
- the number of pixels for which the number
of bytes necessary to store them is to be computedprivate int computeColumnsAdam7(int pass)
private void fillRowBuffer(int y, byte[] row, int offs)
private static String getChunkName(int chunk)
int
value, supposed to be storing a chunk name.public String getFormatName()
ImageCodec
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)
.getFormatName
in class ImageCodec
public String[] getMimeTypes()
ImageCodec
null
if none are available.getMimeTypes
in class ImageCodec
private static int getPaeth(byte l, byte u, byte nw)
private void inflateBytes(byte[] buffer, int numBytes) throws InvalidFileStructureException, IOException
public boolean isLoadingSupported()
ImageCodec
true
is returned this does not necessarily mean that all files in this
format can be read, but at least some.isLoadingSupported
in class ImageCodec
public boolean isSavingSupported()
ImageCodec
true
is returned this does not necessarily mean that all types files in this
format can be written, but at least some.isSavingSupported
in class ImageCodec
private void load() throws InvalidFileStructureException, IOException, UnsupportedTypeException, WrongFileFormatException
private void loadChunk() throws InvalidFileStructureException, IOException, UnsupportedTypeException
private void loadImage(long chunkSize) throws InvalidFileStructureException, IOException, UnsupportedTypeException
chunkSize
- size of the IDAT chunk that was just readInvalidFileStructureException
- if there are values in the PNG stream that make it invalidIOException
- if there were I/O errors when readingUnsupportedTypeException
- if something was encountered in the stream that is valid but not supported by this codecprivate void loadImageHeader() throws IOException, InvalidFileStructureException, UnsupportedTypeException
private void loadImageInterlacedAdam7() throws InvalidFileStructureException, IOException, UnsupportedTypeException
private void loadImageNonInterlaced() throws InvalidFileStructureException, IOException, UnsupportedTypeException
private void loadPalette(long numEntries) throws InvalidFileStructureException, IOException
public void process() throws InvalidFileStructureException, MissingParameterException, OperationFailedException, UnsupportedTypeException, WrongFileFormatException
Operation
process
in class Operation
MissingParameterException
- if any mandatory parameter was not given to the operationWrongParameterException
- if at least one of the input parameters was
not initialized appropriately (values out of the valid interval, etc.)OperationFailedException
InvalidFileStructureException
UnsupportedTypeException
WrongFileFormatException
private int readFilterType() throws InvalidFileStructureException, IOException
private void reverseFilter(int rowFilterType, byte[] buffer, byte[] prev, int numBytes) throws UnsupportedTypeException
UnsupportedTypeException
private void save() throws IOException
IOException
private void saveChunk(int chunkType, int chunkSize, byte[] data) throws IOException
IOException
private void saveIendChunk() throws IOException
IOException
private void saveIhdrChunk() throws IOException
IOException
private void saveImage() throws IOException
IOException
private void saveImageNonInterlaced() throws IOException
IOException
private void savePhysChunk() throws IOException
IOException
private void savePlteChunk() throws IOException
IOException
private void saveTextChunks() throws IOException
IOException
private void saveTimeChunk() throws IOException
IOException
public void setCompressionLevel(int newLevel)
Deflater
object which does the compression.
If no value is specified, Deflater.DEFAULT_COMPRESSION
is used.newLevel
- compression level, from 0 to 9, 0 being fastest
and compressing worst and 9 offering highest compression and taking
the most timepublic void setCompressionStrategy(int newStrategy)
Deflater
object which does the compression.
If no value is specified, Deflater.DEFAULT_STRATEGY
is used.newStrategy
- one of Deflater's strategy values:
Deflater.DEFAULT_STRATEGY
,
Deflater.FILTERED
,
Deflater.HUFFMAN_ONLY
public void setEncodingIdatSize(int newSize)
Compressed image data is spread over several IDAT chunks by this codec.
The length of the compressed data of a complete image is known only after the complete image
has been encoded.
With PNG, that length value has to be stored before the compressed data as a chunk size value.
This codec is supposed to work with OutputStream
objects,
so seeking back to adjust the chunk size value of an IDAT chunk is not
possible.
That's why all data of a chunk is compressed into a memory buffer.
Whenever the buffer gets full, it is written to output as an IDAT chunk.
Note that the last IDAT chunk may be smaller than the size defined here.
newSize
- size of encoding compressed data bufferpublic void setFile(String fileName, CodecMode codecMode) throws IOException, UnsupportedCodecModeException
ImageCodec
setFile
in class ImageCodec
fileName
- name of the file to be used for loading or savingcodecMode
- defines whether file is to be used for loading or savingIOException
UnsupportedCodecModeException
public void setModification(Calendar time)
new GregorianCalendar(new SimpleTimeZone(0, "UTC"))
as parameter for this method.time
- time of last modification of the imageprivate void skip(long num) throws IOException
num
- number of bytes to be skippedIOException
- if there were I/O errorsprivate void storeInterlacedAdam7(int pass, int y, byte[] buffer)
private void storeInterlacedAdam7Gray(int pass, int y, byte[] buffer)
private void storeInterlacedAdam7GrayAlpha(int pass, int y, byte[] buffer)
private void storeInterlacedAdam7Indexed(int pass, int y, byte[] buffer)
private void storeInterlacedAdam7Rgb(int pass, int y, byte[] buffer)
private void storeInterlacedAdam7RgbAlpha(int pass, int y, byte[] buffer)
private void storeNonInterlaced(int y, byte[] buffer)
private void storeNonInterlacedGray(int y, byte[] buffer)
private void storeNonInterlacedGrayAlpha(int y, byte[] buffer)
private void storeNonInterlacedIndexed(int y, byte[] buffer)
private void storeNonInterlacedRgb(int y, byte[] buffer)
private void storeNonInterlacedRgbAlpha(int y, byte[] buffer)
public String suggestFileExtension(PixelImage image)
ImageCodec
PNMCodec
).
This default implementation always returns null
.suggestFileExtension
in class ImageCodec
image
- the image that is to be written to a filenull
if no file extension can be recommended