# Identifies apngs # Written by Foone/Popcorn Mariachi#!9i78bPeIxI, based on Wakaba code by !WAHa.06x36 # This code is in the public domain # identify_png returns: # '?' for non-png or corrupt PNG # 'png' for a standard png # 'apng' for an APNG # takes one argument, a file handle. When the function reutrns it'll be positioned at the start of the file sub identify_png($){ my ($file)=@_; my ($bytes,$buffer); seek($file,0,0); $bytes=read($file,$buffer,24); seek($file,0,0); return '?' unless($bytes==24); my ($magic1,$magic2,$length,$ihdr,$width,$height)=unpack("NNNNNN",$buffer); return '?' unless($magic1==0x89504e47 and $magic2==0x0d0a1a0a and $ihdr==0x49484452); # So we know it's a valid PNG now, the only question is if it's an APNG too seek($file,8,0); # Jump to the end of the signature while(1){ $bytes=read($file,$buffer,8); last if $bytes!=8; my ($length,$type)=unpack('NA4',$buffer); last if $type eq 'IDAT'; # acTL must come before IDAT, so if we see an IDAT this is plain PNG last if $type eq 'IEND'; # End of File if ($type eq 'acTL'){ # It's APNG seek($file,0,0); return 'apng'; } last if seek($file,$length+4,1)==0; # +4 because of the CRC at the end } seek($file,0,0); return 'png'; }