| From: Maks Orlovich <morlovich@google.com> |
| Subject: Provide a custom allocation wrapper for libpng, that mostly just uses |
| malloc, but makes sure that padding bytes at very end are deterministically |
| zero. |
| . |
| Reason: Testing on native builds on Debian Sid suggested that *something* in |
| our compression stack was apparently letting some of the padding bytes |
| influence the output. (Noticeable on PngOptimizerTest.ValidPngs). |
| This works around the issue. |
| Origin: upstream, https://github.com/pagespeed/mod_pagespeed/commit/a99ea36b31e78abd24ec83cb0b7cbde407f4e517 |
| --- a/src/pagespeed/kernel/image/png_optimizer.cc |
| +++ b/src/pagespeed/kernel/image/png_optimizer.cc |
| @@ -49,6 +49,28 @@ |
| |
| namespace { |
| |
| +// A wrapper that ensures that any padding bytes are initialized |
| +// deterministically. |
| +void* PngWrapMalloc(png_structp ptr, png_size_t size) { |
| + if ((size & 7) == 0) { |
| + return malloc(size); |
| + } else { |
| + png_size_t extra = 8 - (size & 7); |
| + png_size_t rounded = size + extra; |
| + DCHECK_NE(rounded, 0); |
| + if (rounded == 0) { |
| + return nullptr; |
| + } |
| + char* p = reinterpret_cast<char*>(malloc(rounded)); |
| + memset(p + (rounded - 8), 0, 8); |
| + return p; |
| + } |
| +} |
| + |
| +static void PngWrapFree(png_structp, png_voidp ptr) { |
| + free(ptr); |
| +} |
| + |
| // we use these four combinations because different images seem to benefit from |
| // different parameters and this combination of 4 seems to work best for a large |
| // set of PNGs from the web. |
| @@ -184,6 +206,7 @@ |
| info_ptr_ = png_create_info_struct(png_ptr_); |
| } |
| |
| + png_set_mem_fn(png_ptr_, nullptr, &PngWrapMalloc, &PngWrapFree); |
| png_set_error_fn(png_ptr_, message_handler_, &PngErrorFn, &PngWarningFn); |
| } |
| |