#!/usr/bin/perl -w use strict; use Compress::Zlib; use IO::File; use Getopt::Long; sub usage { "Usage: uncomp [-o OFFS] [-w WINDOW] [-l COMPLEVEL] [-b BUFSZE] {-d|-c} file\n" ." -T : trace on byte level\n" } my $offset=0; my $decompress=1; my $compress; my $windowbits; my $level; my $bufsize; my $trace; my $gzip; GetOptions( "o=s" => sub { $offset=eval($_[1]); }, "d" => sub { $decompress=1; $compress=0; }, "c" => sub { $compress=1; $decompress=0; }, "w=s" => sub { $windowbits=eval($_[1]); }, "l=s" => sub { $level=eval($_[1]); }, "b=s" => sub { $bufsize=eval($_[1]); }, "g" => \$gzip, "T" => \$trace, ) || die usage(); my $fn=shift || die usage(); my $fh=$fn eq '-' ? *STDIN : IO::File->new($fn, "r") or die "$fn: $!\n"; binmode $fh; my $data; if ($fn eq '-') { local $/; $data=<>; } else { $fh->seek($offset, SEEK_SET); $fh->read($data, (-s $fh) - $offset); } $fh->close(); my $datalen= length($data); binmode STDOUT; my @options; push @options, (-WindowBits=>$windowbits) if defined $windowbits; push @options, (-Level=>$level) if defined $level; push @options, (-Bufsize=>$bufsize) if defined $bufsize; if ($gzip) { if ($decompress) { my $output= Compress::Zlib::memGunzip($data); warn sprintf("left: 0x%x bytes\n", length($data)); print $output; } elsif ($compress) { } } elsif ($trace) { if ($decompress) { my $d= inflateInit(@options); tracedecompress($offset, $d, $data); } elsif ($compress) { my $d= deflateInit(@options); tracecompress($offset, $d, $data); } } elsif ($decompress) { #print Compress::Zlib::uncompress($data); my $d= inflateInit(@options); my ($output, $err)= $d->inflate($data); if ($err!=Z_STREAM_END) { warn sprintf("left: 0x%x bytes, offset 0x%x - error: %s\n", length($data), $datalen-length($data)+$offset, $err) } print $output; if (length($data)) { warn sprintf("left: 0x%x bytes, offset 0x%x\n", length($data), $datalen-length($data)+$offset); } } elsif ($compress) { #print Compress::Zlib::compress($data); my $d= deflateInit(@options); my ($output, $err)= $d->deflate($data); print $output; ($output, $err)= $d->flush(); print $output; } sub tracedecompress { my $baseofs= shift; my $d= shift; my $oofs= 0; for (my $ofs= 0 ; $ofsinflate($compbyte); printf("%08lx %s -> [%4d] %08lx: %s\n", $baseofs+$ofs, unpack("H*", substr($_[0], $ofs, 1)), $err, $oofs, unpack("H*", $output)); $oofs += length($output); } } sub tracecompress { my $baseofs= shift; my $d= shift; my $oofs= 0; for (my $ofs= 0 ; $ofsdeflate($compbyte); printf("%08lx %s -> [%4d] %08lx: %s\n", $baseofs+$ofs, unpack("H*", substr($_[0], $ofs, 1)), $err, $oofs, unpack("H*", $output)); $oofs += length($output); } }