#! /usr/bin/perl ## This script is based on cyclo.cgi, see http://homepage2.nifty.com/sophia0/ ## cyclo.cgi v0.3c (CYCLIC IMAGE) 2001.04.15 by techan # usage: png2mng $basename = $ARGV[0]; # Image Width Height @w_h = ($ARGV[1], $ARGV[2]); # The number of repeats for base (integer > 1) $b_repeat = 1; # Ticks per second $tps = 20; ## Main &InitCrcTable; $r = "NG\r\n\x1a\n"; $sig_p = "\x89P".$r; $sig_m = "\x8aM".$r; # Check File @png = (); $size = 1; for ($i=0;$size > 0;) { $file = $basename.sprintf('%04d.png', $i+1); $size = -s $file; if ($size > 0) { open(IN, "< $file") || &Error(1); binmode(IN); read(IN, $sig, 8); if ($sig ne $sig_p) { close(IN); &Error(2); } read(IN, $png[$i], $size-8); close(IN); $i++; } } $number = $i; $it = $number * $b_repeat; $ti = $it; $|=1; binmode(STDOUT); # Signature print $sig_m; # MHDR $data = 'MHDR'.pack("N7", $w_h[0], # Width $w_h[1], # Height $tps, # Ticks per second $number, # Layers $ti, # Frames $ti, # Time 583); # Simplicity &OutputData; # DEFI define objects of the number specified by $number for ($i=0;$i<$number;$i++) { $data = 'DEFI'.pack("n", $i+1); # Object_id # Do_not_show: 1 byte (unsigned integer) # Concrete_flag: 1 byte (unsigned integer) # X_location: 4 bytes (signed integer) # Y_location: 4 bytes (signed integer) # Left_cb: 4 bytes (signed integer) # Right_cb: 4 bytes (signed integer) # Top_cb: 4 bytes (signed integer) # Bottom_cb: 4 bytes (signed integer) &OutputData; print $png[$i]; } undef(@png); # LOOP $data = 'LOOP'.pack("CNC", 0, # Nest_level $it, # Iteration_count 6); # Termination_condition: # 1: Decoder discretion, not cacheable. # 2: User discretion, not cacheable. # *3: External signal, not cacheable. # 4: Deterministic, cacheable. # 5: Decoder discretion, cacheable. # 6: User discretion, cacheable. # *7: External signal, cacheable. # Iteration_min: 4 bytes(unsigned integer) # Iteration_max: 4 bytes (unsigned integer) # Signal_number: 4 bytes (unsigned integer) # Additional signal_number: 4 bytes (unsigned integer) &OutputData; # SHOW $data = 'SHOW'.pack("nnC", 1, # First_image $number, # Last_image 6); # Show_mode: # 0: Make the images potentially visible and display them. # 1: Make the images invisible. # 2: Display those that are potentially visible. # 3: Mark images "potentially visible" but do not display # them. # 4: Display any that are potentially visible after toggling. # 5: Do not display even if potentially visible after toggling. # 6: Step through the images in the given range, making the # next image potentially visible and display it. Jump to # the beginning of the range when reaching the end of the # range. Perform one step for each SHOW chunk (in reverse # order if last_image < first_image). # 7: Make the next image in the range (cycle) potentially # visible but do not display it. &OutputData; # ENDL $data = "ENDL\0"; # Nest_level: 1 byte &OutputData; # MEND print "\0\0\0\0MEND! \xf7\xd5"; exit(0); sub Error { my $e = $_[0]; $black = "\0\0\0"; $red = "\xff\0\0"; $white = "\xff\xff\xff"; if ($e == 1) { $plte = $white.$black; } elsif ($e == 2) { $plte = $white.$red; } else { $plte = $red.$white; } $plte = "PLTE".$plte; $p = $sig_p; $p.="\0\0\0\rIHDR"; $p.="\0\0\0\x1e\0\0\0\x0c\x01\x03\0\0\0"; $p.="\x4f\xe0\x9f\x71"; $p.="\0\0\0\x06".$plte.&CalcCrc($plte); $p.="\0\0\0\x2eIDAT"; $p.="\x78\x9c\x63\x60\x40\x05\xbf\xcf\xcb\x7c\x60\x68\xd2\x58\xd4\x01"; $p.="\x21\x3e\x81\x88\xe6\xf3\x4a\x40\xb1\x2e\xa5\x05\x0c\x4d\x9e\x4a"; $p.="\x13\x18\x7e\x69\xcc\xe9\0\xab\x05\0\xb0\x88\x10\xb8"; $p.="\x57\x3a\0\xa1"; $p.="\0\0\0\0IEND\xaeB`\x82"; $|=1; # print "Content-type: $mime\n"; # print "Content-length: 121\n\n"; binmode(STDOUT); print $p; exit(1); } sub InitCrcTable { my $d; @crc_table = (); for (0 .. 255) { $d = $_; for (0 .. 7) { if ($d & 1) { $d = 0xedb88320 ^ (($d >> 1) & 0x7fffffff); } else { $d = ($d >> 1) & 0x7fffffff; } } $crc_table[$_] = $d; } } sub CalcCrc { my $data = $_[0]; my $c = 0xffffffff; foreach (unpack("C*", $data)) { $c = $crc_table[($c ^ $_) & 0xff] ^ (($c >> 8) & 0xffffff); } return(pack("N", ~$c)); } sub OutputData { print pack("N", length($data)-4).$data.&CalcCrc($data); undef($data); } __END__