com.keypoint

## Class PngEncoder

- java.lang.Object
- - com.keypoint.PngEncoder

-     public class PngEncoder
      extends java.lang.Object

  PngEncoder takes a Java Image object and creates a byte string which can be saved as a PNG file. The Image is presumed to use the DirectColorModel.

  Thanks to Jay Denny at KeyPoint Software http://www.keypoint.com/ who let me develop this code on company time.

  You may contact me with (probably very-much-needed) improvements, comments, and bug fixes at:

  `david@catcode.com`

  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; either version 2.1 of the License, or (at your option) any later version.

  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.

  You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. A copy of the GNU LGPL may be found at `http://www.gnu.org/copyleft/lesser.html`

  Version:
    1.5, 19 Oct 2003 CHANGES: -------- 19-Nov-2002 : CODING STYLE CHANGES ONLY (by David Gilbert for Object Refinery Limited); 19-Sep-2003 : Fix for platforms using EBCDIC (contributed by Paulo Soares); 19-Oct-2003 : Change private fields to protected fields so that PngEncoderB can inherit them (JDE) Fixed bug with calculation of nRows 15-Aug-2008 : Added scrunch.end() in writeImageData() method - see JFreeChart bug report 2037930 (David Gilbert);
  Author:
    J. David Eisenberg

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected int` | `bytePos` The byte position.
    `protected int` | `bytesPerPixel` The bytes-per-pixel.
    `protected int` | `compressionLevel` The compression level (1 = best speed, 9 = best compression, 0 = no compression).
    `protected java.util.zip.CRC32` | `crc` CRC.
    `protected long` | `crcValue` The CRC value.
    `static boolean` | `ENCODE_ALPHA` Constant specifying that alpha channel should be encoded.
    `protected boolean` | `encodeAlpha` Encode alpha?
    `protected int` | `filter` The filter type.
    `static int` | `FILTER_LAST` Constants for filter (LAST).
    `static int` | `FILTER_NONE` Constants for filter (NONE).
    `static int` | `FILTER_SUB` Constants for filter (SUB).
    `static int` | `FILTER_UP` Constants for filter (UP).
    `protected int` | `height` The height.
    `protected static byte[]` | `IDAT` IDAT tag.
    `protected static byte[]` | `IEND` IEND tag.
    `protected static byte[]` | `IHDR` IHDR tag.
    `protected java.awt.Image` | `image` The image.
    `protected byte[]` | `leftBytes` The left bytes.
    `protected int` | `maxPos` The maximum position.
    `static boolean` | `NO_ALPHA` Constant specifying that alpha channel should not be encoded.
    `protected static byte[]` | `PHYS` PHYS tag.
    `protected byte[]` | `pngBytes` The png bytes.
    `protected byte[]` | `priorRow` The prior row.
    `protected int` | `width` The width.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `PngEncoder()` Class constructor.
    `PngEncoder(java.awt.Image image)` Class constructor specifying Image to encode, with no alpha channel encoding.
    `PngEncoder(java.awt.Image image, boolean encodeAlpha)` Class constructor specifying Image to encode, and whether to encode alpha.
    `PngEncoder(java.awt.Image image, boolean encodeAlpha, int whichFilter)` Class constructor specifying Image to encode, whether to encode alpha, and filter to use.
    `PngEncoder(java.awt.Image image, boolean encodeAlpha, int whichFilter, int compLevel)` Class constructor specifying Image source to encode, whether to encode alpha, filter to use, and compression level.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected void` | `filterSub(byte[] pixels, int startPos, int width)` Perform "sub" filtering on the given row.
    `protected void` | `filterUp(byte[] pixels, int startPos, int width)` Perform "up" filtering on the given row.
    `int` | `getCompressionLevel()` Retrieve compression level.
    `boolean` | `getEncodeAlpha()` Retrieve alpha encoding status.
    `int` | `getFilter()` Retrieve filtering scheme.
    `java.awt.Image` | `getImage()` Returns the image to be encoded.
    `int` | `getXDpi()` Get the DPI for the X axis.
    `int` | `getYDpi()` Get the DPI for the Y axis.
    `byte[]` | `pngEncode()` Creates an array of bytes that is the PNG equivalent of the current image.
    `byte[]` | `pngEncode(boolean encodeAlpha)` Creates an array of bytes that is the PNG equivalent of the current image, specifying whether to encode alpha or not.
    `protected byte[]` | `resizeByteArray(byte[] array, int newLength)` Increase or decrease the length of a byte array.
    `void` | `setCompressionLevel(int level)` Set the compression level to use.
    `void` | `setDpi(int xDpi, int yDpi)` Set the DPI resolution.
    `void` | `setEncodeAlpha(boolean encodeAlpha)` Set the alpha encoding on or off.
    `void` | `setFilter(int whichFilter)` Set the filter to use.
    `void` | `setImage(java.awt.Image image)` Set the image to be encoded.
    `void` | `setXDpi(int xDpi)` Set the DPI for the X axis.
    `void` | `setYDpi(int yDpi)` Set the DPI for the Y axis.
    `protected int` | `writeByte(int b, int offset)` Write a single byte into the pngBytes array at a given position.
    `protected int` | `writeBytes(byte[] data, int offset)` Write an array of bytes into the pngBytes array.
    `protected int` | `writeBytes(byte[] data, int nBytes, int offset)` Write an array of bytes into the pngBytes array, specifying number of bytes to write.
    `protected void` | `writeEnd()` Write a PNG "IEND" chunk into the pngBytes array.
    `protected void` | `writeHeader()` Write a PNG "IHDR" chunk into the pngBytes array.
    `protected boolean` | `writeImageData()` Write the image data into the pngBytes array.
    `protected int` | `writeInt2(int n, int offset)` Write a two-byte integer into the pngBytes array at a given position.
    `protected int` | `writeInt4(int n, int offset)` Write a four-byte integer into the pngBytes array at a given position.
    `protected void` | `writeResolution()` Write a PNG "pHYs" chunk into the pngBytes array.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### ENCODE_ALPHA

          public static final boolean ENCODE_ALPHA

      Constant specifying that alpha channel should be encoded.
      See Also:
        Constant Field Values

    - #### NO_ALPHA

          public static final boolean NO_ALPHA

      Constant specifying that alpha channel should not be encoded.
      See Also:
        Constant Field Values

    - #### FILTER_NONE

          public static final int FILTER_NONE

      Constants for filter (NONE).
      See Also:
        Constant Field Values

    - #### FILTER_SUB

          public static final int FILTER_SUB

      Constants for filter (SUB).
      See Also:
        Constant Field Values

    - #### FILTER_UP

          public static final int FILTER_UP

      Constants for filter (UP).
      See Also:
        Constant Field Values

    - #### FILTER_LAST

          public static final int FILTER_LAST

      Constants for filter (LAST).
      See Also:
        Constant Field Values

    - #### IHDR

          protected static final byte[] IHDR

      IHDR tag.

    - #### IDAT

          protected static final byte[] IDAT

      IDAT tag.

    - #### IEND

          protected static final byte[] IEND

      IEND tag.

    - #### PHYS

          protected static final byte[] PHYS

      PHYS tag.

    - #### pngBytes

          protected byte[] pngBytes

      The png bytes.

    - #### priorRow

          protected byte[] priorRow

      The prior row.

    - #### leftBytes

          protected byte[] leftBytes

      The left bytes.

    - #### image

          protected java.awt.Image image

      The image.

    - #### width

          protected int width

      The width.

    - #### height

          protected int height

      The height.

    - #### bytePos

          protected int bytePos

      The byte position.

    - #### maxPos

          protected int maxPos

      The maximum position.

    - #### crc

          protected java.util.zip.CRC32 crc

      CRC.

    - #### crcValue

          protected long crcValue

      The CRC value.

    - #### encodeAlpha

          protected boolean encodeAlpha

      Encode alpha?

    - #### filter

          protected int filter

      The filter type.

    - #### bytesPerPixel

          protected int bytesPerPixel

      The bytes-per-pixel.

    - #### compressionLevel

          protected int compressionLevel

      The compression level (1 = best speed, 9 = best compression, 0 = no compression).

  - ### Constructor Detail

    - #### PngEncoder

          public PngEncoder()

      Class constructor.

    - #### PngEncoder

          public PngEncoder(java.awt.Image image)

      Class constructor specifying Image to encode, with no alpha channel encoding.
      Parameters:
        `image` - A Java Image object which uses the DirectColorModel
      See Also:
        `Image`

    - #### PngEncoder

          public PngEncoder(java.awt.Image image,
                            boolean encodeAlpha)

      Class constructor specifying Image to encode, and whether to encode alpha.
      Parameters:
        `image` - A Java Image object which uses the DirectColorModel
        `encodeAlpha` - Encode the alpha channel? false=no; true=yes
      See Also:
        `Image`

    - #### PngEncoder

          public PngEncoder(java.awt.Image image,
                            boolean encodeAlpha,
                            int whichFilter)

      Class constructor specifying Image to encode, whether to encode alpha, and filter to use.
      Parameters:
        `image` - A Java Image object which uses the DirectColorModel
        `encodeAlpha` - Encode the alpha channel? false=no; true=yes
        `whichFilter` - 0=none, 1=sub, 2=up
      See Also:
        `Image`

    - #### PngEncoder

          public PngEncoder(java.awt.Image image,
                            boolean encodeAlpha,
                            int whichFilter,
                            int compLevel)

      Class constructor specifying Image source to encode, whether to encode alpha, filter to use, and compression level.
      Parameters:
        `image` - A Java Image object
        `encodeAlpha` - Encode the alpha channel? false=no; true=yes
        `whichFilter` - 0=none, 1=sub, 2=up
        `compLevel` - 0..9 (1 = best speed, 9 = best compression, 0 = no compression)
      See Also:
        `Image`

  - ### Method Detail

    - #### setImage

          public void setImage(java.awt.Image image)

      Set the image to be encoded.
      Parameters:
        `image` - A Java Image object which uses the DirectColorModel
      See Also:
        `Image`, `DirectColorModel`

    - #### getImage

          public java.awt.Image getImage()

      Returns the image to be encoded.
      Returns:
        The image.

    - #### pngEncode

          public byte[] pngEncode(boolean encodeAlpha)

      Creates an array of bytes that is the PNG equivalent of the current image, specifying whether to encode alpha or not.
      Parameters:
        `encodeAlpha` - boolean false=no alpha, true=encode alpha
      Returns:
        an array of bytes, or null if there was a problem

    - #### pngEncode

          public byte[] pngEncode()

      Creates an array of bytes that is the PNG equivalent of the current image. Alpha encoding is determined by its setting in the constructor.
      Returns:
        an array of bytes, or null if there was a problem

    - #### setEncodeAlpha

          public void setEncodeAlpha(boolean encodeAlpha)

      Set the alpha encoding on or off.
      Parameters:
        `encodeAlpha` - false=no, true=yes

    - #### getEncodeAlpha

          public boolean getEncodeAlpha()

      Retrieve alpha encoding status.
      Returns:
        boolean false=no, true=yes

    - #### setFilter

          public void setFilter(int whichFilter)

      Set the filter to use.
      Parameters:
        `whichFilter` - from constant list

    - #### getFilter

          public int getFilter()

      Retrieve filtering scheme.
      Returns:
        int (see constant list)

    - #### setCompressionLevel

          public void setCompressionLevel(int level)

      Set the compression level to use.
      Parameters:
        `level` - the compression level (1 = best speed, 9 = best compression, 0 = no compression)

    - #### getCompressionLevel

          public int getCompressionLevel()

      Retrieve compression level.
      Returns:
        int (1 = best speed, 9 = best compression, 0 = no compression)

    - #### resizeByteArray

          protected byte[] resizeByteArray(byte[] array,
                                           int newLength)

      Increase or decrease the length of a byte array.
      Parameters:
        `array` - The original array.
        `newLength` - The length you wish the new array to have.
      Returns:
        Array of newly desired length. If shorter than the original, the trailing elements are truncated.

    - #### writeBytes

          protected int writeBytes(byte[] data,
                                   int offset)

      Write an array of bytes into the pngBytes array. Note: This routine has the side effect of updating maxPos, the largest element written in the array. The array is resized by 1000 bytes or the length of the data to be written, whichever is larger.
      Parameters:
        `data` - The data to be written into pngBytes.
        `offset` - The starting point to write to.
      Returns:
        The next place to be written to in the pngBytes array.

    - #### writeBytes

          protected int writeBytes(byte[] data,
                                   int nBytes,
                                   int offset)

      Write an array of bytes into the pngBytes array, specifying number of bytes to write. Note: This routine has the side effect of updating maxPos, the largest element written in the array. The array is resized by 1000 bytes or the length of the data to be written, whichever is larger.
      Parameters:
        `data` - The data to be written into pngBytes.
        `nBytes` - The number of bytes to be written.
        `offset` - The starting point to write to.
      Returns:
        The next place to be written to in the pngBytes array.

    - #### writeInt2

          protected int writeInt2(int n,
                                  int offset)

      Write a two-byte integer into the pngBytes array at a given position.
      Parameters:
        `n` - The integer to be written into pngBytes.
        `offset` - The starting point to write to.
      Returns:
        The next place to be written to in the pngBytes array.

    - #### writeInt4

          protected int writeInt4(int n,
                                  int offset)

      Write a four-byte integer into the pngBytes array at a given position.
      Parameters:
        `n` - The integer to be written into pngBytes.
        `offset` - The starting point to write to.
      Returns:
        The next place to be written to in the pngBytes array.

    - #### writeByte

          protected int writeByte(int b,
                                  int offset)

      Write a single byte into the pngBytes array at a given position.
      Parameters:
        `b` - The integer to be written into pngBytes.
        `offset` - The starting point to write to.
      Returns:
        The next place to be written to in the pngBytes array.

    - #### writeHeader

          protected void writeHeader()

      Write a PNG "IHDR" chunk into the pngBytes array.

    - #### filterSub

          protected void filterSub(byte[] pixels,
                                   int startPos,
                                   int width)

      Perform "sub" filtering on the given row. Uses temporary array leftBytes to store the original values of the previous pixels. The array is 16 bytes long, which will easily hold two-byte samples plus two-byte alpha.
      Parameters:
        `pixels` - The array holding the scan lines being built
        `startPos` - Starting position within pixels of bytes to be filtered.
        `width` - Width of a scanline in pixels.

    - #### filterUp

          protected void filterUp(byte[] pixels,
                                  int startPos,
                                  int width)

      Perform "up" filtering on the given row. Side effect: refills the prior row with current row
      Parameters:
        `pixels` - The array holding the scan lines being built
        `startPos` - Starting position within pixels of bytes to be filtered.
        `width` - Width of a scanline in pixels.

    - #### writeImageData

          protected boolean writeImageData()

      Write the image data into the pngBytes array. This will write one or more PNG "IDAT" chunks. In order to conserve memory, this method grabs as many rows as will fit into 32K bytes, or the whole image; whichever is less.
      Returns:
        true if no errors; false if error grabbing pixels

    - #### writeEnd

          protected void writeEnd()

      Write a PNG "IEND" chunk into the pngBytes array.

    - #### setXDpi

          public void setXDpi(int xDpi)

      Set the DPI for the X axis.
      Parameters:
        `xDpi` - The number of dots per inch

    - #### getXDpi

          public int getXDpi()

      Get the DPI for the X axis.
      Returns:
        The number of dots per inch

    - #### setYDpi

          public void setYDpi(int yDpi)

      Set the DPI for the Y axis.
      Parameters:
        `yDpi` - The number of dots per inch

    - #### getYDpi

          public int getYDpi()

      Get the DPI for the Y axis.
      Returns:
        The number of dots per inch

    - #### setDpi

          public void setDpi(int xDpi,
                             int yDpi)

      Set the DPI resolution.
      Parameters:
        `xDpi` - The number of dots per inch for the X axis.
        `yDpi` - The number of dots per inch for the Y axis.

    - #### writeResolution

          protected void writeResolution()

      Write a PNG "pHYs" chunk into the pngBytes array.