- newer versions of GIMP add a line to gradient files before the
authorTony Cook <tony@develop=help.com>
Fri, 15 Apr 2005 10:48:27 +0000 (10:48 +0000)
committerTony Cook <tony@develop=help.com>
Fri, 15 Apr 2005 10:48:27 +0000 (10:48 +0000)
  segment count giving a descriptive name of the gradient.
  Imager::Fountain can now read and write such gradient files.  The
  interface is a bit indirect, but I'd like to preserve
  Imager::Fountain as a blessed array ref for now.

Changes
MANIFEST
TODO
lib/Imager/Fountain.pm
t/t61filters.t
testimg/newgimpgrad.ggr [new file with mode: 0644]

diff --git a/Changes b/Changes
index 171951f..6481e8a 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1047,6 +1047,13 @@ Revision history for Perl extension Imager.
 - Makefile.PL now adds rules to generate a suitable META.yml to the
   generated Makefile.
 - added sample code for handling images uploaded via a HTML form.
+- saving a GIMP gradiant file with Imager::Fountain->save has always been
+  broken.  Fixed it and added tests.
+- newer versions of GIMP add a line to gradient files before the
+  segment count giving a descriptive name of the gradient.  
+  Imager::Fountain can now read and write such gradient files.  The
+  interface is a bit indirect, but I'd like to preserve
+  Imager::Fountain as a blessed array ref for now.
 
 =================================================================
 
index ecf42e7..023a442 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -197,6 +197,7 @@ testimg/maxval_256.ppm
 testimg/maxval_4095_asc.ppm
 testimg/maxval_65536.ppm
 testimg/maxval_asc.ppm
+testimg/newgimpgrad.ggr Test GIMP Gradient file (newer type)
 testimg/nocmap.gif
 testimg/palette.png
 testimg/palette_out.png
diff --git a/TODO b/TODO
index 936a371..e62d662 100644 (file)
--- a/TODO
+++ b/TODO
@@ -18,7 +18,7 @@ not commitments.
 - examples for fountain filter in Imager::Filters
 - allow Imager::Fountain to take color descriptions (eg. blue, FF000)
   instead of color objects for c0 and c1.
-- support newer GIMP gradient files with the Name line
+- support newer GIMP gradient files with the Name line (done)
 - provide access to right-side bearing information from the bounding box
   function
 - capture TIFF read warnings (i_warnings tag?) (done)
index 10500e8..af7d2f6 100644 (file)
@@ -28,8 +28,17 @@ file or you can build them from scratch.
 
 =item read(gimp=>$filename)
 
-  Loads a gradient from the given GIMP gradient file, and returns a
-  new Imager::Fountain object.
+=item read(gimp=>$filename, name=>\$name)
+
+Loads a gradient from the given GIMP gradient file, and returns a
+new Imager::Fountain object.
+
+If the name parameter is supplied as a scalar reference then any name
+field from newer GIMP gradient files will be returned in it.
+
+  my $gradient = Imager::Fountain->read(gimp=>'foo.ggr');
+  my $name;
+  my $gradient2 = Imager::Fountain->read(gimp=>'bar.ggr', name=>\$name);
 
 =cut
 
@@ -44,7 +53,10 @@ sub read {
       return;
     }
 
