PNG: Inform inflate about expected output size for extra speed.

This commit is contained in:
Jeroen van Rijn
2021-06-27 13:57:12 +02:00
parent eaf88bcc4d
commit 064516bf0b
+13 -11
View File
@@ -668,19 +668,13 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
return img, E_PNG.IDAT_Missing; return img, E_PNG.IDAT_Missing;
} }
buf: bytes.Buffer;
zlib_error := zlib.inflate(idat, &buf);
defer bytes.buffer_destroy(&buf);
if zlib_error != nil {
return {}, zlib_error;
} else {
/* /*
Let's calcalate the expected size of the IDAT based on its dimensions, Calculate the expected output size, to help `inflate` make better decisions about the output buffer.
and whether or not it's interlaced We'll also use it to check the returned buffer size is what we expected it to be.
Let's calcalate the expected size of the IDAT based on its dimensions, and whether or not it's interlaced.
*/ */
expected_size: int; expected_size: int;
buf_len := len(buf.buf);
if header.interlace_method != .Adam7 { if header.interlace_method != .Adam7 {
expected_size = compute_buffer_size(int(header.width), int(header.height), int(img.channels), int(header.bit_depth), 1); expected_size = compute_buffer_size(int(header.width), int(header.height), int(img.channels), int(header.bit_depth), 1);
@@ -698,10 +692,18 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
} }
} }
buf: bytes.Buffer;
zlib_error := zlib.inflate(idat, &buf, false, expected_size);
defer bytes.buffer_destroy(&buf);
if zlib_error != nil {
return {}, zlib_error;
}
buf_len := len(buf.buf);
if expected_size != buf_len { if expected_size != buf_len {
return {}, E_PNG.IDAT_Corrupt; return {}, E_PNG.IDAT_Corrupt;
} }
}
/* /*
Defilter just cares about the raw number of image channels present. Defilter just cares about the raw number of image channels present.