add png_compression_level parameter for writing PNG files
authorTony Cook <tony@develop-help.com>
Mon, 4 Jun 2018 09:38:57 +0000 (19:38 +1000)
committerTony Cook <tony@develop-help.com>
Mon, 4 Jun 2018 09:38:57 +0000 (19:38 +1000)
PNG/PNG.pm
PNG/impng.c
PNG/t/10png.t
lib/Imager/Files.pod

index 954e964..f145d0e 100644 (file)
@@ -4,7 +4,7 @@ use Imager;
 use vars qw($VERSION @ISA);
 
 BEGIN {
-  $VERSION = "0.92";
+  $VERSION = "0.93";
 
   require XSLoader;
   XSLoader::load('Imager::File::PNG', $VERSION);
index ac3f9fe..c7a7b8e 100644 (file)
@@ -2,6 +2,7 @@
 #include "png.h"
 #include <stdlib.h>
 #include <string.h>
+#include <zlib.h>
 
 /* this is a way to get number of channels from color space 
  * Color code to channel number */
@@ -1137,6 +1138,19 @@ set_png_tags(i_img *im, png_structp png_ptr, png_infop info_ptr) {
     }
   }
 
+  {
+    int level;
+    if (i_tags_get_int(&im->tags, "png_compression_level", 0, &level)) {
+      if (level >= Z_NO_COMPRESSION && level <= Z_BEST_COMPRESSION) 
+       png_set_compression_level(png_ptr, level);
+      else {
+       i_push_errorf(0, "png_compression_level must be between %d and %d",
+                     Z_NO_COMPRESSION, Z_BEST_COMPRESSION);
+       return 0;
+      }
+    }
+  }
+
   {
     /* no bKGD support yet, maybe later
        it may be simpler to do it in the individual writers
index b191507..2892a56 100644 (file)
@@ -10,7 +10,7 @@ my $debug_writes = 1;
 
 init_log("testout/t102png.log",1);
 
-plan tests => 251;
+plan tests => 256;
 
 # this loads Imager::File::PNG too
 ok($Imager::formats{"png"}, "must have png format");
@@ -799,6 +799,23 @@ SKIP:
   }
 }
 
+{
+  # png_compression_level
+  my $im = test_image();
+  my $out1;
+  ok($im->write(data => \$out1, type => "png"), "write default compression");
+  my $out2;
+  ok($im->write(data => \$out2, type => "png", png_compression_level => 9),
+     "write best compression");
+  cmp_ok(length($out1), '>', length($out2), "best compression smaller than default");
+  note "went from ", length($out1), " to ", length($out2);
+  # error handling
+  ok(!$im->write(data => \$out1, type => "png", png_compression_level => -1),
+     "fail with compression level -1");
+  ok(!$im->write(data => \$out1, type => "png", png_compression_level => 10),
+     "fail with compression level 10");
+}
+
 sub limited_write {
   my ($limit) = @_;
 
index 0c3c16d..e19a68f 100644 (file)
@@ -1449,7 +1449,7 @@ C<adam7>.
 X<tags, png_srgb_intent>C<png_srgb_intent> - the sRGB rendering intent
 for the image. an integer from 0 to 3, per the PNG specification.  If
 this chunk is found in the PNG file the C<gAMA> and C<cHRM> are
-ignored and the C<png_gamme> and C<png_chroma_...> tags are not set.
+ignored and the C<png_gamma> and C<png_chroma_...> tags are not set.
 Similarly when writing if C<png_srgb_intent> is set the C<gAMA> and
 C<cHRM> chunks are not written.
 
@@ -1492,6 +1492,11 @@ C<i_background> - set from the C<sBKG> when reading an image file.
 
 =back
 
+X<compression>X<png_compression_level>You can control the level of
+F<zlib> compression used when writing with the
+C<png_compression_level> parameter.  This can be an integer between 0
+(uncompressed) and 9 (best compression).
+
 =for stopwords
 CRC