-    return $class->_load_gimp_gradient($fh, $opts{gimp});
+    my $trash_name;
+    my $name_ref = $opts{name} && ref $opts{name} ? $opts{name} : \$trash_name;
+
+    return $class->_load_gimp_gradient($fh, $opts{gimp}, $name_ref);
   }
   else {
     warn "$class::read: Nothing to do!";
@@ -54,8 +66,18 @@ sub read {
 
 =item write(gimp=>$filename)
 
+=item write(gimp=>$filename, name=>$name)
+
 Save the gradient to a GIMP gradient file.
 
+The second variant allows the gradient name to be set (for newer
+versions of the GIMP).
+
+  $gradient->write(gimp=>'foo.ggr')
+    or die Imager->errstr;
+  $gradient->write(gimp=>'bar.ggr', name=>'the bar gradient')
+    or die Imager->errstr;
+
 =cut
 
 sub write {
@@ -69,7 +91,7 @@ sub write {
       return;
     }
 
-    return $self->_save_gimp_gradient($fh, $opts{gimp});
+    return $self->_save_gimp_gradient($fh, $opts{gimp}, $opts{name});
   }
   else {
     warn "Nothing to do\n";
@@ -283,18 +305,22 @@ Does the work of loading a GIMP gradient file.
 =cut
 
 sub _load_gimp_gradient {
-  my ($class, $fh, $name) = @_;
+  my ($class, $fh, $filename, $name) = @_;
 
   my $head = <$fh>;
   chomp $head;
   unless ($head eq 'GIMP Gradient') {
-    $Imager::ERRSTR = "$name is not a GIMP gradient file";
+    $Imager::ERRSTR = "$filename is not a GIMP gradient file";
     return;
   }
   my $count = <$fh>;
   chomp $count;
+  if ($count =~ /^name:\s?(.*)/i) {
+    ref $name and $$name = $1;
+    $count = <$fh>; # try again
+  }
   unless ($count =~ /^\d$/) {
-    $Imager::ERRSTR = "$name is missing the segment count";
+    $Imager::ERRSTR = "$filename is missing the segment count";
     return;
   }
   my @result;
@@ -322,18 +348,23 @@ Does the work of saving to a GIMP gradient file.
 =cut
 
 sub _save_gimp_gradient {
-  my ($self, $fh, $name) = @_;
+  my ($self, $fh, $filename, $name) = @_;
 
   print $fh "GIMP Gradient\n";
+  defined $name or $name = '';
+  $name =~ tr/ -~/ /cds;
+  if ($name) {
+    print $fh "Name: $name\n";
+  }
   print $fh scalar(@$self),"\n";
   for my $row (@$self) {
     printf $fh "%.6f %.6f %.6f ",@{$row}[0..2];
     for my $i (0, 1) {
       for ($row->[3+$i]->rgba) {
-        printf $fh, "%.6f ", $_;
+        printf $fh "%.6f ", $_/255.0;
       }
     }
-    print $fh @{$row}[5,6];
+    print $fh "@{$row}[5,6]";
     unless (print $fh "\n") {
       $Imager::ERRSTR = "write error: $!";
       return;
index 65e4504..dcf49d6 100644 (file)
@@ -1,7 +1,7 @@
 #!perl -w
 use strict;
 use Imager qw(:handy);
-use Test::More tests => 45;
+use Test::More tests => 54;
 Imager::init_log("testout/t61filters.log", 1);
 # meant for testing the filters themselves
 my $imbase = Imager->new;
@@ -103,6 +103,37 @@ SKIP:
      "compare test image and diff image");
 }
 
+# newer versions of gimp add a line to the gradient file
+my $name;
+my $f5 = Imager::Fountain->read(gimp=>'testimg/newgimpgrad.ggr',
+                                name => \$name);
+ok($f5, "read newer gimp gradient")
+  or print "# ",Imager->errstr,"\n";
+is($name, "imager test gradient", "check name read correctly");
+$f5 = Imager::Fountain->read(gimp=>'testimg/newgimpgrad.ggr');
+ok($f5, "check we handle case of no name reference correctly")
+  or print "# ",Imager->errstr,"\n";
+
+# test writing of gradients
+ok($f2->write(gimp=>'testout/t61grad1.ggr'), "save a gradient")
+  or print "# ",Imager->errstr,"\n";
+undef $name;
+my $f6 = Imager::Fountain->read(gimp=>'testout/t61grad1.ggr', 
+                                name=>\$name);
+ok($f6, "read what we wrote")
+  or print "# ",Imager->errstr,"\n";
+ok(!defined $name, "we didn't set the name, so shouldn't get one");
+
+# try with a name
+ok($f2->write(gimp=>'testout/t61grad2.ggr', name=>'test gradient'),
+   "write gradient with a name")
+  or print "# ",Imager->errstr,"\n";
+undef $name;
+my $f7 = Imager::Fountain->read(gimp=>'testout/t61grad2.ggr', name=>\$name);
+ok($f7, "read what we wrote")
+  or print "# ",Imager->errstr,"\n";
+is($name, "test gradient", "check the name matches");
+
 sub test {
   my ($in, $params, $out) = @_;
 
diff --git a/testimg/newgimpgrad.ggr b/testimg/newgimpgrad.ggr
new file mode 100644 (file)
index 0000000..b39bff4
--- /dev/null
@@ -0,0 +1,4 @@
+GIMP Gradient
+Name: imager test gradient
+1
+0.000000 0.500000 1.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0 0