Usage¶
The context must be created with the SPNG_CTX_ENCODER
flag set.
Before any (implicit) write operation an output must be set with spng_set_png_stream() or spng_set_png_file().
Alternatively the SPNG_ENCODE_TO_BUFFER
option can be enabled with spng_set_option(),
in this case the encoder will create and manage an internal output buffer,
it is freed by spng_ctx_free()
unless it’s retrieved with spng_get_png_buffer()
.
In all cases the PNG must be explicitly finalized, this can be done with the SPNG_ENCODE_FINALIZE
flag or with a call to
spng_encode_chunks()
after the image has been encoded.
Memory usage¶
On top of the overhead of the the context buffer the internal write buffer may grow to the length of entire chunks or more than the length of the PNG file when encoding to the internal buffer.
Encoding an image requires at least 2 rows to be kept in memory, this may increase to 3 rows for future versions.
Data types¶
spng_encode_flags¶
enum spng_encode_flags
{
SPNG_ENCODE_PROGRESSIVE = 1, /* Initialize for progressive writes */
SPNG_ENCODE_FINALIZE = 2, /* Finalize PNG after encoding image */
};
API¶
spng_encode_chunks()¶
int spng_encode_chunks(spng_ctx *ctx)
Encode all stored chunks before or after the image data (IDAT) stream, depending on the state of the encoder.
If the image is encoded this function will also finalize the PNG with the end-of-file (IEND) marker.
Calling this function before spng_encode_image()
is optional.
spng_encode_image()¶
int spng_encode_image(spng_ctx *ctx, const void *img, size_t len, int fmt, int flags)
Encodes the image from img
in the source format fmt
to the specified PNG format set with spng_set_ihdr().
The width, height, color type, bit depth and interlace method must be set with spng_set_ihdr().
If the color type is set to SPNG_COLOR_TYPE_INDEXED
a palette must be set with spng_set_plte().
img
must point to a buffer of length len
, len
must be equal to the expected image
size for the given format fmt
.
This function may call spng_encode_chunks()
, writing any pending chunks before the image data.
If the SPNG_ENCODE_FINALIZE
flag is set this function will call spng_encode_chunks()
on the last
scanline/row, writing any pending chunks after the image data and finalize the PNG with the
end-of-file (IEND) marker before returning.
In most cases the only data after the image is the 12-byte IEND marker.
When the image is encoded to an internal buffer and the PNG is finalized spng_get_png_buffer() will return the encoded buffer, this must be freed by the user. If this function isn’t called or an error is encountered the internal buffer is freed by spng_ctx_free().
Supported format, flag combinations¶
Input format | PNG Format | Flags | Notes |
---|---|---|---|
SPNG_FMT_PNG |
Any format* | All | Converted from host-endian if required |
SPNG_FMT_RAW |
Any format* | All | No conversion (assumes big-endian) |
* Any combination of color type and bit depth defined in the standard.
16-bit images are assumed to be host-endian except for SPNG_FMT_RAW
.
The alpha channel is always straight alpha, premultiplied alpha is not supported.
Compression level and other options can be customized with spng_set_option()
,
see Encode options for all options.
Note that encoder options are optimized based on PNG format and compression level,
overriding other options such as filtering may disable some of these optimizations.
Progressive image encoding¶
If the SPNG_ENCODE_PROGRESSIVE
flag is set the encoder will be initialized
with fmt
and flags
for progressive encoding, the values of img
, len
are ignored.
With the SPNG_ENCODE_FINALIZE
flag set the PNG is finalized on the last scanline
or row.
Progressive encoding is straightforward when the image is not interlaced,
calling spng_encode_row() for each row of the image will yield
the return value SPNG_EOI
for the final row:
int error;
size_t image_width = image_size / ihdr.height;
for(i = 0; i < ihdr.height; i++)
{
void *row = image + image_width * i;
error = spng_encode_row(ctx, row, image_width);
if(error) break;
}
if(error == SPNG_EOI) /* success */
But for interlaced images (spng_ihdr.interlaced_method
set to 1
)
rows are accessed multiple times and non-sequentially,
use spng_get_row_info() to get the current row number:
int error;
struct spng_row_info row_info;
do
{
error = spng_get_row_info(ctx, &row_info);
if(error) break;
void *row = image + image_width * row_info.row_num;
error = spng_encode_row(ctx, row, len);
}
while(!error)
if(error == SPNG_EOI) /* success */
spng_encode_scanline()¶
int spng_encode_scanline(spng_ctx *ctx, const void *scanline, size_t len)
Encodes scanline
, this function is meant to be used for interlaced PNG’s
with image data that is already split into multiple passes.
This function requires the encoder to be initialized by calling
spng_encode_image()
with the SPNG_ENCODE_PROGRESSIVE
flag set.
For the last scanline and subsequent calls the return value is SPNG_EOI
.
spng_encode_row()¶
int spng_encode_row(spng_ctx *ctx, const void *row, size_t len)
Encodes row
, interlacing it if necessary.
This function requires the encoder to be initialized by calling
spng_encode_image()
with the SPNG_ENCODE_PROGRESSIVE
flag set.
See also: Progressive-image-encoding
For the last row and subsequent calls the return value is SPNG_EOI
.
If the image is not interlaced this function’s behavior is identical to
spng_encode_scanline()
.
spng_get_png_buffer()¶
void *spng_get_png_buffer(spng_ctx *ctx, size_t *len, int *error)
If SPNG_ENCODE_TO_BUFFER
is enabled via spng_set_option() the encoded buffer is returned,
it must be called after spng_encode_image() and the PNG must be finalized.
On success the buffer must be freed by the user.
Encode options¶
Option | Default value | Description |
---|---|---|
SPNG_IMG_COMPRESSION_LEVEL |
Z_DEFAULT_COMPRESSION |
Set image compression level (0-9) |
SPNG_IMG_WINDOW_BITS |
15 * |
Set image zlib window bits (9-15) |
SPNG_IMG_MEM_LEVEL |
8 |
Set zlib memLevel for images |
SPNG_IMG_COMPRESSION_STRATEGY |
Z_FILTERED * |
Set image compression strategy |
SPNG_TEXT_COMPRESSION_LEVEL |
Z_DEFAULT_COMPRESSION |
Set text compression level (0-9) |
SPNG_TEXT_WINDOW_BITS |
15 |
Set text zlib window bits (9-15) |
SPNG_TEXT_MEM_LEVEL |
8 |
Set zlib memLevel for text |
SPNG_TEXT_COMPRESSION_STRATEGY |
Z_DEFAULT_STRATEGY |
Set text compression strategy |
SPNG_FILTER_CHOICE |
SPNG_FILTER_CHOICE_ALL * |
Configure or disable filtering |
SPNG_ENCODE_TO_BUFFER |
0 |
Encode to internal buffer |
* Option may be optimized if not set explicitly.
Options not listed here have no effect on encoders.
Performance¶
The default encoder settings match the reference implementation
and will produce files of the exact same size, but there are settings that offer
better performance for a small increase in file size. Reducing compression level (set SPNG_IMG_COMPRESSION_LEVEL
to a value lower than 6
) will reduce encoding time for all image types.
-
Truecolor images - Reduce compression level (between
1
and5
) and leave everything else on defaults, file size should not increase by more than 10% but encode up to three times faster. -
Indexed-color - Choose a reduced compression level (
1
-5
), file size should stay within 5% but encode up to two times faster. -
Grayscale - Choose a reduced compression level (
1
-5
), file size should stay within 5% but encode up to two times faster. -
Grayscale-alpha images - Choose a reduced compression level (
1
-5
), file size should stay within 5% but encode up to four times faster. -
Disabling filtering may further improve performance but will significantly increase file size.
Note
See encode experiments for more details.
Recommendations are based on benchmarks with zlib, performance with other implementations (miniz, zlib-ng) was not measured.