#!/usr/bin/perl -w
#
# Copyright (c) 2006 David Sheldon
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# split.pl
# Split all of the images within a file into segments.
# The command line parameters are the filename, number of rows,
# and number of columns.
#
use Image::Magick;

my ($filename, $hgrid, $vgrid, $status) ;

# Check to see if the three required parameters are provided...
# $vgrid is the number of rows, $hgrid is the number of columns
#
if (($filename = $ARGV[0]) &&
    ($vgrid = $ARGV[1]) &&
    ($hgrid = $ARGV[2])) {
    
    my $images = new Image::Magick;           # source file
    my $images2 = new Image::Magick;          # used later as a temp image
    $status = $images->Read("$filename");     # file may be multi-image
    die "Couldn't open file $filename!" if "$status";
    
    my $imagecount = @$images;                # number of scenes
    $images->Set(adjoin=>0);                  # split into separate images
    
    print STDERR "Writing scene files...\n";
    # If it is a multi-image file, write each of the
    # individual scenes for reference purposes...
    #
    $images->Write() if ($imagecount>1);                 
   
    my ($width, $height) = $images->Get('width', 'height');
    my @x = (0);               # This list contains the x values of the crop grid
    my @y = (0);               # This contains the y values

    # Set up the horizontal crop grid.
    # Because of rounding errors, not all tiles will be the same
    # dimensions unless $width is a multiple of $hgrid. To make sure 
    # we don't lose any pixels, the last tile in the grid should 
    # always crop to the width of the image...
    #
    foreach my $count (1..$hgrid) {
        if ($count == $hgrid) {
            push @x, $width;       # crop to the edge
        } else {
            # otherwise the width of the tile should be int($width/$hgrid)
            #
            push @x, $count * int($width/$hgrid);  
        }
    }
    
    # Now set up the vertical crop grid...
    #
    foreach my $count (1..$vgrid) {
        if ($count == $vgrid) {
            push @y, $height;
        } else {
            push @y, $count * int($height/$vgrid);
        }
    }

    my $geometry;              # This will be the string passed to Crop()
    foreach my $xcount (0..$hgrid-1) {
        foreach my $ycount (0..$vgrid-1) {
            # The Clone() method copies the content of $images
            #
            $images2 = $images->Clone();    
        
            # Set up the geometry string
            #
            $geometry = ($x[$xcount+1] - $x[$xcount])."x".
                        ($y[$ycount+1] - $y[$ycount]).
                        "+$x[$xcount]+$y[$ycount]";
            print STDERR "Crop $geometry\n";
            $images2->Crop("$geometry");
        
            # Write a file consisting of the cropped tile for 
            # each scene. The filename will be in the form 
            # filename.x.y.scene where x and y is the coordinate of
            # the upper left coordinate of the tile.
            #
            $images2->Write("jpg:tile-$xcount-$ycount.jpg");
            undef $images2;     # Clean up
        }
    }
    undef $images;              # Clean up
    print STDERR "Done!...\n";
} else {
    print "Usage: perl split.pl filename rows columns\n";
}
