### 3:05 PM 1/7/2006


### RGB values of (255,255,255) is white. 
### In the Windows .BMP format, RGB values are stored backwards.
###
###                   blue      green       red

$TransparentColor = chr(255) . chr(255) . chr(255);


######################################
###  Check inputs and load images  ###
######################################

$NumberArgs = @ARGV;
if( $NumberArgs != 3 )
{
    print "Error:  Incorrect parameters. \n";
    print "Example:  perl -w overlay.pl test1bg.bmp test1.bmp final.bmp \n";
    exit;
}

if( ! ( -e $ARGV[0] ) )
{
    die "Error:  File not found.  $ARGV[0] \n";
}

if( ! ( -e $ARGV[1] ) )
{
    die "Error:  File not found.  $ARGV[1] \n";
}

print "Working . . . \n";


###############################
###  Load background image  ###
###############################

$BackgroundFile = "";
open INPUT1, "$ARGV[0]" or die "Error: Could not open $ARGV[0] for reading. \n";
binmode INPUT1;
$LineOfData = "";
while( read( INPUT1, $LineOfData, 1048576 ) )
{
    ### Read in one meg at a time.
    $BackgroundFile .= $LineOfData;
}
close INPUT1;

if( substr($BackgroundFile, 0, 2) ne "BM" )
{
    die "Error: $ARGV[0] is not in the Windows bitmap format. \n";
}

if( unpack("S", substr($BackgroundFile, 28, 2)) != 24 )
{
    die "Error: $ARGV[0] needs to be a 24-bit per pixel bitmap. \n";
}

$BgHoriz = unpack("L", substr($BackgroundFile, 18, 4));
$BgVert = unpack("L", substr($BackgroundFile, 22, 4));


###############################
###  Load foreground image  ###
###############################

$ForegroundFile = "";
open INPUT2, "$ARGV[1]" or die "Error: Could not open $ARGV[1] for reading. \n";
binmode INPUT2;
$LineOfData = "";
while( read( INPUT2, $LineOfData, 1048576 ) )
{
    ### Read in one meg at a time.
    $ForegroundFile .= $LineOfData;
}
close INPUT2;

if( substr($ForegroundFile, 0, 2) ne "BM" )
{
    die "Error: $ARGV[1] is not in the Windows bitmap format. \n";
}

if( unpack("S", substr($ForegroundFile, 28, 2)) != 24 )
{
    die "Error: $ARGV[1] needs to be a 24-bit per pixel bitmap. \n";
}

$FgHoriz = unpack("L", substr($ForegroundFile, 18, 4));
$FgVert = unpack("L", substr($ForegroundFile, 22, 4));


########################
###  Process images  ###
########################

$FinalFile = $ForegroundFile;

$BgOneLineSize = ( $BgHoriz * 3 ) + ( $BgHoriz % 4 );
$FgOneLineSize = ( $FgHoriz * 3 ) + ( $FgHoriz % 4 );

for( $y = 0; $y < $FgVert; $y++ )
{
    for( $x = 0; $x < $FgHoriz; $x++ )
    {
        $FgOffset = 54 + ( $FgOneLineSize * $y ) + ( $x * 3 );
        
        ### Scale and find point in background image. 
        
        $a = int( 0.5 + ( ( $x * $BgHoriz ) / $FgHoriz ) );
        $b = int( 0.5 + ( ( $y * $BgVert ) / $FgVert ) );
        
        $BgOffset = 54 + ( $BgOneLineSize * $b ) + ( $a * 3 );

        if( substr($ForegroundFile, $FgOffset, 3) eq $TransparentColor )
        {
            substr($FinalFile, $FgOffset, 3) = substr($BackgroundFile, $BgOffset, 3);
        }
    }
}


############################
###  Write output image  ###
############################

open OUTPUT, ">$ARGV[2]" or die "Error: Could not open $ARGV[2] for writing. \n";
binmode OUTPUT;
print OUTPUT $FinalFile;
close OUTPUT;

print "Done. Image written to $ARGV[2] \n";




