#!/usr/bin/perl

# example:
#gimp-perl-server &
#time ./nicezoom -input franziska8.jpg -o franziska8-big.png

use Gimp ":auto";
use Gimp::Fu;

use strict; use warnings;

# TODO fix this so it can work from within gimp, not only as a script

sub nicezoom {
	my($input, $zoom, $blur_radius, $blur_max_delta, $blur_radius_2_factor, $blur_max_delta_2, $warp_sharp_edge_detection, $warp_sharp_blur_radius, $warp_sharp_bump_depth, $warp_sharp_intensity) = @_;

	# Create a new image of an arbitrary size with 
	my $img = gimp_file_load($input, $input);

	my $drw = $img->get_active_drawable;

	if ($drw->is_indexed) {
		$img->convert_rgb;
		$drw = $img->get_active_drawable;
	}

	if ($blur_radius && $blur_max_delta) {
		plug_in_sel_gauss(1, $img, $drw, $blur_radius, $blur_max_delta);
	}

	my $w = $img->width;
	my $h = $img->height;

	$w = int($w * $zoom + 0.5);
	$h = int($h * $zoom + 0.5);

	$img->scale_full($w, $h, 3);  # SINC (LANCZOS3)

	my $blur_radius_2 = $blur_radius * $zoom * $blur_radius_2_factor;
	if ($blur_radius_2 && $blur_max_delta_2) {
		plug_in_sel_gauss(1, $img, $drw, $blur_radius_2, $blur_max_delta_2);
	}

	# TODO which warp_sharp parameters should depend on the zoom?
	# I am guessing blur_radius only

	if ($warp_sharp_edge_detection && $warp_sharp_blur_radius && $warp_sharp_bump_depth && $warp_sharp_intensity) {
		# this scaling is a bit bogus but gives consistent results
		for ($warp_sharp_edge_detection, $warp_sharp_blur_radius, $warp_sharp_intensity) {
			$_ *= $zoom / 6;
		}
		plug_in_warp_sharp(1, $img, $drw, $warp_sharp_edge_detection, $warp_sharp_blur_radius, $warp_sharp_bump_depth, $warp_sharp_intensity);
	}

	return $img;
}

register "nicezoom", "enlarge an image as nicely as possible", "gets rid of jpeg artifacts with a selective gaussian blur, then enlarges the image with lanczos3",
	"Sam Watkins <swatkins\@fastmail.fm>", "Sam Watkins",
	"2009-02-19",
	"<Toolbox>/Xtns/Perl-Fu/nicezoom", 
	"*",
	[
	 [PF_STRING, "input",          "image to zoom"],
	 [PF_FLOAT,  "zoom",           "zoom",           6],
# TODO target width or height instead?
	 [PF_FLOAT,  "blur_radius",    "blur radius",    1.5],
	 [PF_INT,    "blur_max_delta", "blur max delta", 15],
	 [PF_FLOAT,  "blur_radius_2_factor",    "blur radius 2 factor",    0.5],
	 [PF_INT,    "blur_max_delta_2", "blur max delta 2", 30],
	 [PF_FLOAT,  "warp_sharp_edge_detection", "warp sharp edge detection", 7],
	 [PF_FLOAT,  "warp_sharp_blur_radius", "warp sharp blur radius", 3],
	 [PF_INT,    "warp_sharp_bump_depth", "warp sharp bump depth", 3], # tool default is 2
	 [PF_FLOAT,  "warp_sharp_intensity", "warp sharp intensity", 3.5], # tool default is 2.5
#	 [PF_FLOAT,  "zoom",           "zoom",           6],
## TODO target width or height instead?
#	 [PF_FLOAT,  "blur_radius",    "blur radius",    0.5],
#	 [PF_INT,    "blur_max_delta", "blur max delta", 15],
#	 [PF_FLOAT,  "blur_radius_2_factor",    "blur radius 2 factor",    1],
#	 [PF_INT,    "blur_max_delta_2", "blur max delta 2", 30],
#	 [PF_FLOAT,  "warp_sharp_edge_detection", "warp sharp edge detection", 7],
#	 [PF_FLOAT,  "warp_sharp_blur_radius", "warp sharp blur radius", 3],
#	 [PF_INT,    "warp_sharp_bump_depth", "warp sharp bump depth", 12], # tool default is 2
#	 [PF_FLOAT,  "warp_sharp_intensity", "warp sharp intensity", 3], # tool default is 2.5
	],
	[PF_IMAGE],
	\&nicezoom;

if ($ARGV[0] !~ /^-/) {
	my ($in, $out, @opts) = @ARGV;
	exec $0, "-input", $in, "-o", $out, @opts;
	exit 1;
}

exit main();
