Vebjorn Ljosa » Software » CL-PNG

CL-PNG

CL-PNG is a Common Lisp library for reading and writing PNG (Portable Network Graphics) files. It is currently maintained by Vebjorn Ljosa, and new versions can be found at the CL-PNG homepage, http://www.ljosa.com/~ljosa/software/cl-png/.

Copyright © 2001–2009 by the authors (see the file AUTHORS). Licensed under the GNU Lesser General Public License; see the file COPYING for details. This manual is in the public domain.

Table of contents:

  1. Status
  2. Download
  3. Installation
  4. Example
  5. API reference
  6. Symbol index

Status

Since version 0.5, CL-PNG uses a foreign function interface to call libpng, the official PNG reference library. As a result, it benefits from all the effort that has been put into that library: CL-PNG is much faster than before, and better able to handle corner cases.

The interface is likely to change in future versions. Please report on your experience with the current interface.

The current version has the following limitation:

CL-PNG 0.6 has been verified to work on the following platforms.

Please report success/failure on other platforms.

Download

Installation

CL-PNG depends on libpng (your operating system distribution may have a separate package, called libpng-dev or something similar, that contains the required png.h header file) and CFFI. CFFI in turn depends on Alexandria, Babel, and trivial-features.

If you have ASDF-INSTALL, installation is easy: the following takes care of CL-PNG and all dependencies:

    (asdf-install:install '#:png)

Otherwise, install the dependencies, then symlink png.asd (and, if you'd like to run the unit tests, png-test.asd) to one of the directories in asdf:*central-registry*. Then, evaluate (asdf:oos 'asdf:load-op '#:png) in order to compile and load CL-PNG.

On Mac OS X 10.4, you may discover that the C compiler does not accept the -m32 option that CFFI-Grovel attempts to pass to it. You will need to work around this, for instance by settings cffi-grovel::*cpu-word-size-flags* to the empty string.

If you would like to run the unit tests, evaluate (asdf:oos 'adsf:load-op '#:png-test) followed by (lisp-unit:run-all-tests #:png-test).

Example

(defun rotate (input-pathname output-pathname)
  "Read a PNG image, rotate it 90 degrees, and write it to a new file."
  (let* ((old (with-open-file (input input-pathname
                                     :element-type '(unsigned-byte 8)
)

                (png:decode input)
)
)

         (new (png:make-image (png:image-width old)
                              (png:image-height old)
                              (png:image-channels old)
)
)

         (m (png:image-width old))
)

      (dotimes (i (png:image-height new))
        (dotimes (j (png:image-width new))
          (dotimes (k (png:image-channels new))
            (setf (aref new i j k) (aref old j (- m i 1) k))
)
)
)

      (with-open-file (output output-pathname :element-type '(unsigned-byte 8)
                              :direction :output :if-exists :supersede
)

        (png:encode new output)
)
)
)

API reference

Type IMAGE

Supertypes:

array, t

Description:

An image is a three-dimensional array of (unsigned-byte 8) or (unsigned-byte 16). The three dimensions represent row, column, and channel. In other words, (aref image i j k) is the intensity in the k-th channel of the pixel in the i-th row and j-th column of image.

In the current version, an image is displaced to a one-dimensional simple-array with the same total number of elements, but applications should not rely on this implementation detail, as it is likely to change in future versions. The functions make-image, decode, copy-image, 8-bit-image, and 16-bit-image return images.

Compound Type Specifier Kind:

Specializing.

Compound Type Specifier Syntax:

image [{ height | * } { width | * } { channels | * }]

Compound Type Specifier Arguments:

height, width, channels---valid array dimensions


Type 8-BIT-IMAGE

Supertypes:

image, array, t

Description:

An image with element type (unsigned-byte 8).

Compound Type Specifier Kind:

Specializing.

Compound Type Specifier Syntax:

8-bit-image [{ height | * } { width | * } { channels | * }]

Compound Type Specifier Arguments:

height, width, channels---valid array dimensions


Type 16-BIT-IMAGE

Supertypes:

image, array, t

Description:

An image with element type (unsigned-byte 16).

Compound Type Specifier Kind:

Specializing.

Compound Type Specifier Syntax:

8-bit-image [{ height | * } { width | * } { channels | * }]

Compound Type Specifier Arguments:

height, width, channels---valid array dimensions


Type GRAYSCALE-IMAGE

Supertypes:

image, array, t

Description:

An image with one channel.

Compound Type Specifier Kind:

Specializing.

Compound Type Specifier Syntax:

grayscale-image [{ height | * } { width | * }]

Compound Type Specifier Arguments:

height, width---valid array dimensions

Notes:

(grayscale-image n m) == (image n m 1)


Type RGB-IMAGE

Supertypes:

image, array, t

Description:

An image with three channels.

Compound Type Specifier Kind:

Specializing.

Compound Type Specifier Syntax:

rgb-image [{ height | * } { width | * }]

Compound Type Specifier Arguments:

height, width---valid array dimensions

Notes:

(rgb-image n m) == (image n m 3)


Function MAKE-IMAGE

Syntax:

make-image height width channels &optional bit-depth => image

Arguments and Values:

height, width, channels---valid array dimensions

bit-depth---either 8, or 16, or nil

image---an image

Description:

Makes a new image with the specified height, width, and number of channels. The image will be an 8-bit-image if bit-depth is 8 or nil, and a 16-bit-image if bit-depth is 16. The contents of the image are undefined.


Function IMAGE-HEIGHT

Syntax:

image-height image => height

Arguments and Values:

image---an image

height---a valid array dimension

Description:

Returns the height of image, i.e., the number of rows.


Function IMAGE-WIDTH

Syntax:

image-width image => width

Arguments and Values:

image---an image

width---a valid array dimension

Description:

Returns the width of image, i.e., the number of columns.


Function IMAGE-CHANNELS

Syntax:

image-channels image => channels

Arguments and Values:

image---an image

channels---a valid array dimension

Description:

Returns the number of channels in image. Grayscale images have one channel, whereas RGB images have three.


Function IMAGE-BIT-DEPTH

Syntax:

image-bit-depth image => bit-depth

Arguments and Values:

image---an image

bit-depth---either 8 or 16

Description:

Returns the bit-depth of the image, i.e., the number of bits in the byte representing each sample. The bit depth of an 8-bit-image is 8, and the bit-depth of a 16-bit-image is 16.


Function COPY-IMAGE

Syntax:

copy-image image => copied-image

Arguments and Values:

image---an image

copied-image---an image

Description:

Creates a copy of image. The elements of the new image are the same as the corresponding elements of image, and copied-image has the same height, width, number of channels, and bit depth as image.


Function 8-BIT-IMAGE

Syntax:

8-bit-image image => result-image

Arguments and Values:

image---an image

result-image---an image

Description:

If image is an 8-bit-image, return it or a copy of it. If image is a 16-bit-image, return an 8-bit-image that has the same width, height, and number of channels as image, but where each element is the corresponding element in image divided by 257 and rounded to the nearest integer. The effect of this division is to compress the dynamic range of the image so as to fit within the smaller bit depth.


Function 16-BIT-IMAGE

Syntax:

16-bit-image image => result-image

Arguments and Values:

image---an image

result-image---an image

Description:

If image is a 16-bit-image, return it or a copy of it. If image is an 8-bit-image, return a 16-bit-image that has the same width, height, and number of channels as image, but where each element is the corresponding element in image multiplied by 257. The effect of this multiplication is to stretch the dynamic range of the image to utilize the increased bit depth.


Function DECODE

Syntax:

decode input => image

Arguments and Values:

input---an fd input stream

image---an image

Description:

Reads an image in PNG format from input and returns an array of type image. If the bit depth of the PNG file is less than or equal to 8, an 8-bit-image will be returned; otherwise, a 16-bit-image will be returned.

Applications that would like to receive images of consistent bit depth (rather than 8 or 16 depending on the PNG file) can apply the function 8-bit-image or the function 16-bit-image to the result of decode.

An image with bit depths below 8 will be converted to 8 bits when read, and an image with bit depths between 8 and 16 bits will be converted to 16 bits. As an example, a 2-bit PNG file contains only the pixel values 0, 1, 2, and 3. These will be converted to 0, 85, 170, and 255, respectively, in order to fill the dynamic range of the 8-bit image that is returned.

Exceptional Situations:

Signals an error if reading the image fails.


Function ENCODE

Syntax:

encode image output => t

Arguments and Values:

image---a grayscale-image or rgb-image

output---an fd output stream

Description:

Writes image in PNG format to output. The current version always writes an 8-bit PNG file if image is an 8-bit-image and a 16-bit PNG file if image is an 16-bit-image. Future versions may write PNG files of lower bit depths than image when the least significant bits may be trimmed without loss of precision.

Exceptional Situations:

Signals an error if writing the image fails.


SYMBOL INDEX:


Last updated: 2009-02-08