Pergunta

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.

  • I can manipulate the PNG files before transferring them to the microcontroller.
  • The data is actually be read inside the callback function registerd with png_set_read_fn.

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?

Foi útil?

Solução

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);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top