blob: da3befc5db4b1b199638507118ac35ab3803a525 [file] [log] [blame]
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);
}