Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
#!/usr/bin/perl -w
use strict;
@ARGV or die "Usage: $0 PNGFILE...\nOutputs the file names of the PNG files with trailing data.";
FILE: while (@ARGV) {
my $fn = shift;
eval {
no warnings 'exiting';
open my $fh, "<", $fn;
read $fh, my $magic, 8;
$magic eq "\x89PNG\x0d\x0a\x1a\x0a" or next FILE;
while (1) {
read $fh, my $size_packed, 4;
my $size = unpack "N", $size_packed;
read $fh, my $ctype, 4;
#print "[$ctype=$size]", tell($fh), "\n";
seek $fh, $size + 4, 1; # skip data + checksum
last if $ctype eq "IEND";
next FILE if eof $fh;
next FILE if eof $fh;
my $extra = (-s $fn) - tell $fh;
next FILE if $extra <= 4;
print $fn, "\n";
warn "$fn: $@\n" if $@;
Copy link

Juerd commented Mar 22, 2023

Example use:

find images -type f -iname '*.png' -exec perl ~/Downloads/ {} + | tee -a acropalypse.list

This will scan all files with .png or .PNG extensions in the images directory and append the paths of suspect files to a text file called acropalypse.list. These can then be fixed by running them through a PNG repair tool, like optipng -fix:

xargs -d '\n' -a acropalypse.list optipng -fix

NOTE: This example will not correctly handle filenames that contain a newline (\n) character. You could change \n to \0 in the Perl code (line 27) and change -d '\n' to -0 in the xargs call if you need it to handle such filenames.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment