#!/usr/bin/perl -w

#    This file is part of Internet Explorer Mask'O'Matic script
#    Copyright (C) 2003  Stanislaw Y. Pusep
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#    E-Mail:    stanis@linuxmail.org
#    Site:      http://sysdlabs.hypermart.net/

use strict;
use Getopt::Long;
use Image::Magick;

my $VERSION = '1.0';

# salute user
print "Internet Explorer Mask'O'Matic v$VERSION by Stas <stanis\@linuxmail.org>\n",
      "Grab yours at http://sysdlabs.hypermart.net/ ;)\n\n",

      "Inspirated by some mad stuff by Lem0nHead\n",
      "Based on Photoshop 'Hidden Image' Guide (http://www.atomicwienerdog.com/ot/)\n",
      "made by Matt Kment & suggested to me by xfalmp\n\n\n";

# our variables
my ($visible, $hidden, $output, $quality, $contrast, $test);
my $percentage = 50.0;

# read commandline
GetOptions (
   'visible=s'	=> \$visible,
   'hidden=s'	=> \$hidden,
   'output=s'	=> \$output,
   'percentage=f'=>\$percentage,
   'quality=i'	=> \$quality,
   'contrast'	=> \$contrast,
   'test=s'	=> \$test,
);

# validate parameters passed
if (not defined $visible or not $visible) {
   print "ERROR: please give us --visible\n";
   &usage;
}

if (not defined $hidden or not $hidden) {
   print "ERROR: please give us --hidden\n";
   &usage;
}

if (not defined $output or not $output) {
   print "ERROR: please give us --output\n";
   &usage;
} elsif (-e $output) {
   print "ERROR: file specified by --output already exists\n";
   &usage;
}

if ($percentage < 0.0 or $percentage > 100.0) {
   print "ERROR: --percentage should be between 0.0 & 100.0\n";
   &usage;
}

my $r = '';


# load visible image
my $vis = Image::Magick->new;
print "Reading [$visible]... ";
$r = $vis->Read ($visible);
die "\nERROR: $r" if "$r";
print "OK!\n";

my $x = $vis->Get ('base-columns');
my $y = $vis->Get ('base-rows');
my $res = sprintf '%dx%d', $x, $y;

# load hidden image
my $hid = Image::Magick->new;
print "Reading [$hidden]... ";
$r = $hid->Read ($hidden);
die "\nERROR: $r" if "$r";
print "OK!\n";

if ($x != $hid->Get ('base-columns') || $y != $hid->Get ('base-rows')) {
   print "Resampling to $res...";
   $r = $hid->Resize (width => $x, height => $y, filter => 'Lanczos');
   die "\nERROR: $r" if "$r";
   print "OK!\n";
}

# create selection mask
print "Creating selection mask\n";
my $tile = Image::Magick->new;
$tile->Set (size => '2x2');
$tile->ReadImage ('xc:white');
my $mask_color = 'black';
$tile->Set ('pixel[0,1]' => $mask_color);
$tile->Set ('pixel[1,0]' => $mask_color);

print "Tiling over mask layer\n";
my $msk = Image::Magick->new;
$msk->Set (size => $res);
$msk->ReadImage ('xc:white');
$msk->Composite (image => $tile, tile=> 'True');


# make negative of hidden image
print "Reteiving negative of [$hidden]... ";
my $nhid = $hid->Clone;
die "\nERROR: $r" unless ref ($nhid); 
print "OK!\n";
$nhid->Negate;

# compose hidden image with it's negative through selection mask
print "Compositing hidden image with it's negative through selection mask... ";
$r = $hid->Composite (image => $nhid, mask => $msk);
die "\nERROR: $r" if "$r";
print "OK!\n";


# create merge opacity layer
print "Creating opacity layer\n";
my $half = Image::Magick->new;
$half->Set (size => $res);
my $opacity = (sprintf '%02x', (0xff * ((100 - $percentage) / 100))) x 3;
$half->ReadImage ('xc:#' . $opacity);


# now merging...
print "Merging visible & processed hidden images... ";
$r = $vis->Composite (image => $hid, mask => $half, compose => 'Dissolve');
die "\nERROR: $r" if "$r";
print "OK!\n";

# attempt to reduce contrast
if ($contrast) {
   print "Reducing contrast... ";
   $r = $vis->Contrast (sharpen => 'False');
   die "\nERROR: $r" if "$r";
   print "OK!\n";
}

# now finish our dirty work ;)
print "Writing out output [$output]... ";
$vis->Set (quality => $quality) if defined $quality;
$r = $vis->Write ($output);
die "\nERROR: $r" if "$r";
print "OK!\n";

# generate preview (VERY useful on non-M$ systems ;)
if (defined $test) {
   # damn, that's ugly!
   $msk->Negate;
   $msk->Transparent (color => 'white');
   $vis->Composite (image => $msk);

   print "Writing out preview [$test]... ";
   $r = $vis->Write ($test);
   die "\nERROR: $r" if "$r";
   print "OK!\n";
}


print "\nDone!\n";
exit;


sub usage {
   print <<END_USAGE


 * Usage: $0 <options>
 * Options (note that you can use syntaxes like --vis= --hid -out -p):
	--visible	filename of image normally seen (required)
	--hidden	filename of image seen when selected in IE (required)
	--output	filename to write out, format is selected automatically
			using suffix provided (required)
	--percentage	float value between 0 & 100; how much of hidden appears
			(optional, defaults to 50%)
	--quality	JPEG/MIFF/PNG compression level (optional, DON'T USE!)
	--contrast	flag, internal contrast reduction (optional)
	--test		filename to dump preview of selected image (optional)

 * Notes:
	 # Visible & hidden images doesn't need to have same size, when size
	   doesn't matches then hidden image is rescaled using Lanczos filter
	 # A huge set of image formats is supported (JPG, GIF, PNG for example)
	   but I strongly advice you to write output in loseless format *only*
	   (BMP, PNG, TGA) and *then* fine-tune contrast/brightness & save
	   compressed in your favourite image editor (like GIMP)

 * Example:
	$0 --vis bush.jpg --hid death.jpg --out sublim.bmp
END_USAGE
;

   exit;
}
