very small PNG decoding library
Switch branches/tags
Nothing to show
Clone or download
Latest commit 01937b7 Jan 15, 2017

README

uPNG -- derived from LodePNG version 20100808
==========================================

Copying
-------

Copyright (c) 2005-2010 Lode Vandevenne
Copyright (c) 2010 Sean Middleditch

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
  claim that you wrote the original software. If you use this software
  in a product, an acknowledgment in the product documentation would be
  appreciated but is not required.

  2. Altered source versions must be plainly marked as such, and must not be
  misrepresented as being the original software.

  3. This notice may not be removed or altered from any source
  distribution.

Features
--------

uPNG supports loading and decoding PNG images into a simple byte buffer, suitable
for passing directly to OpenGL as texture data.

uPNG does NOT support interlaced images, paletted images, and fixed-transparency.
Checksums are NOT verified and corrupt image data may be undetected.

It DOES support RGB, RGBA, greyscale, and greyscale-with-alpha images.  RGB and
RGBA are currently only supported in 8-bit color depths, and greyscale images
are supported in either 1-, 2-, 4-, or 8-bit color depths.

WARNING: the source project that uPNG is derived from, LodePNG, did not have
the cleanest or best documented code.  Several potential buffer overflows in the
original source have been fixed in uPNG, but there may be more.  Do NOT use uPNG
to load data from untrusted sources, e.g. the Web.  Doing so may open a
remotely exploitable buffer overflow attack in your application.

Installation
------------

Copy the upng.c and upng.h files into your project, and add them to your build
system.  upng.c will compile as C++ if necessary.

Usage
-----

To load a PNG, you must create an upng_t instance, load the raw PNG into the
decoder, and then you can query the upng_t for image properties and the
decoded image buffer.

  upng_t* upng;

  upng = upng_new_from_file("image.png");
  if (upng != NULL) {
    upng_decode(upng);
    if (upng_get_error(upng) == UPNG_EOK) {
      /* do stuff with image */
    }

    upng_free(upng);
  }

You can load a PNG either from an in-memory buffer of bytes or from a file
specified by file path.

  upng_new_from_bytes(const unsigned char*, unsigned long length)
  upng_new_from_file(const char*)

Once an upng_t object is created, you can read just its header properties,
decode the entire file, and release its resources.

  upng_header(upng_t*)  Reads just the header, sets image properties
  upng_decode(upng_t*)  Decodes image data
  upng_free(upng_t*)    Frees the resources attached to a upng_t object

The query functions are:

  upng_get_width(upng_t*)       Returns width of image in pixels
  upng_get_height(upng_t*)      Returns height of image in pixels
  upng_get_size(upng_t*)        Returns the total size of the image buffer in bytes
  upng_get_bpp(upng_t*)         Returns the number of bits per pixel (e.g., 32 for 8-bit RGBA)
  upng_get_bitdepth(upng_t*)    Returns the number of bits per component (e.g., 8 for 8-bit RGBA)
  upng_get_pixelsize(upng_t*)   Returns the number of bytes per pixel (e.g., 4 for 8-bit RGBA)
  upng_get_components(upng_t*)  Returns the number of components per pixel (e.g., 4 for 8-bit RGBA)
  upng_get_format(upng_t*)      Returns the format of the image buffer (see below)
  upng_get_buffer(upng_t*)      Returns a pointer to the image buffer

Additionally, for error handling, you can use:

  upng_get_error(upng_t*)       Returns the error state of the upng object (UPNG_EOK means no error)
  upng_get_error_line(upng_t*)  Returns the line in the upng.c file where the error state was set

The formats supported are:

  UPNG_RGB8         24-bit RGB
  UPNG_RGB16        48-bit RGB
  UPNG_RGBA8        32-bit RGBA
  UPNG_RGBA16       64-bit RGBA
  UPNG_LUMINANCE8   8-bit Greyscale
  UPNG_LUMINANCEA8  8-bit Greyscale w/ 8-bit Alpha

Possible error states are:

  UPNG_EOK          No error (success)
  UPNG_ENOMEM       Out of memory
  UPNG_ENOTFOUND    Resource not found
  UPNG_ENOTPNG      Invalid file header (not a PNG image)
  UPNG_EMALFORMED   PNG image data does not follow spec and is malformed
  UPNG_EUNSUPPORTED PNG image data is well-formed but not supported by uPNG

TODO
----

- Audit the code (particularly the Huffman decoder) for buffer overflows.  Make sure
  uPNG is safe to use even with image data from untrusted sources.

- Make the decompressor work in a streaming/buffered manner, so that we don't need
  to stitch together the PNG IDATA chunks before decompressing, shaving off one
  unnecessary allocation.

- Update the unfiltering code to work on the decompressed image buffer, rather than
  needing a separate output buffer.  The removal of the Adam7 de-interlacing support
  makes this easier.  Removes another unnecessary allocation.

- Update the decoder API to work in a stream/buffered manner, so files can be read
  without needing to allocate a temporary buffer.  This removes yet another
  unnecessary allocation.

- Update the decoder API to allow the user to provide an output buffer, so that
  PNG images can be decoded directly to mapped texture memory.  Removes the need
  for the last unnecessary allocation.

- Test that greyscale images with less than 8-bits of depth actually work, fix
  or remove if they do not.

- Provide optional format conversion (as an extension to byte swizzling) to
  convert input PNGs in one format to one of a (limited) set of target output
  formats commonly used for texturing.

- Provide floating-point conversion, at least for 16-bit source images, for
  HDR textures.

- Provide vertical flipping of decoded image data for APIs that prefer textures
  with an origin in the lower-left instead of upper-left.