From d5a1a064218f98ae54e8401a39f652ab51979e1c Mon Sep 17 00:00:00 2001 From: Bruno Martins Date: Sun, 20 Jan 2013 19:45:49 +0000 Subject: [PATCH] code cleanup --- repack-MT65xx.pl | 106 ++++++++++++++++------------------- unpack-MT65xx.pl | 143 +++++++++++++++++++++++------------------------ 2 files changed, 117 insertions(+), 132 deletions(-) diff --git a/repack-MT65xx.pl b/repack-MT65xx.pl index d57453c..96b8693 100755 --- a/repack-MT65xx.pl +++ b/repack-MT65xx.pl @@ -18,10 +18,11 @@ use Cwd; use Compress::Zlib; use Term::ANSIColor; +use FindBin qw($Bin); my $dir = getcwd; -my $version = "MTK-Tools by Bruno Martins\nMT65xx repack script (last update: 13-01-2013)\n"; +my $version = "MTK-Tools by Bruno Martins\nMT65xx repack script (last update: 20-01-2013)\n"; my $usage = "repack-MT65xx.pl COMMAND [...]\n\nCOMMANDs are:\n\n -boot \n Repacks boot image\n\n -recovery \n Repacks recovery image\n\n -logo [--no_compression] \n Repacks logo image\n\n"; print colored ("$version", 'bold blue') . "\n"; @@ -47,7 +48,6 @@ } sub repack_boot { - # initilization my $kernel = $ARGV[1]; my $ramdiskdir = $ARGV[2]; my $outfile = $ARGV[3]; @@ -66,12 +66,12 @@ sub repack_boot { chdir $dir or die "\n$ramdiskdir $!";; - my $slurpvar = $/; - undef $/; open (RAMDISKFILE, "ramdisk-repack.cpio.gz") or die colored ("Error: could not open ramdisk file 'ramdisk-repack.cpio.gz'", 'red') . "\n"; - my $ramdisk = ; - close RAMDISKFILE; - $/ = $slurpvar; + my $ramdisk; + while () { + $ramdisk .= $_; + } + close (RAMDISKFILE); # generate the header according to the ramdisk size my $sizeramdisk = length($ramdisk); @@ -81,41 +81,42 @@ sub repack_boot { my $newramdisk = $header . $ramdisk; open (RAMDISKFILE, ">new-ramdisk-repack.cpio.gz"); + binmode (RAMDISKFILE); print RAMDISKFILE $newramdisk or die; - close RAMDISKFILE; + close (RAMDISKFILE); # create the output file if ( $^O eq "cygwin" ) { - system ("./mkbootimg.exe --kernel $kernel --ramdisk new-ramdisk-repack.cpio.gz -o $outfile"); + system ("$Bin/mkbootimg.exe --kernel $kernel --ramdisk new-ramdisk-repack.cpio.gz -o $outfile"); } else { - system ("mkbootimg --kernel $kernel --ramdisk new-ramdisk-repack.cpio.gz -o $outfile"); + system ("$Bin/mkbootimg --kernel $kernel --ramdisk new-ramdisk-repack.cpio.gz -o $outfile"); } # cleanup - unlink("ramdisk-repack.cpio.gz") or die $!; - system("rm new-ramdisk-repack.cpio.gz"); + unlink ("ramdisk-repack.cpio.gz") or die $!; + system ("rm new-ramdisk-repack.cpio.gz"); - print "\nRepacked $ARGV[0] image into '$outfile'\n"; + print "\nRepacked $ARGV[0] image into '$outfile'.\n"; } sub repack_logo { - # initilization - my $input; my $logodir = $ARGV[1]; my $outfile = $ARGV[2]; my $signature = $_[0]; $ARGV[0] =~ s/-//; - + chdir $logodir or die colored ("Error: directory '$logodir' not found", 'red') . "\n"; my (@raw_addr, @zlib_raw) = (); my $i = 0; - my $slurpvar = $/; - undef $/; + print "Repacking $ARGV[0] image...\n"; for my $inputfile ( glob "./*.rgb565" ) { open (INPUTFILE, "$inputfile") or die colored ("Error: could not open raw image '$inputfile'", 'red') . "\n"; - $input = ; + my $input; + while () { + $input .= $_; + } close INPUTFILE; # deflate all rgb565 raw files found (compress zlib rfc1950) @@ -124,86 +125,74 @@ sub repack_logo { $i++; } die colored ("Error: could not find any .rgb565 file under the specified directory '$logodir'", 'red') . "\n" unless $i > 0; - print "Repacking $ARGV[0] image...\n"; chdir $dir or die "\n$logodir $!";; - - $/ = $slurpvar; + my $num_blocks = $i; print "Number of raw images found in the specified folder: $num_blocks\n"; my $logo_length = (4 + 4 + $num_blocks * 4); # calculate the start address of each raw image and the new file size - $i = 0; - do { + for my $i (0 .. $num_blocks - 1) { $raw_addr[$i] = $logo_length; $logo_length += length($zlib_raw[$i]); - $i++; - } while $i < $num_blocks; + } # generate logo header according to the logo size my $logo_header = gen_header($signature, $logo_length); - my $logobin = pack('LL', $num_blocks, $logo_length); + my $logobin = pack('L L', $num_blocks, $logo_length); - $i = 0; - do { + for my $i (0 .. $num_blocks - 1) { $logobin .= pack('L', $raw_addr[$i]); - $i++; - } while $i < $num_blocks; + } - $i = 0; - do { + for my $i (0 .. $num_blocks - 1) { $logobin .= $zlib_raw[$i]; - $i++; - } while $i < $num_blocks; + } $logobin = $logo_header . $logobin; # create the output file - open (RAWFILE, ">$outfile"); - binmode(RAWFILE); - print RAWFILE $logobin or die; - close RAWFILE; + open (LOGOFILE, ">$outfile"); + binmode (LOGOFILE); + print LOGOFILE $logobin or die; + close (LOGOFILE); - print "\nRepacked $ARGV[0] image into '$outfile'\n"; + print "\nRepacked $ARGV[0] image into '$outfile'.\n"; } sub repack_logo_uncompressed { - # initilization my @raw; my $logodir = $ARGV[2]; my $outfile = $ARGV[3]; my $signature = $_[0]; $ARGV[0] =~ s/-//; - + chdir $logodir or die colored ("Error: directory '$logodir' not found", 'red') . "\n"; my $i = 0; - my $slurpvar = $/; - undef $/; + print "Repacking $ARGV[0] image (without compression)...\n"; for my $inputfile ( glob "./*.rgb565" ) { open (INPUTFILE, "$inputfile") or die colored ("Error: could not open raw image '$inputfile'", 'red') . "\n"; - $raw[$i] = ; + while () { + $raw[$i] .= $_; + } close INPUTFILE; $i++; } die colored ("Error: could not find any .rgb565 file under the specified directory '$logodir'", 'red') . "\n" unless $i > 0; - print "Repacking $ARGV[0] image (without compression)...\n"; chdir $dir or die "\n$logodir $!";; - $/ = $slurpvar; my $num_blocks = $i; print "Number of raw images found in the specified folder: $num_blocks\n"; my $logobin; - $i = 0; - do { + for my $i (0 .. $num_blocks - 1) { $logobin .= $raw[$i]; - $i++; - } while $i < $num_blocks; + } # generate logo header according to the logo size my $logo_header = gen_header($signature, length($logobin)); @@ -211,17 +200,16 @@ sub repack_logo_uncompressed { $logobin = $logo_header . $logobin; # create the output file - open (RAWFILE, ">$outfile"); - binmode(RAWFILE); - print RAWFILE $logobin or die; - close RAWFILE; + open (LOGOFILE, ">$outfile"); + binmode (LOGOFILE); + print LOGOFILE $logobin or die; + close (LOGOFILE); - print "\nRepacked $ARGV[0] image into '$outfile'\n"; + print "\nRepacked $ARGV[0] image into '$outfile'.\n"; } sub gen_header { - my $header_type = $_[0]; - my $length = $_[1]; + my ($header_type, $length) = @_; - return pack('a4La32H*', "\x88\x16\x88\x58", $length, $header_type, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + return pack('a4 L a32 a472', "\x88\x16\x88\x58", $length, $header_type, "\xFF"x472); } diff --git a/unpack-MT65xx.pl b/unpack-MT65xx.pl index b9eebc4..a345d4b 100755 --- a/unpack-MT65xx.pl +++ b/unpack-MT65xx.pl @@ -26,7 +26,7 @@ use Term::ANSIColor; use Scalar::Util qw(looks_like_number); -my $version = "MTK-Tools by Bruno Martins\nMT65xx unpack script (last update: 15-01-2013)\n"; +my $version = "MTK-Tools by Bruno Martins\nMT65xx unpack script (last update: 20-01-2013)\n"; my $usage = "unpack-MT65xx.pl [COMMAND ...]\n Unpacks boot, recovery or logo image\n\nOptional COMMANDs are:\n\n -kernel_only\n Extract kernel only from boot or recovery image\n\n -ramdisk_only\n Extract ramdisk only from boot or recovery image\n\n -force_logo_res \n Forces logo image file to be unpacked by specifying image resolution,\n which must be entered in pixels\n (only useful when no zlib compressed images are found)\n\n"; print colored ("$version", 'bold blue') . "\n"; @@ -44,12 +44,12 @@ my $inputfile = $ARGV[0]; -my $slurpvar = $/; -undef $/; open (INPUTFILE, "$inputfile") or die colored ("Error: could not open the specified file '$inputfile'", 'red') . "\n"; -my $input = ; -close INPUTFILE; -$/ = $slurpvar; +my $input; +while () { + $input .= $_; +} +close (INPUTFILE); if ((substr($input, 0, 4) eq "\x88\x16\x88\x58") & (substr($input, 8, 4) eq "LOGO")) { # if the input file contains the logo signature, try to unpack it @@ -69,15 +69,15 @@ $ARGV[1] =~ s/_only//; unpack_boot($input, $ARGV[1]); } else { - unpack_boot($input, "extract_all"); + unpack_boot($input, "kernel and ramdisk"); } } else { die colored ("Error: the input file does not appear to be supported or valid", 'red') . "\n"; } sub unpack_boot { - my $bootimg = $_[0]; - my($bootMagic, $kernelSize, $kernelLoadAddr, $ram1Size, $ram1LoadAddr, $ram2Size, $ram2LoadAddr, $tagsAddr, $pageSize, $unused1, $unused2, $bootName, $cmdLine, $id) = unpack('a8 L L L L L L L L L L a16 a512 a8', $bootimg); + my ($bootimg, $extract) = @_; + my ($bootMagic, $kernelSize, $kernelLoadAddr, $ram1Size, $ram1LoadAddr, $ram2Size, $ram2LoadAddr, $tagsAddr, $pageSize, $unused1, $unused2, $bootName, $cmdLine, $id) = unpack('a8 L L L L L L L L L L a16 a512 a8', $bootimg); print colored ("\nInput file information:\n", 'yellow') . "\n"; print " Kernel size: $kernelSize bytes / "; @@ -93,18 +93,18 @@ sub unpack_boot { print " Command line: $cmdLine\n\n"; } - if ( $_[1] eq "kernel" || $_[1] eq "extract_all" ) { + if ( $extract eq "kernel" || $extract eq "kernel and ramdisk" ) { my($kernel) = substr($bootimg, $pageSize, $kernelSize); open (KERNELFILE, ">$ARGV[0]-kernel.img"); - binmode(KERNELFILE); + binmode (KERNELFILE); print KERNELFILE $kernel or die; - close KERNELFILE; + close (KERNELFILE); print "Kernel written to '$ARGV[0]-kernel.img'\n"; } - if ( $_[1] eq "ramdisk" || $_[1] eq "extract_all" ) { + if ( $extract eq "ramdisk" || $extract eq "kernel and ramdisk" ) { my($kernelAddr) = $pageSize; my($kernelSizeInPages) = int(($kernelSize + $pageSize - 1) / $pageSize); @@ -120,9 +120,9 @@ sub unpack_boot { } open (RAMDISKFILE, ">$ARGV[0]-ramdisk.cpio.gz"); - binmode(RAMDISKFILE); + binmode (RAMDISKFILE); print RAMDISKFILE $ram1 or die; - close RAMDISKFILE; + close (RAMDISKFILE); if (-e "$ARGV[0]-ramdisk") { rmtree "$ARGV[0]-ramdisk"; @@ -142,10 +142,11 @@ sub unpack_boot { print "Extracted ramdisk contents to directory '$ARGV[0]-ramdisk'\n"; } - printf ("\nSuccessfully unpacked %s.\n", $_[1] eq "extract_all" ? "kernel and ramdisk" : $_[1] ); + print "\nSuccessfully unpacked $extract.\n"; } sub unpack_logo { + my $logobin = $_[0]; my @resolution = ( # HD (High-Definition) [360,640,"(nHD)"], [540,960,"(qHD)"], [720,1280,"(HD)"], [1080,1920,"(FHD)"], @@ -162,10 +163,10 @@ sub unpack_logo { # Quad XGA (Quad Extended Graphics Array) [1152,2048,"(QWXGA)"], [1536,2048,"(QXGA)"], [1600,2560,"(WQXGA)"], [2048,2560,"(QSXGA)"], [2048,3200,"(WQSXGA)"], [2400,3200,"(QUXGA)"], [2400,3840,"(WQUXGA)"], - # Others - [38,54,""], [48,54,""], [135,24,""], [135,1,""] ); + # Others (found in some MediaTek logo images) + [38,54,""], [48,54,""], [135,24,""], [135,1,""] + ); - my $logobin = $_[0]; # get logo header my $header = substr($logobin, 0, 512); my ($header_sig, $logo_length, $logo_sig) = unpack('a4 V A4', $header); @@ -177,7 +178,7 @@ sub unpack_logo { print colored ("Warning: unexpected logo image file size! Trying to unpack it anyway...", 'yellow') . "\n"; } - # chop the header and any garbage at the EOF + # chop the header and any eventual garbage found at the EOF # (only extract important logo information that contains packed raw images) my $logo = substr($logobin, 512, $logo_length); @@ -186,9 +187,6 @@ sub unpack_logo { die colored ("\nError: no way, the logo image file seems to be corrupted", 'red') . "\n"; } - my $num_blocks = unpack('V', $logo); - my $i = 0; - if (-e "$ARGV[0]-unpacked") { rmtree "$ARGV[0]-unpacked"; print "\nRemoved old unpacked logo directory '$ARGV[0]-unpacked'\n"; @@ -198,66 +196,65 @@ sub unpack_logo { chdir "$ARGV[0]-unpacked" or die; print "Extracting raw images to directory '$ARGV[0]-unpacked'\n"; + # get the number of packed raw images + my $num_blocks = unpack('V', $logo); + if ( ! $num_blocks ) { - die "\nNo zlib packed rgb565 images were found inside logo file.\nRecheck script usage and try to use -force_logo_res switch.\n" - unless $ARGV[1]; + die "\nNo zlib packed rgb565 images were found inside logo file." . + "\nRecheck script usage and try to use -force_logo_res switch.\n" unless $ARGV[1]; + # if no compressed files are found, try to unpack logo based on specified image resolution my $image_file_size = ($ARGV[2] * $ARGV[3] * 2); $num_blocks = $logo_length / $image_file_size; print "\nNumber of uncompressed images found (based on specified resolution): $num_blocks\n"; - for $i (0 .. $num_blocks - 1) { - open (RAWFILE, ">$ARGV[0]-raw[$i].rgb565"); - binmode(RAWFILE); - print RAWFILE substr($logo, $i * $image_file_size, $image_file_size) or die; - close RAWFILE; - print "Raw image #$i written to $ARGV[0]-raw[$i].rgb565\n"; - } - goto END; - } + for my $i (0 .. $num_blocks - 1) { + my $filename = sprintf ("%s-img[%02d]", $ARGV[0], $i); - my $j = 0; - my (@raw_addr, @zlib_raw) = (); - print "\nNumber of raw images found: $num_blocks\n"; - # get the starting address of each raw file - do { - $raw_addr[$i] = unpack('L', substr($logo, 8+$i*4, 4)); - $i++; - } while $i < $num_blocks; - - $i = 0; - my $num; - my $raw_num_pixels; - # extract rgb565 raw files (uncompress zlib rfc1950) - do { - if ($i < $num_blocks-1) { - $zlib_raw[$i] = substr($logo, $raw_addr[$i], $raw_addr[$i+1]-$raw_addr[$i]); - } else { - $zlib_raw[$i] = substr($logo, $raw_addr[$i]); + open (RAWFILE, ">$filename.rgb565"); + binmode (RAWFILE); + print RAWFILE substr($logo, $i * $image_file_size, $image_file_size) or die; + close (RAWFILE); + print "Raw image #$i written to '$filename.rgb565'\n"; } - $num = sprintf ("%02d",$i); - open (RAWFILE, ">$ARGV[0]-raw[$num].rgb565"); - binmode(RAWFILE); - print RAWFILE uncompress($zlib_raw[$i]) or die; - close RAWFILE; - print "Raw image #$i written to '$ARGV[0]-raw[$num].rgb565'\n"; - # calculate rgb565 image resolution - $raw_num_pixels = length (uncompress($zlib_raw[$i])) / 2; - while ( $j <= $#resolution ) { - last if ( $raw_num_pixels == ($resolution[$j][0] * $resolution[$j][1]) ); - $j++; + } else { + my $j = 0; + my (@raw_addr, @zlib_raw) = (); + print "\nNumber of raw images found: $num_blocks\n"; + # get the starting address of each raw file + for my $i (0 .. $num_blocks - 1) { + $raw_addr[$i] = unpack('L', substr($logo, 8+$i*4, 4)); } - if ( $j <= $#resolution ) { - print " Image resolution (width x height): $resolution[$j][0] x $resolution[$j][1] $resolution[$j][2]\n"; - } else { - print " Image resolution: unknown\n"; + # extract rgb565 raw files (uncompress zlib rfc1950) + for my $i (0 .. $num_blocks - 1) { + if ($i < $num_blocks-1) { + $zlib_raw[$i] = substr($logo, $raw_addr[$i], $raw_addr[$i+1]-$raw_addr[$i]); + } else { + $zlib_raw[$i] = substr($logo, $raw_addr[$i]); + } + my $filename = sprintf ("%s-img[%02d]", $ARGV[0], $i); + + open (RAWFILE, ">$filename.rgb565"); + binmode (RAWFILE); + print RAWFILE uncompress($zlib_raw[$i]) or die; + close (RAWFILE); + + print "Raw image #$i written to '$filename.rgb565'\n"; + # calculate rgb565 image resolution + my $raw_num_pixels = length (uncompress($zlib_raw[$i])) / 2; + while ( $j <= $#resolution ) { + last if ( $raw_num_pixels == ($resolution[$j][0] * $resolution[$j][1]) ); + $j++; + } + if ( $j <= $#resolution ) { + print " Image resolution (width x height): $resolution[$j][0] x $resolution[$j][1] $resolution[$j][2]\n"; + } else { + print " Image resolution: unknown\n"; + } + $j = 0; } - $j = 0; - - $i++; - } while $i < $num_blocks; + } - END: - print "\nSuccessfully extracted all raw images.\n"; + print "\nSuccessfully extracted all images.\n"; }