Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PNG_ALL_FILTERS, adaptive filtering in php gd

In PHP GD, what does the PNG_ALL_FILTERS do and how is that related to "adaptive filtering" of png images?

Background

In php, the imagepng function from the GD library has a parameter for filters. The documentation on the filter type constants allowed only "reveals" that these constants represent:

A special PNG filter, used by the imagepng() function

Very helpful indeed.

This answer on SO tells more, but lacks information on the constant PNG_ALL_FILTERS. To me, it seems that the other filters are mutually exclusive, so what does "all" do?

In my search, I found that for png filtering, a good strategy (under certain circumstances) would be to pick the most optimal filter for each scan line separately, called "adaptive filtering".

Considering the above, I would guess that "adaptive filtering" is accomplished with the PNG_ALL_FILTERS option. Am I guessing right? If not, what does PNG_ALL_FILTERS do? And can I get GD to do adaptive filtering from php?

Thanks a lot!

like image 576
Marten Koetsier Avatar asked May 04 '14 10:05

Marten Koetsier


1 Answers

GD uses libpng.

The libpng manpage says essentially what the pngimage description said. If that's "far from a confirmation" then you'll need to read the libpng source for confirmation. In libpng's png.h, the macros are defined:

/* Flags for png_set_filter() to say which filters to use. */
#define PNG_NO_FILTERS     0x00
#define PNG_FILTER_NONE    0x08
#define PNG_FILTER_SUB     0x10
#define PNG_FILTER_UP      0x20
#define PNG_FILTER_AVG     0x40
#define PNG_FILTER_PAETH   0x80
#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
                         PNG_FILTER_AVG | PNG_FILTER_PAETH)

The macros are used in png_write_find_filter(), which contains code like this:

if (filter_to_do & PNG_FILTER_SUB)
    [calculate figure of merit for the SUB filter]
else if (filter_to_do & PNG_FILTER_UP)
    [calculate figure of merit for the UP filter]
...
else if (filter_to_do & PNG_FILTER_PAETH)
    [calculate figure of merit for the PAETH filter]

Then select the filter with the lowest figure of merit for the scanline being written. The PNG_ALL_FILTERS macro simply provides a short way of enabling all filters for testing.

like image 80
Glenn Randers-Pehrson Avatar answered Sep 25 '22 02:09

Glenn Randers-Pehrson