Imported Upstream version 1.6.39
[platform/upstream/libpng.git] / contrib / libtests / pngunknown.c
index 0d52ff8..dfa9d10 100644 (file)
@@ -1,8 +1,8 @@
 
 /* pngunknown.c - test the read side unknown chunk handling
  *
- * Last changed in libpng 1.6.10 [March 6, 2014]
- * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Copyright (c) 2021 Cosmin Truta
+ * Copyright (c) 2015,2017 Glenn Randers-Pehrson
  * Written by John Cunningham Bowler
  *
  * This code is released under the libpng license.
 #  include "../../png.h"
 #endif
 
+/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
+ * a skipped test, in earlier versions we need to succeed on a skipped test, so:
+ */
+#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
+#  define SKIP 77
+#else
+#  define SKIP 0
+#endif
+
+
 /* Since this program tests the ability to change the unknown chunk handling
  * these must be defined:
  */
 #if defined(PNG_SET_UNKNOWN_CHUNKS_SUPPORTED) &&\
+   defined(PNG_STDIO_SUPPORTED) &&\
    defined(PNG_READ_SUPPORTED)
 
 /* One of these must be defined to allow us to find out what happened.  It is
@@ -45,7 +56,7 @@
    defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)
 
 #if PNG_LIBPNG_VER < 10500
-/* This deliberately lacks the PNG_CONST. */
+/* This deliberately lacks the const. */
 typedef png_byte *png_const_bytep;
 
 /* This is copied from 1.5.1 png.h: */
@@ -74,7 +85,7 @@ typedef png_byte *png_const_bytep;
 #define PNG_WRITE_16BIT_SUPPORTED
 #define PNG_READ_16BIT_SUPPORTED
 
-/* This comes from pnglibconf.h afer 1.5: */
+/* This comes from pnglibconf.h after 1.5: */
 #define PNG_FP_1 100000
 #define PNG_GAMMA_THRESHOLD_FIXED\
    ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))
@@ -103,6 +114,7 @@ typedef png_byte *png_const_bytep;
 #define png_PLTE PNG_U32( 80,  76,  84,  69)
 #define png_bKGD PNG_U32( 98,  75,  71,  68)
 #define png_cHRM PNG_U32( 99,  72,  82,  77)
+#define png_eXIf PNG_U32(101,  88,  73, 102) /* registered July 2017 */
 #define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */
 #define png_gAMA PNG_U32(103,  65,  77,  65)
 #define png_gIFg PNG_U32(103,  73,  70, 103)
@@ -199,6 +211,13 @@ static struct
          1,
 #     endif
       1,  START, 0 },
+   { "eXIf", PNG_INFO_eXIf, png_eXIf,
+#     ifdef PNG_READ_eXIf_SUPPORTED
+         0,
+#     else
+         1,
+#     endif
+      1,  END, 0 },
    { "gAMA", PNG_INFO_gAMA, png_gAMA,
 #     ifdef PNG_READ_gAMA_SUPPORTED
          0,
@@ -351,7 +370,9 @@ find_by_flag(png_uint_32 flag)
 {
    int i = NINFO;
 
-   while (--i >= 0) if (chunk_info[i].flag == flag) return i;
+   while (--i >= 0)
+      if (chunk_info[i].flag == flag)
+         return i;
 
    fprintf(stderr, "pngunknown: internal error\n");
    exit(4);
@@ -467,7 +488,7 @@ get_valid(display *d, png_infop info_ptr)
       png_textp text;
       png_uint_32 ntext = png_get_text(d->png_ptr, info_ptr, &text, NULL);
 
-      while (ntext-- > 0) switch (text[ntext].compression)
+      while (ntext > 0) switch (text[--ntext].compression)
       {
          case -1:
             flags |= PNG_INFO_tEXt;
@@ -528,27 +549,30 @@ read_callback(png_structp pp, png_unknown_chunkp pc)
 
       case PNG_HANDLE_CHUNK_AS_DEFAULT:
       case PNG_HANDLE_CHUNK_NEVER:
-         discard = 1/*handled; discard*/;
+         discard = 1; /*handled; discard*/
          break;
 
       case PNG_HANDLE_CHUNK_IF_SAFE:
       case PNG_HANDLE_CHUNK_ALWAYS:
-         discard = 0/*not handled; keep*/;
+         discard = 0; /*not handled; keep*/
          break;
    }
 
    /* Also store information about this chunk in the display, the relevant flag
     * is set if the chunk is to be kept ('not handled'.)
     */
-   if (chunk >= 0) if (!discard) /* stupidity to stop a GCC warning */
+   if (chunk >= 0)
    {
-      png_uint_32 flag = chunk_info[chunk].flag;
+      if (!discard) /* stupidity to stop a GCC warning */
+      {
+         png_uint_32 flag = chunk_info[chunk].flag;
 
-      if (pc->location & PNG_AFTER_IDAT)
-         d->after_IDAT |= flag;
+         if (pc->location & PNG_AFTER_IDAT)
+            d->after_IDAT |= flag;
 
-      else
-         d->before_IDAT |= flag;
+         else
+            d->before_IDAT |= flag;
+      }
    }
 
    /* However if there is no support to store unknown chunks don't ask libpng to
@@ -603,7 +627,7 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT)
                   ++(d->error_count);
                   break;
                }
-               /* FALL THROUGH (safe) */
+               /* FALLTHROUGH */ /* (safe) */
             case PNG_HANDLE_CHUNK_ALWAYS:
                break;
          }
@@ -615,7 +639,7 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT)
 
    return flags;
 }
