Update libpng to version 1.6.3

Change-Id: I86cb46ec376eb41324b82d2875757aeda734c5c1
diff --git a/contrib/pngminus/pnm2png.c b/contrib/pngminus/pnm2png.c
index 4cdfad8..f9903dd 100644
--- a/contrib/pngminus/pnm2png.c
+++ b/contrib/pngminus/pnm2png.c
@@ -18,6 +18,7 @@
 #include <mem.h>
 #include <fcntl.h>
 #endif
+#include <zlib.h>
 
 #ifndef BOOL
 #define BOOL unsigned char
@@ -197,6 +198,9 @@
   char          height_token[16];
   char          maxval_token[16];
   int           color_type;
+  unsigned long   ul_width=0, ul_alpha_width=0;
+  unsigned long   ul_height=0, ul_alpha_height=0;
+  unsigned long   ul_maxval=0;
   png_uint_32   width, alpha_width;
   png_uint_32   height, alpha_height;
   png_uint_32   maxval;
@@ -206,6 +210,9 @@
   int           alpha_present;
   int           row, col;
   BOOL          raw, alpha_raw = FALSE;
+#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+  BOOL          packed_bitmap = FALSE;
+#endif
   png_uint_32   tmp16;
   int           i;
 
@@ -218,20 +225,36 @@
   }
   else if ((type_token[1] == '1') || (type_token[1] == '4'))
   {
+#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
     raw = (type_token[1] == '4');
     color_type = PNG_COLOR_TYPE_GRAY;
+    get_token(pnm_file, width_token);
+    sscanf (width_token, "%lu", &ul_width);
+    width = (png_uint_32) ul_width;
+    get_token(pnm_file, height_token);
+    sscanf (height_token, "%lu", &ul_height);
+    height = (png_uint_32) ul_height;
     bit_depth = 1;
+    packed_bitmap = TRUE;
+#else
+    fprintf (stderr, "PNM2PNG built without PNG_WRITE_INVERT_SUPPORTED and \n");
+    fprintf (stderr, "PNG_WRITE_PACK_SUPPORTED can't read PBM (P1,P4) files\n");
+#endif
   }
   else if ((type_token[1] == '2') || (type_token[1] == '5'))
   {
     raw = (type_token[1] == '5');
     color_type = PNG_COLOR_TYPE_GRAY;
     get_token(pnm_file, width_token);
-    sscanf (width_token, "%lu", &width);
+    sscanf (width_token, "%lu", &ul_width);
+    width = (png_uint_32) ul_width;
     get_token(pnm_file, height_token);
-    sscanf (height_token, "%lu", &height);
+    sscanf (height_token, "%lu", &ul_height);
+    height = (png_uint_32) ul_height;
     get_token(pnm_file, maxval_token);
-    sscanf (maxval_token, "%lu", &maxval);
+    sscanf (maxval_token, "%lu", &ul_maxval);
+    maxval = (png_uint_32) ul_maxval;
+
     if (maxval <= 1)
       bit_depth = 1;
     else if (maxval <= 3)
@@ -248,11 +271,14 @@
     raw = (type_token[1] == '6');
     color_type = PNG_COLOR_TYPE_RGB;
     get_token(pnm_file, width_token);
-    sscanf (width_token, "%lu", &width);
+    sscanf (width_token, "%lu", &ul_width);
+    width = (png_uint_32) ul_width;
     get_token(pnm_file, height_token);
-    sscanf (height_token, "%lu", &height);
+    sscanf (height_token, "%lu", &ul_height);
+    height = (png_uint_32) ul_height;
     get_token(pnm_file, maxval_token);
-    sscanf (maxval_token, "%lu", &maxval);
+    sscanf (maxval_token, "%lu", &ul_maxval);
+    maxval = (png_uint_32) ul_maxval;
     if (maxval <= 1)
       bit_depth = 1;
     else if (maxval <= 3)
@@ -287,15 +313,18 @@
     {
       alpha_raw = (type_token[1] == '5');
       get_token(alpha_file, width_token);
-      sscanf (width_token, "%lu", &alpha_width);
+      sscanf (width_token, "%lu", &ul_alpha_width);
+      alpha_width=(png_uint_32) ul_alpha_width;
       if (alpha_width != width)
         return FALSE;
       get_token(alpha_file, height_token);
-      sscanf (height_token, "%lu", &alpha_height);
+      sscanf (height_token, "%lu", &ul_alpha_height);
+      alpha_height = (png_uint_32) ul_alpha_height;
       if (alpha_height != height)
         return FALSE;
       get_token(alpha_file, maxval_token);
-      sscanf (maxval_token, "%lu", &maxval);
+      sscanf (maxval_token, "%lu", &ul_maxval);
+      maxval = (png_uint_32) ul_maxval;
       if (maxval <= 1)
         alpha_depth = 1;
       else if (maxval <= 3)
@@ -329,8 +358,14 @@
 
   alpha_present = (channels - 1) % 2;
 
-  /* row_bytes is the width x number of channels x (bit-depth / 8) */
-  row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
+#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+  if (packed_bitmap)
+    /* row data is as many bytes as can fit width x channels x bit_depth */
+    row_bytes = (width * channels * bit_depth + 7) / 8;
+  else
+#endif
+    /* row_bytes is the width x number of channels x (bit-depth / 8) */
+    row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
 
   if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL)
     return FALSE;
@@ -340,40 +375,48 @@
 
   for (row = 0; row < height; row++)
   {
-    for (col = 0; col < width; col++)
+#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+    if (packed_bitmap) {
+      for (i = 0; i < row_bytes; i++)
+        /* png supports this format natively so no conversion is needed */
+        *pix_ptr++ = get_data (pnm_file, 8);
+    } else
+#endif
     {
-      for (i = 0; i < (channels - alpha_present); i++)
+      for (col = 0; col < width; col++)
       {
-        if (raw)
-          *pix_ptr++ = get_data (pnm_file, bit_depth);
-        else
-          if (bit_depth <= 8)
-            *pix_ptr++ = get_value (pnm_file, bit_depth);
+        for (i = 0; i < (channels - alpha_present); i++)
+        {
+          if (raw)
+            *pix_ptr++ = get_data (pnm_file, bit_depth);
           else
-          {
-            tmp16 = get_value (pnm_file, bit_depth);
-            *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF);
-            pix_ptr++;
-            *pix_ptr = (png_byte) (tmp16 & 0xFF);
-            pix_ptr++;
-          }
-      }
+            if (bit_depth <= 8)
+              *pix_ptr++ = get_value (pnm_file, bit_depth);
+            else
+            {
+              tmp16 = get_value (pnm_file, bit_depth);
+              *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF);
+              pix_ptr++;
+              *pix_ptr = (png_byte) (tmp16 & 0xFF);
+              pix_ptr++;
+            }
+        }
 
-      if (alpha) /* read alpha-channel from pgm file */
-      {
-        if (alpha_raw)
-          *pix_ptr++ = get_data (alpha_file, alpha_depth);
-        else
-          if (alpha_depth <= 8)
-            *pix_ptr++ = get_value (alpha_file, bit_depth);
+        if (alpha) /* read alpha-channel from pgm file */
+        {
+          if (alpha_raw)
+            *pix_ptr++ = get_data (alpha_file, alpha_depth);
           else
-          {
-            tmp16 = get_value (alpha_file, bit_depth);
-            *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF);
-            *pix_ptr++ = (png_byte) (tmp16 & 0xFF);
-          }
-      } /* if alpha */
-
+            if (alpha_depth <= 8)
+              *pix_ptr++ = get_value (alpha_file, bit_depth);
+            else
+            {
+              tmp16 = get_value (alpha_file, bit_depth);
+              *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF);
+              *pix_ptr++ = (png_byte) (tmp16 & 0xFF);
+            }
+        } /* if alpha */
+      } /* if packed_bitmap */
     } /* end for col */
   } /* end for row */
 
@@ -390,6 +433,14 @@
     return FALSE;
   }
 
+#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+  if (packed_bitmap == TRUE)
+  {
+    png_set_packing (png_ptr);
+    png_set_invert_mono (png_ptr);
+  }
+#endif
+
   /* setjmp() must be called in every function that calls a PNG-reading libpng function */
   if (setjmp (png_jmpbuf(png_ptr)))
   {
@@ -446,19 +497,32 @@
 void get_token(FILE *pnm_file, char *token)
 {
   int i = 0;
+  int ret;
 
-  /* remove white-space */
+  /* remove white-space and comment lines */
   do
   {
-    token[i] = (unsigned char) fgetc (pnm_file);
+    ret = fgetc(pnm_file);
+    if (ret == '#') {
+      /* the rest of this line is a comment */
+      do
+      {
+        ret = fgetc(pnm_file);
+      }
+      while ((ret != '\n') && (ret != '\r') && (ret != EOF));
+    }
+    if (ret == EOF) break;
+    token[i] = (unsigned char) ret;
   }
   while ((token[i] == '\n') || (token[i] == '\r') || (token[i] == ' '));
 
   /* read string */
   do
   {
+    ret = fgetc(pnm_file);
+    if (ret == EOF) break;
     i++;
-    token[i] = (unsigned char) fgetc (pnm_file);
+    token[i] = (unsigned char) ret;
   }
   while ((token[i] != '\n') && (token[i] != '\r') && (token[i] != ' '));
 
@@ -510,6 +574,7 @@
 {
   static png_uint_32 mask = 0;
   png_byte token[16];
+  unsigned long ul_ret_value;
   png_uint_32 ret_value;
   int i = 0;
 
@@ -518,7 +583,8 @@
       mask = (mask << 1) | 0x01;
 
   get_token (pnm_file, (char *) token);
-  sscanf ((const char *) token, "%lu", &ret_value);
+  sscanf ((const char *) token, "%lu", &ul_ret_value);
+  ret_value = (png_uint_32) ul_ret_value;
 
   ret_value &= mask;