#!/usr/bin/perl
#
# Gimp plugin for Gaussian destriping, as described in
# http://www.no-hype.com/articles/denoise.html
#

use Gimp qw(:auto N_ __);
use Gimp::Fu;

use constant HORIZONTAL => 1;
use constant VERTICAL => 2;

sub do_destripe {
  my ($img, $dwb, $width, $direction) = @_;

  $dwb->is_layer() or die "this plug-in only works for layers";

  $img->undo_group_start;
  # Make sure we don't bail out before ending the undo group.
  eval {
    my $horblur = $direction = HORIZONTAL ? $width : 1;
    my $vrtblur = $direction = HORIZONTAL ? 1 : $width;

    my @selection_info = $img->selection_bounds;
    my $has_selection = $selection_info[0];

    # save visibility and set selected layer as only visible one
    my $layer_vis = {};
    foreach my $layer ($img->get_layers) {
      $layer_vis->{$layer->get_tattoo} = $layer->get_visible();
      $layer->set_visible(0);
    }
    $dwb->set_visible(1);

    my $dsl = $dwb->copy(1); # DeStripe Layer
    $img->add_layer($dsl, -1);
    my $cel = $dwb->copy(1); # Contrast Enhancing Layer
    $img->add_layer($cel, -1);

    # Do the stuff as described in the web page
    $dsl->plug_in_gauss_iir2($horblur, $vrtblur);
    $cel->plug_in_gauss_iir2($width, $width);
    $dsl->set_mode(OVERLAY_MODE);
    $cel->set_mode(OVERLAY_MODE);
    $dsl->invert;

    # if there is a selection, limit the effect to just the selection.
    if ($has_selection) {
      $img->selection_invert;
      $dsl->edit_clear;
      $cel->edit_clear;
      $img->selection_invert;
    }

    my $new_dwb = $img->merge_visible_layers(0);

    # restore visibility settings
    foreach my $layer ($img->get_layers) {
      $layer->set_visible($layer_vis->{$layer->get_tattoo});
    }
  };
  $img->undo_group_end;
  warn "done!\n";
  ();
}

register
"destripe_gauss",
'Remove stripes using gaussian frequency filtering',
'Get rid of those annoying artifacts',
'Matijs van Zuijlen',
'Matijs van Zuijlen <mvz@xs4all.nl>',
'2004-09-27',
N_"<Image>/Filters/Enhance/G_aussian destripe...",
'RGB*,GRAY*',
[
[PF_INT, "blur_size", "Size of the gaussian blur to be used", 32],
[PF_RADIO, "direction", "The direction of the stripes to remove",
HORIZONTAL, [Horizontal => HORIZONTAL, Vertical => VERTICAL] ]
],
[],
\&do_destripe;

exit main;

=head1 LICENSE

Copyright Matijs van Zuijlen
Distrubuted under the same terms as Gimp-Perl.

=cut
