#
# This filter allows one to pass frame data through the Gimp for
# processing.  The main script (the one you're looking at) does the
# grunt work of converting the frame data to a Gimp drawable.  Once
# this is done, the drawable is passed to a user-specified script
# which can perform it's own processing.  eg:
#
# cat stream.yuv | perl yuvgimp.pl -script myscript.pl > result.yuv
#
# See gimp_emboss.pl for an example yuvgimp script.
#

package GimpFilter::Main;

use Gimp qw(:auto);
use Gimp::Fu;
use YUV4MPEG;

register "yuv_gimp_filter",
         "filter a YUV image through The Gimp",
         "",
         "Brett Kosinski",
         "Brett Kosinski <brettk\@frodo.dyn.gno.org>",
         "20030311",
         "<None>",
         "RGB*",
         [
           [PF_STRING, "script", "The filter script to run on input."],
           [PF_STRING, "call",   "The function to call for each frame.", "filter"]
         ],
         \&yuv_filter;

exit main;

sub yuv_filter
{
    my $script = shift;
    my $function = shift;

    GimpFilter::Sandbox::load_script($script);

    my $streaminfo = new YUV4MPEG::StreamInfo;
    my $frameinfo = new YUV4MPEG::FrameInfo;

    $streaminfo->read();
    $streaminfo->write();

    my ($w, $h) = ($streaminfo->get_width(),
                   $streaminfo->get_height());

    my $frame = new YUV4MPEG::Frame($streaminfo);
    my $img = new Gimp::Image($w, $h, RGB_IMAGE);
    my $layer = $img->layer_new($w, $h, RGB_IMAGE, "image", 100, NORMAL_MODE);

    $img->add_layer($layer, 0);        

    while ($frame->read($frameinfo) == Y4M_OK)
    {
        my $region = $layer->pixel_rgn(0, 0, $w, $h, 1, 0);
        my $handle = Gimp->pixel_rgns_register($region);
        my $rgb;

        $frame->to_rgb();
        $rgb = $frame->get_packed_data();

        $region->set_rect2($rgb, 0, 0, $w);
        Gimp->pixel_rgns_process($handle);

        GimpFilter::Sandbox::exec_script($img, $function);

        $img->flatten();

        ($layer) = $img->get_layers();
        $region = $layer->pixel_rgn(0, 0, $w, $h, 0, 0);

        $rgb = $region->get_rect2(0, 0, $w, $h);
        $frame->set_packed_data($rgb);
        $frame->to_yuv();

        $frame->write($frameinfo);
        
        $frameinfo = new YUV4MPEG::FrameInfo;
    }

    return undef;
}

package GimpFilter::Sandbox;

sub load_script
{
    my $script = shift;

    do $script;

    die $@ if ($@);
}

sub exec_script
{
    my ($img, $func) = @_;

    eval "\&$func(\$img)";
}
