Skip to content

Commit

Permalink
code cleanup
Browse files Browse the repository at this point in the history
bgcngm committed Jan 20, 2013
1 parent 1f66aa1 commit d5a1a06
Showing 2 changed files with 117 additions and 132 deletions.
106 changes: 47 additions & 59 deletions repack-MT65xx.pl
Original file line number Diff line number Diff line change
@@ -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 <kernel> <ramdisk-directory> <outfile>\n Repacks boot image\n\n -recovery <kernel> <ramdisk-directory> <outfile>\n Repacks recovery image\n\n -logo [--no_compression] <logo-directory> <outfile>\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 = <RAMDISKFILE>;
close RAMDISKFILE;
$/ = $slurpvar;
my $ramdisk;
while (<RAMDISKFILE>) {
$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 = <INPUTFILE>;
my $input;
while (<INPUTFILE>) {
$input .= $_;
}
close INPUTFILE;

# deflate all rgb565 raw files found (compress zlib rfc1950)
@@ -124,104 +125,91 @@ 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] = <INPUTFILE>;
while (<INPUTFILE>) {
$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));

$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);
}
143 changes: 70 additions & 73 deletions unpack-MT65xx.pl
Original file line number Diff line number Diff line change
@@ -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 <infile> [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 <width> <height>\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 = <INPUTFILE>;
close INPUTFILE;
$/ = $slurpvar;
my $input;
while (<INPUTFILE>) {
$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";
}

0 comments on commit d5a1a06

Please sign in to comment.