#!/usr/bin/perl -w
# Copyright (C) 2009  Glen Pitt-Pladdy
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
#
#
# Put files to process as command line arguments


use Image::Magick;

#$debug = 1;

# these parameters are suitable for files that are being printed at 720DPI
# at 360DPI then halve the radius': eg. $UNSHARP = '3x1+1.5+0'; $BLUR = 2;
# or scale them accordingly for your resolution (yes - I could have done
# this automatically too!)OB

$UNSHARP = '6x2+1.5+0';
$NOSHARPRATIO = 0.5;	# amount of std dev above mean below which unsharpened
$FULLSHARPRATIO = 1.0;	# amount of std dev above mean above which full sharp
$MINSHARP = 0.3;		# minimum amount of sharpening
$BLUR = 4;				# amount to blur edge selection by



for $file (@ARGV) {
	$base = $file;
	$base =~ s/\.\w+$//;
	print "processing $file\n";
	# read in
	$image=Image::Magick->new;
	$image->Read ( $file );
	# unsharp
	$unsharp = $image->Clone;
	$unsharp->UnsharpMask ( geometry=>$UNSHARP );
	# write unsharp
	if ( $debug ) { $unsharp->Write ( $base.'-usm.tif' ); }
	# get difference
	$mask = $unsharp->Clone;
	$mask->Composite ( compose=>'Difference', image=>$image );
	# smooth
	$mask->Blur ( geometry=>"0x$BLUR" );
	# loose colour
	$mask->Modulate ( saturation=>0 );
	# sort levels
	$mask->Normalize;
	# analyse
	@histogram = $mask->Histogram;
	$mean = 0;
	$count = 0;
	undef @hist;
	while (@histogram) {
		@colour = splice @histogram, 0, 5;
		if ( $colour[0] > 0 and $colour[0] < 0xffff ) {
			# work out mean
			$mean += $colour[0] * ( $colour[4] ** 2 );
			$count += $colour[4] ** 2;
		}
		$hist[$colour[0]] = $colour[4];
	}
	$mean /= $count;
	# find the stddev
	$stddev = 0;
	$count = 0;
	for ( $i = 1; $i < 0xffff; ++$i ) {
		if ( $hist[$i] ) {
			$stddev += ( ( $mean - $i ) ** 2 ) * $hist[$i];
			$count += $hist[$i];
		}
	}
	$stddev = ( $stddev / $count ) ** 0.5;
	# work out target levels
	$blackpoint = $mean + ( $stddev * $NOSHARPRATIO );
	$whitepoint = $mean + ( $stddev * $FULLSHARPRATIO );
	# apply levels
	$mask->Level ( 'black-point'=>$blackpoint, 'white-point'=>$whitepoint );
	# apply shifts (minimum sharpness)
	$mask->Negate;
	$mask->Modulate ( brightness=>int(100*(1-$MINSHARP)) );
	$mask->Negate;

	# write
	if ( $debug ) { $mask->Write ( $base.'-mask.tif' ); }

	# apply to final
	$image->Composite ( composite=>'src-over', image=>$unsharp, mask=>$mask );
	# write
	$image->Set ( depth=>8, compression=>'Zip' );	# keep it smallOA
	$image->Write ( $base.'-out.tif' );

}


