PNG re-work: test tags from PNG reads and re-work a little
authorTony Cook <tony@develop-help.com>
Sun, 15 Apr 2012 04:50:52 +0000 (14:50 +1000)
committerTony Cook <tony@develop-help.com>
Sun, 29 Apr 2012 03:40:56 +0000 (13:40 +1000)
libpng synthesizes gAMA and cHRM chunks on input when sRGB is present,
so ignore them if sRGB is present.

No longer generate a png_text tag when the keyword is recognized.

Added png_time

MANIFEST
PNG/MANIFEST
PNG/impng.c
PNG/t/10png.t
PNG/testimg/comment.png [new file with mode: 0644]

index 756b81e..83b3637 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -227,6 +227,7 @@ PNG/t/00load.t
 PNG/t/10png.t                  Test png support
 PNG/testimg/badcrc.png
 PNG/testimg/bilevel.png
+PNG/testimg/comment.png
 PNG/testimg/cover.png
 PNG/testimg/cover16.png
 PNG/testimg/cover16i.png
index 9bd6644..0857920 100644 (file)
@@ -12,6 +12,7 @@ t/00load.t
 t/10png.t
 testimg/badcrc.png
 testimg/bilevel.png
+testimg/comment.png
 testimg/cover.png
 testimg/cover16.png
 testimg/cover16i.png
index f9a7a25..1d63ab3 100644 (file)
@@ -724,25 +724,28 @@ get_png_tags(i_img *im, png_structp png_ptr, png_infop info_ptr, int bit_depth)
   /* the various readers can call png_set_expand(), libpng will make
      it's internal record of bit_depth at least 8 in that case */
   i_tags_setn(&im->tags, "png_bits", bit_depth);
-
   
-  {
+  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
     int intent;
     if (png_get_sRGB(png_ptr, info_ptr, &intent)) {
       i_tags_setn(&im->tags, "png_srgb_intent", intent);
     }
   }
-  {
+  else {
+    /* Ignore these if there's an sRGB chunk, libpng simulates
+       their existence if there's an sRGB chunk, and the PNG spec says
+       that these are ignored if the sRGB is present, so ignore them.
+    */
     double gamma;
-    if (png_get_gAMA(png_ptr, info_ptr, &gamma)) {
-      i_tags_set_float2(&im->tags, "png_gamma", 0, gamma, 4);
-    }
-  }
-  {
     double white_x, white_y;
     double red_x, red_y;
     double green_x, green_y;
     double blue_x, blue_y;
+
+    if (png_get_gAMA(png_ptr, info_ptr, &gamma)) {
+      i_tags_set_float2(&im->tags, "png_gamma", 0, gamma, 4);
+    }
+
     if (png_get_cHRM(png_ptr, info_ptr, &white_x, &white_y,
                     &red_x, &red_y, &green_x, &green_y,
                     &blue_x, &blue_y)) {
@@ -765,26 +768,44 @@ get_png_tags(i_img *im, png_structp png_ptr, png_infop info_ptr, int bit_depth)
       int i;
       for (i = 0; i < num_text; ++i) {
        int j;
-       char tag_name[50];
-       sprintf(tag_name, "png_text%d_key", i);
-       i_tags_set(&im->tags, tag_name, text[i].key, -1);
-       sprintf(tag_name, "png_text%d_text", i);
-       i_tags_set(&im->tags, tag_name, text[i].text, -1);
-       sprintf(tag_name, "png_text%d_type", i);
-       i_tags_set(&im->tags, tag_name, 
-                  (text[i].compression == PNG_TEXT_COMPRESSION_NONE
-                   || text[i].compression == PNG_TEXT_COMPRESSION_zTXt) ?
-                  "text" : "itxt", -1);
+       int found = 0;
 
        for (j = 0; j < text_tags_count; ++j) {
          if (strcmp(text_tags[j].keyword, text[i].key) == 0) {
            i_tags_set(&im->tags, text_tags[j].tagname, text[i].text, -1);
+           found = 1;
            break;
          }
        }
+
+       if (!found) {
+         char tag_name[50];
+         sprintf(tag_name, "png_text%d_key", i);
+         i_tags_set(&im->tags, tag_name, text[i].key, -1);
+         sprintf(tag_name, "png_text%d_text", i);
+         i_tags_set(&im->tags, tag_name, text[i].text, -1);
+         sprintf(tag_name, "png_text%d_type", i);
+         i_tags_set(&im->tags, tag_name, 
+                    (text[i].compression == PNG_TEXT_COMPRESSION_NONE
+                     || text[i].compression == PNG_TEXT_COMPRESSION_zTXt) ?
+                    "text" : "itxt", -1);
+       }
       }
     }
   }
+
+  {
+    png_time *mod_time;
+
+    if (png_get_tIME(png_ptr, info_ptr, &mod_time)) {
+      char time_formatted[80];
+
+      sprintf(time_formatted, "%d-%02d-%02dT%02d:%02d:%02d",
+             mod_time->year, mod_time->month, mod_time->day,
+             mod_time->hour, mod_time->minute, mod_time->second);
+      i_tags_set(&im->tags, "png_time", time_formatted, -1);
+    }
+  }
 }
 
 static int
index 8ef0141..ff9fb57 100644 (file)
@@ -10,7 +10,7 @@ my $debug_writes = 1;
 
 init_log("testout/t102png.log",1);
 
-plan tests => 204;
+plan tests => 210;
 
 # this loads Imager::File::PNG too
 ok($Imager::formats{"png"}, "must have png format");
@@ -568,6 +568,21 @@ SKIP:
   is($in->tags(name => "png_bits"), 16, "check png_bits");
 }
 
+SKIP:
+{
+  my $im = Imager->new(file => "testimg/comment.png");
+  ok($im, "read file with comment")
+    or diag("Cannot read comment.png: ".Imager->errstr);
+  $im
+    or skip("Cannot test tags file I can't read", 5);
+  is($im->tags(name => "i_comment"), "Test comment", "check i_comment");
+  is($im->tags(name => "png_interlace"), "0", "no interlace");
+  is($im->tags(name => "png_interlace_name"), "none", "no interlace (text)");
+  is($im->tags(name => "png_srgb_intent"), "0", "srgb perceptual");
+  is($im->tags(name => "png_time"), "2012-04-15T03:36:50",
+     "modification time");
+}
+
 sub limited_write {
   my ($limit) = @_;
 
diff --git a/PNG/testimg/comment.png b/PNG/testimg/comment.png
new file mode 100644 (file)
index 0000000..8962fe1
Binary files /dev/null and b/PNG/testimg/comment.png differ