function create_png($gzimage, $width, $height) { // SIG $image = pack('C8', 137, 80, 78, 71, 13, 10, 26, 10); // IHDR $raw = pack('C4', $width >> 24, $width >> 16, $width >> 8, $width); $raw .= pack('C4', $height >> 24, $height >> 16, $height >> 8, $height); $raw .= pack('C5', 8, 0, 0, 0, 0); $image .= png_chunk(13, 'IHDR', $raw); // IDAT $image .= png_chunk(strlen($gzimage), 'IDAT', $gzimage); // IEND $image .= png_chunk(0, 'IEND', ''); return $image; }
function create_png($raw_image, $width, $height) { // SIG $image = pack('C8', 137, 80, 78, 71, 13, 10, 26, 10); // IHDR $raw = pack('C4', $width >> 24, $width >> 16, $width >> 8, $width); $raw .= pack('C4', $height >> 24, $height >> 16, $height >> 8, $height); $raw .= pack('C5', 8, 0, 0, 0, 0); $image .= png_chunk(13, 'IHDR', $raw); if (@extension_loaded('zlib')) { $raw_image = gzcompress($raw_image); $length = strlen($raw_image); } else { // The total length of this image, uncompressed, is just a calculation of pixels $length = ($width + 1) * $height; // Adler-32 hash generation // Optimized Adler-32 loop ported from the GNU Classpath project $temp_length = $length; $s1 = 1; $s2 = $index = 0; while ($temp_length > 0) { // We can defer the modulo operation: // s1 maximally grows from 65521 to 65521 + 255 * 3800 // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 $substract_value = $temp_length < 3800 ? $temp_length : 3800; $temp_length -= $substract_value; while (--$substract_value >= 0) { $s1 += ord($raw_image[$index]); $s2 += $s1; $index++; } $s1 %= 65521; $s2 %= 65521; } $adler_hash = pack('N', $s2 << 16 | $s1); // This is the same thing as gzcompress($raw_image, 0) but does not need zlib $raw_image = pack('C3v2', 0x78, 0x1, 0x1, $length, ~$length) . $raw_image . $adler_hash; // The Zlib header + Adler hash make us add on 11 $length += 11; } // IDAT $image .= png_chunk($length, 'IDAT', $raw_image); // IEND $image .= png_chunk(0, 'IEND', ''); return $image; }