-#else
+#else /* SAVE_UNKNOWN_CHUNKS */
 static png_uint_32
 get_unknown(display *d, png_infop info_ptr, int after_IDAT)
    /* Otherwise this will return the cached values set by any user callback */
@@ -634,8 +658,8 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT)
        * a check to ensure the logic is correct.
        */
 #     error No store support and no user chunk support, this will not work
-#  endif
-#endif
+#  endif /* READ_USER_CHUNKS */
+#endif /* SAVE_UNKNOWN_CHUNKS */
 
 static int
 check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/,
@@ -822,8 +846,9 @@ check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/,
             {
                png_uint_32 y;
 
-               for (y=0; y<height; ++y) if (PNG_ROW_IN_INTERLACE_PASS(y, ipass))
-                  png_read_row(d->png_ptr, NULL, NULL);
+               for (y=0; y<height; ++y)
+                  if (PNG_ROW_IN_INTERLACE_PASS(y, ipass))
+                     png_read_row(d->png_ptr, NULL, NULL);
             }
          }
       } /* interlaced */
@@ -1001,6 +1026,20 @@ perform_one_test(FILE *fp, int argc, const char **argv,
 
    def = check(fp, argc, argv, flags[1], d, set_callback);
 
+   /* If IDAT is being handled as unknown the image read is skipped and all the
+    * IDATs after the first end up in the end info struct, so in this case add
+    * IDAT to the list of unknowns.  (Do this after 'check' above sets the
+    * chunk_info 'keep' fields.)
+    *
+    * Note that the flag setting has to be in the 'known' field to avoid
+    * triggering the consistency check below and the flag must only be set if
+    * there are multiple IDATs, so if the check above did find an unknown IDAT
+    * after IDAT.
+    */
+   if (chunk_info[0/*IDAT*/].keep != PNG_HANDLE_CHUNK_AS_DEFAULT &&
+       (flags[1][3] & PNG_INFO_IDAT) != 0)
+      flags[0][2] |= PNG_INFO_IDAT;
+
    /* Chunks should either be known or unknown, never both and this should apply
     * whether the chunk is before or after the IDAT (actually, the app can
     * probably change this by swapping the handling after the image, but this
@@ -1058,15 +1097,15 @@ perform_one_test_safe(FILE *fp, int argc, const char **argv,
 
 static const char *standard_tests[] =
 {
"discard", "default=discard", 0,
"save", "default=save", 0,
"if-safe", "default=if-safe", 0,
"vpAg", "vpAg=if-safe", 0,
"sTER", "sTER=if-safe", 0,
"IDAT", "default=discard", "IDAT=save", 0,
- "sAPI", "bKGD=save", "cHRM=save", "gAMA=save", "all=discard", "iCCP=save",
-   "sBIT=save", "sRGB=save", 0,
0/*end*/
  "discard", "default=discard", NULL,
  "save", "default=save", NULL,
  "if-safe", "default=if-safe", NULL,
  "vpAg", "vpAg=if-safe", NULL,
  "sTER", "sTER=if-safe", NULL,
  "IDAT", "default=discard", "IDAT=save", NULL,
  "sAPI", "bKGD=save", "cHRM=save", "gAMA=save", "all=discard", "iCCP=save",
+      "sBIT=save", "sRGB=save", "eXIf=save", NULL,
  NULL /*end*/
 };
 
 static PNG_NORETURN void
@@ -1082,7 +1121,7 @@ int
 main(int argc, const char **argv)
 {
    FILE *fp;
-   png_uint_32 default_flags[4/*valid,unknown{before,after}*/];
+   png_uint_32 default_flags[4]; /*valid,unknown{before,after}*/
    int strict = 0, default_tests = 0;
    const char *count_argv = "default=save";
    const char *touch_file = NULL;
@@ -1120,8 +1159,9 @@ main(int argc, const char **argv)
    /* GCC BUG: if (default_tests && argc != 1) triggers some weird GCC argc
     * optimization which causes warnings with -Wstrict-overflow!
     */
-   else if (default_tests) if (argc != 1)
-      usage(d.program, "extra arguments");
+   else if (default_tests)
+      if (argc != 1)
+         usage(d.program, "extra arguments");
 
    /* The name of the test file is the last argument; remove it. */
    d.file = argv[--argc];
@@ -1183,7 +1223,11 @@ main(int argc, const char **argv)
          const char *result;
          int arg_count = 0;
 
-         while (*next) ++next, ++arg_count;
+         while (*next != NULL)
+         {
+            ++next;
+            ++arg_count;
+         }
 
          perform_one_test_safe(fp, arg_count, test, default_flags, &d,
             this_test);
@@ -1245,7 +1289,7 @@ main(void)
    fprintf(stderr,
       " test ignored: no support to find out about unknown chunks\n");
    /* So the test is skipped: */
-   return 77;
+   return SKIP;
 }
 #endif /* READ_USER_CHUNKS || SAVE_UNKNOWN_CHUNKS */
 
@@ -1256,6 +1300,6 @@ main(void)
    fprintf(stderr,
       " test ignored: no support to modify unknown chunk handling\n");
    /* So the test is skipped: */
-   return 77;
+   return SKIP;
 }
 #endif /* SET_UNKNOWN_CHUNKS && READ*/