harper
harper

Reputation: 13690

Improve performance with libpng

I have a microcontroller with a LCD display. I need to display several PNG images. Since the performance of the microcontroller is limited the time to display an image is too large.

I made benchmarks and detected that the most time is spent in the libpng and not in accessing the display memory or the storage where the (compressed) file is located.

Edit: The pictures are encoded with 8 bits per color plus transparency resulting in 32 bits per pixel. But most of the pictures have gray colors.

Here is the sequence of functions that I use to convert:

png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, show_png_error, show_png_warn);
info_ptr = png_create_info_struct(png_ptr);
end_info = png_create_info_struct(png_ptr);
png_set_user_limits(png_ptr, MAX_X, MAX_Y);
png_set_read_fn(png_ptr, 0, &read_callback);
png_set_sig_bytes(png_ptr, 0);
png_read_info(png_ptr, info_ptr);
png_read_update_info(png_ptr, info_ptr);
result->image = malloc(required_size);
height = png_get_image_height(png_ptr, info_ptr);
png_bytep *row_pointers = malloc(sizeof(void*) * height);

for (i = 0; i < height; ++i)
    row_pointers[i] = result->image + (i * png_get_rowbytes(png_ptr, info_ptr));

png_set_invert_alpha(png_ptr);
png_read_image(png_ptr, row_pointers);
png_read_end(png_ptr, end_info);
free(row_pointers);
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);

What parameters should be considered to get the fastest decompression?

Upvotes: 4

Views: 3055

Answers (1)

Glenn Randers-Pehrson
Glenn Randers-Pehrson

Reputation: 12455

It depends upon the nature of the images.

For photos, pngcrush method 12 (filter type 1, zlib strategy 2, zlib level 2) works well. For images with 256 or fewer colors, method 7 (filter type 0, zlib level 9, zlib strategy 0) works well.

Method 12 also happens to be a very fast compressor but as I understand it, that does not matter to you. zlib strategy 2 is Huffman-only compression so the result is the same for any non-zero zlib compression level.

In your code, to obtain the same behavior as pngcrush method 7, use

 png_set_compression_level(png_ptr, 9);
 png_set_compression_strategy(png_ptr, 0);
 png_set_filter(png_ptr,PNG_FILTER_NONE);

and to get pngcrush method 12 behavior,

 png_set_compression_level(png_ptr, 2);
 png_set_compression_strategy(png_ptr, 2);
 png_set_filter(png_ptr,PNG_FILTER_SUB);

Upvotes: 4

Related Questions