< prev index next >

src/share/native/sun/awt/libpng/png.c

Print this page
rev 1287 : 8143941: Update splashscreen displays
Reviewed-by: ahgross, prr, serb
rev 1288 : 8144955: Wrong changes were pushed with 8143942
Reviewed-by: prr, serb

@@ -27,12 +27,12 @@
  * This file is available under and governed by the GNU General Public
  * License version 2 only, as published by the Free Software Foundation.
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Last changed in libpng 1.6.16 [December 22, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.19 [November 12, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer

@@ -40,11 +40,11 @@
  */
 
 #include "pngpriv.h"
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_16 Your_png_h_is_not_version_1_6_16;
+typedef png_libpng_version_1_6_20 Your_png_h_is_not_version_1_6_20;
 
 /* Tells libpng that we have already handled the first "num_bytes" bytes
  * of the PNG file signature.  If the PNG data is embedded into another
  * stream we can set num_bytes = 8 so that libpng will not attempt to read
  * or write any of the magic bytes before it starts on the IHDR.

@@ -52,19 +52,24 @@
 
 #ifdef PNG_READ_SUPPORTED
 void PNGAPI
 png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
 {
+   unsigned int nb = (unsigned int)num_bytes;
+
    png_debug(1, "in png_set_sig_bytes");
 
    if (png_ptr == NULL)
       return;
 
-   if (num_bytes > 8)
+   if (num_bytes < 0)
+      nb = 0;
+
+   if (nb > 8)
       png_error(png_ptr, "Too many bytes for PNG signature");
 
-   png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
+   png_ptr->sig_bytes = (png_byte)nb;
 }
 
 /* Checks whether the supplied bytes match the PNG signature.  We allow
  * checking less than the full 8-byte signature so that those apps that
  * already read the first few bytes of a file to determine the file type

@@ -127,11 +132,11 @@
  * in case CRC is > 32 bits to leave the top bits 0.
  */
 void /* PRIVATE */
 png_reset_crc(png_structrp png_ptr)
 {
-   /* The cast is safe because the crc is a 32 bit value. */
+   /* The cast is safe because the crc is a 32-bit value. */
    png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
 }
 
 /* Calculate the CRC over a section of data.  We can only pass as
  * much data to this routine as the largest single buffer size.  We

@@ -155,23 +160,25 @@
       if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
          need_crc = 0;
    }
 
    /* 'uLong' is defined in zlib.h as unsigned long; this means that on some
-    * systems it is a 64 bit value.  crc32, however, returns 32 bits so the
+    * systems it is a 64-bit value.  crc32, however, returns 32 bits so the
     * following cast is safe.  'uInt' may be no more than 16 bits, so it is
     * necessary to perform a loop here.
     */
    if (need_crc != 0 && length > 0)
    {
       uLong crc = png_ptr->crc; /* Should never issue a warning */
 
       do
       {
          uInt safe_length = (uInt)length;
+#ifndef __COVERITY__
          if (safe_length == 0)
             safe_length = (uInt)-1; /* evil, but safe */
+#endif
 
          crc = crc32(crc, ptr, safe_length);
 
          /* The following should never issue compiler warnings; if they do the
           * target system has characteristics that will probably violate other

@@ -299,21 +306,21 @@
     */
    png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
 
 #  ifdef PNG_SETJMP_SUPPORTED
       if (!setjmp(create_jmp_buf))
+#  endif
       {
+#  ifdef PNG_SETJMP_SUPPORTED
          /* Temporarily fake out the longjmp information until we have
           * successfully completed this function.  This only works if we have
           * setjmp() support compiled in, but it is safe - this stuff should
           * never happen.
           */
          create_struct.jmp_buf_ptr = &create_jmp_buf;
          create_struct.jmp_buf_size = 0; /*stack allocation*/
          create_struct.longjmp_fn = longjmp;
-#  else
-      {
 #  endif
          /* Call the general version checker (shared with read and write code):
           */
          if (png_user_version_check(&create_struct, user_png_ver) != 0)
          {

@@ -437,10 +444,12 @@
       *ptr_ptr = NULL;
       /* The following line is why this API should not be used: */
       free(info_ptr);
       info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
          (sizeof *info_ptr)));
+      if (info_ptr == NULL)
+         return;
       *ptr_ptr = info_ptr;
    }
 
    /* Set everything to 0 */
    memset(info_ptr, 0, (sizeof *info_ptr));

@@ -502,13 +511,14 @@
 
 #ifdef PNG_tRNS_SUPPORTED
    /* Free any tRNS entry */
    if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
    {
+      info_ptr->valid &= ~PNG_INFO_tRNS;
       png_free(png_ptr, info_ptr->trans_alpha);
       info_ptr->trans_alpha = NULL;
-      info_ptr->valid &= ~PNG_INFO_tRNS;
+      info_ptr->num_trans = 0;
    }
 #endif
 
 #ifdef PNG_sCAL_SUPPORTED
    /* Free any sCAL entry */

@@ -570,12 +580,10 @@
          info_ptr->splt_palettes[num].entries = NULL;
       }
 
       else
       {
-         if (info_ptr->splt_palettes_num != 0)
-         {
             int i;
 
             for (i = 0; i < info_ptr->splt_palettes_num; i++)
             {
                png_free(png_ptr, info_ptr->splt_palettes[i].name);

@@ -583,11 +591,10 @@
             }
 
             png_free(png_ptr, info_ptr->splt_palettes);
             info_ptr->splt_palettes = NULL;
             info_ptr->splt_palettes_num = 0;
-         }
          info_ptr->valid &= ~PNG_INFO_sPLT;
       }
    }
 #endif
 

@@ -603,21 +610,18 @@
 
       else
       {
          int i;
 
-         if (info_ptr->unknown_chunks_num != 0)
-         {
             for (i = 0; i < info_ptr->unknown_chunks_num; i++)
                png_free(png_ptr, info_ptr->unknown_chunks[i].data);
 
             png_free(png_ptr, info_ptr->unknown_chunks);
             info_ptr->unknown_chunks = NULL;
             info_ptr->unknown_chunks_num = 0;
          }
       }
-   }
 #endif
 
 #ifdef PNG_hIST_SUPPORTED
    /* Free any hIST entry */
    if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)

@@ -692,26 +696,27 @@
 
    png_ptr->io_ptr = (png_voidp)fp;
 }
 #  endif
 
-#ifdef PNG_SAVE_INT_32_SUPPORTED
-/* The png_save_int_32 function assumes integers are stored in two's
- * complement format.  If this isn't the case, then this routine needs to
- * be modified to write data in two's complement format.  Note that,
- * the following works correctly even if png_int_32 has more than 32 bits
- * (compare the more complex code required on read for sign extension.)
+#  ifdef PNG_SAVE_INT_32_SUPPORTED
+/* PNG signed integers are saved in 32-bit 2's complement format.  ANSI C-90
+ * defines a cast of a signed integer to an unsigned integer either to preserve
+ * the value, if it is positive, or to calculate:
+ *
+ *     (UNSIGNED_MAX+1) + integer
+ *
+ * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the
+ * negative integral value is added the result will be an unsigned value
+ * correspnding to the 2's complement representation.
  */
 void PNGAPI
 png_save_int_32(png_bytep buf, png_int_32 i)
 {
-   buf[0] = (png_byte)((i >> 24) & 0xff);
-   buf[1] = (png_byte)((i >> 16) & 0xff);
-   buf[2] = (png_byte)((i >> 8) & 0xff);
-   buf[3] = (png_byte)(i & 0xff);
+   png_save_uint_32(buf, i);
 }
-#endif
+#  endif
 
 #  ifdef PNG_TIME_RFC1123_SUPPORTED
 /* Convert the supplied time into an RFC 1123 string suitable for use in
  * a "Creation Time" or other text-based time string.
  */

@@ -751,10 +756,11 @@
       APPEND(':');
       APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
       APPEND(':');
       APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
       APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
+      PNG_UNUSED (pos)
 
 #     undef APPEND
 #     undef APPEND_NUMBER
 #     undef APPEND_STRING
    }

@@ -781,11 +787,11 @@
          return png_ptr->time_buffer;
    }
 
    return NULL;
 }
-#     endif
+#    endif /* LIBPNG_VER < 10700 */
 #  endif /* TIME_RFC1123 */
 
 #endif /* READ || WRITE */
 
 png_const_charp PNGAPI

@@ -795,18 +801,18 @@
 #ifdef PNG_STRING_COPYRIGHT
    return PNG_STRING_COPYRIGHT
 #else
 #  ifdef __STDC__
    return PNG_STRING_NEWLINE \
-     "libpng version 1.6.16 - December 22, 2014" PNG_STRING_NEWLINE \
-     "Copyright (c) 1998-2014 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
+      "libpng version 1.6.20 - December 3, 2015" PNG_STRING_NEWLINE \
+      "Copyright (c) 1998-2015 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
      "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
      "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
      PNG_STRING_NEWLINE;
 #  else
-      return "libpng version 1.6.16 - December 22, 2014\
-      Copyright (c) 1998-2014 Glenn Randers-Pehrson\
+   return "libpng version 1.6.20 - December 3, 2015\
+      Copyright (c) 1998-2015 Glenn Randers-Pehrson\
       Copyright (c) 1996-1997 Andreas Dilger\
       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
 #  endif
 #endif
 }

@@ -898,13 +904,13 @@
          break;
    }
 
    for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
    {
-      palette[i].red = (png_byte)v;
-      palette[i].green = (png_byte)v;
-      palette[i].blue = (png_byte)v;
+      palette[i].red = (png_byte)(v & 0xff);
+      palette[i].green = (png_byte)(v & 0xff);
+      palette[i].blue = (png_byte)(v & 0xff);
    }
 }
 #endif
 
 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED

@@ -973,12 +979,10 @@
 {
    /* Version of *.c files used when building libpng */
    return((png_uint_32)PNG_LIBPNG_VER);
 }
 
-
-
 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
 /* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
  * If it doesn't 'ret' is used to set it to something appropriate, even in cases
  * like Z_OK or Z_STREAM_END where the error code is apparently a success code.
  */

@@ -1207,11 +1211,11 @@
 
    info_ptr->colorspace = png_ptr->colorspace;
    png_colorspace_sync_info(png_ptr, info_ptr);
 }
 #endif
-#endif
+#endif /* GAMMA */
 
 #ifdef PNG_COLORSPACE_SUPPORTED
 /* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
  * cHRM, as opposed to using chromaticities.  These internal APIs return
  * non-zero on a parameter error.  The X, Y and Z values are required to be

@@ -1266,20 +1270,21 @@
    png_fixed_point red_inverse, green_inverse, blue_scale;
    png_fixed_point left, right, denominator;
 
    /* Check xy and, implicitly, z.  Note that wide gamut color spaces typically
     * have end points with 0 tristimulus values (these are impossible end
-    * points, but they are used to cover the possible colors.)
+    * points, but they are used to cover the possible colors).  We check
+    * xy->whitey against 5, not 0, to avoid a possible integer overflow.
     */
    if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1;
    if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
    if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
    if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
    if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1;
    if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
    if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
-   if (xy->whitey < 0 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
+   if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
 
    /* The reverse calculation is more difficult because the original tristimulus
     * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
     * derived values were recorded in the cHRM chunk;
     * (red,green,blue,white)x(x,y).  This loses one degree of freedom and

@@ -1733,11 +1738,10 @@
          /* libpng is broken; this should be a warning but if it happens we
           * want error reports so for the moment it is an error.
           */
          colorspace->flags |= PNG_COLORSPACE_INVALID;
          png_error(png_ptr, "internal error checking chromaticities");
-         break;
    }
 
    return 0; /* failed */
 }
 

@@ -1761,11 +1765,10 @@
          break;
 
       default:
          colorspace->flags |= PNG_COLORSPACE_INVALID;
          png_error(png_ptr, "internal error checking chromaticities");
-         break;
    }
 
    return 0; /* failed */
 }
 

@@ -2087,33 +2090,33 @@
     * Profiles of these classes may not be embedded in images.
     */
    temp = png_get_uint_32(profile+12); /* profile/device class */
    switch (temp)
    {
-      case 0x73636E72: /* 'scnr' */
-      case 0x6D6E7472: /* 'mntr' */
+      case 0x73636e72: /* 'scnr' */
+      case 0x6d6e7472: /* 'mntr' */
       case 0x70727472: /* 'prtr' */
       case 0x73706163: /* 'spac' */
          /* All supported */
          break;
 
       case 0x61627374: /* 'abst' */
          /* May not be embedded in an image */
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
             "invalid embedded Abstract ICC profile");
 
-      case 0x6C696E6B: /* 'link' */
+      case 0x6c696e6b: /* 'link' */
          /* DeviceLink profiles cannot be interpreted in a non-device specific
           * fashion, if an app uses the AToB0Tag in the profile the results are
           * undefined unless the result is sent to the intended device,
           * therefore a DeviceLink profile should not be found embedded in a
           * PNG.
           */
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
             "unexpected DeviceLink ICC profile class");
 
-      case 0x6E6D636C: /* 'nmcl' */
+      case 0x6e6d636c: /* 'nmcl' */
          /* A NamedColor profile is also device specific, however it doesn't
           * contain an AToB0 tag that is open to misinterpretation.  Almost
           * certainly it will fail the tests below.
           */
          (void)png_icc_profile_error(png_ptr, NULL, name, temp,

@@ -2135,12 +2138,12 @@
     * either in XYZ or Lab.
     */
    temp = png_get_uint_32(profile+20);
    switch (temp)
    {
-      case 0x58595A20: /* 'XYZ ' */
-      case 0x4C616220: /* 'Lab ' */
+      case 0x58595a20: /* 'XYZ ' */
+      case 0x4c616220: /* 'Lab ' */
          break;
 
       default:
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
             "unexpected ICC PCS encoding");

@@ -2192,11 +2195,12 @@
    }
 
    return 1; /* success, maybe with warnings */
 }
 
-#if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
+#ifdef PNG_sRGB_SUPPORTED
+#if PNG_sRGB_PROFILE_CHECKS >= 0
 /* Information about the known ICC sRGB profiles */
 static const struct
 {
    png_uint_32 adler, crc, length;
    png_uint_32 md5[4];

@@ -2305,12 +2309,12 @@
             length = png_get_uint_32(profile);
             intent = png_get_uint_32(profile+64);
          }
 
          /* Length *and* intent must match */
-         if (length == png_sRGB_checks[i].length &&
-            intent == png_sRGB_checks[i].intent)
+         if (length == (png_uint_32) png_sRGB_checks[i].length &&
+            intent == (png_uint_32) png_sRGB_checks[i].intent)
          {
             /* Now calculate the adler32 if not done already. */
             if (adler == 0)
             {
                adler = adler32(0, NULL, 0);

@@ -2350,12 +2354,12 @@
                    * the profile is perfectly valid, but it would be nice if
                    * people used the up-to-date ones.
                    */
                   else if (png_sRGB_checks[i].have_md5 == 0)
                   {
-                     png_chunk_report(png_ptr, "out-of-date sRGB profile with"
-                        " no signature",
+                     png_chunk_report(png_ptr,
+                        "out-of-date sRGB profile with no signature",
                         PNG_CHUNK_WARNING);
                   }
 
                   return 1+png_sRGB_checks[i].is_broken;
                }

@@ -2364,24 +2368,23 @@
 # if PNG_sRGB_PROFILE_CHECKS > 0
          /* The signature matched, but the profile had been changed in some
           * way.  This probably indicates a data error or uninformed hacking.
           * Fall through to "no match".
           */
-         png_chunk_report(png_ptr, "Not recognizing known sRGB profile that"
-             " has been edited",
+         png_chunk_report(png_ptr,
+             "Not recognizing known sRGB profile that has been edited",
              PNG_CHUNK_WARNING);
          break;
 # endif
          }
       }
    }
 
    return 0; /* no match */
 }
-#endif
+#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
 
-#ifdef PNG_sRGB_SUPPORTED
 void /* PRIVATE */
 png_icc_set_sRGB(png_const_structrp png_ptr,
    png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
 {
    /* Is this profile one of the known ICC sRGB profiles?  If it is, just set

@@ -2391,11 +2394,11 @@
    if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
 #endif
       (void)png_colorspace_set_sRGB(png_ptr, colorspace,
          (int)/*already checked*/png_get_uint_32(profile+64));
 }
-#endif /* READ_sRGB */
+#endif /* sRGB */
 
 int /* PRIVATE */
 png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
    png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
    int color_type)

@@ -2483,11 +2486,11 @@
        */
       else
          png_error(png_ptr, "internal error handling cHRM->XYZ");
    }
 }
-#endif
+#endif /* READ_RGB_TO_GRAY */
 
 #endif /* COLORSPACE */
 
 #ifdef __GNUC__
 /* This exists solely to work round a warning from GNU C. */

@@ -2512,22 +2515,23 @@
    if (width == 0)
    {
       png_warning(png_ptr, "Image width is zero in IHDR");
       error = 1;
    }
-   else if (width > PNG_UINT_31_MAX)
+
+   if (width > PNG_UINT_31_MAX)
    {
       png_warning(png_ptr, "Invalid image width in IHDR");
       error = 1;
    }
 
-   else if (png_gt(width,
-                   (PNG_SIZE_MAX >> 3) /* 8-byte RGBA pixels */
+   if (png_gt(((width + 7) & (~7)),
+       ((PNG_SIZE_MAX
                    - 48                /* big_row_buf hack */
-                   - 1                 /* filter byte */
-                   - 7*8               /* rounding width to multiple of 8 pix */
-                   - 8))               /* extra max_pixel_depth pad */
+           - 1)        /* filter byte */
+           / 8)        /* 8-byte RGBA pixels */
+           - 1))       /* extra max_pixel_depth pad */
    {
       /* The size of the row must be within the limits of this architecture.
        * Because the read code can perform arbitrary transformations the
        * maximum size is checked here.  Because the code in png_read_start_row
        * adds extra space "for safety's sake" in several places a conservative

@@ -2539,45 +2543,42 @@
        * write in a way that avoids compiler warnings.
        */
       png_warning(png_ptr, "Image width is too large for this architecture");
       error = 1;
    }
-   else
-   {
-#     ifdef PNG_SET_USER_LIMITS_SUPPORTED
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
       if (width > png_ptr->user_width_max)
-#     else
+#else
       if (width > PNG_USER_WIDTH_MAX)
-#     endif
+#endif
       {
          png_warning(png_ptr, "Image width exceeds user limit in IHDR");
          error = 1;
       }
-   }
 
    if (height == 0)
    {
       png_warning(png_ptr, "Image height is zero in IHDR");
       error = 1;
    }
-   else if (height > PNG_UINT_31_MAX)
+
+   if (height > PNG_UINT_31_MAX)
    {
       png_warning(png_ptr, "Invalid image height in IHDR");
       error = 1;
    }
-   else
-   {
-#     ifdef PNG_SET_USER_LIMITS_SUPPORTED
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
       if (height > png_ptr->user_height_max)
-#     else
+#else
       if (height > PNG_USER_HEIGHT_MAX)
-#     endif
+#endif
       {
          png_warning(png_ptr, "Image height exceeds user limit in IHDR");
          error = 1;
       }
-   }
 
    /* Check other values */
    if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
        bit_depth != 8 && bit_depth != 16)
    {

@@ -2611,11 +2612,11 @@
    {
       png_warning(png_ptr, "Unknown compression method in IHDR");
       error = 1;
    }
 
-#  ifdef PNG_MNG_FEATURES_SUPPORTED
+#ifdef PNG_MNG_FEATURES_SUPPORTED
    /* Accept filter_method 64 (intrapixel differencing) only if
     * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
     * 2. Libpng did not read a PNG signature (this filter_method is only
     *    used in PNG datastreams that are embedded in MNG datastreams) and
     * 3. The application called png_permit_mng_features with a mask that

@@ -2644,17 +2645,17 @@
          png_warning(png_ptr, "Invalid filter method in IHDR");
          error = 1;
       }
    }
 
-#  else
+#else
    if (filter_type != PNG_FILTER_TYPE_BASE)
    {
       png_warning(png_ptr, "Unknown filter method in IHDR");
       error = 1;
    }
-#  endif
+#endif
 
    if (error == 1)
       png_error(png_ptr, "Invalid IHDR data");
 }
 

@@ -2924,11 +2925,11 @@
           * handle the leading zeros this generates, so no attempt
           * is made to correct that here.
           */
 
          {
-            int czero, clead, cdigits;
+            unsigned int czero, clead, cdigits;
             char exponent[10];
 
             /* Allow up to two leading zeros - this will not lengthen
              * the number compared to using E-n.
              */

@@ -2954,11 +2955,11 @@
                /* Use modf here, not floor and subtract, so that
                 * the separation is done in one step.  At the end
                 * of the loop don't break the number into parts so
                 * that the final digit is rounded.
                 */
-               if (cdigits+czero-clead+1 < (int)precision)
+               if (cdigits+czero+1 < precision+clead)
                   fp = modf(fp, &d);
 
                else
                {
                   d = floor(fp + .5);

@@ -3060,26 +3061,26 @@
                      --exp_b10;
                   }
                   *ascii++ = (char)(48 + (int)d), ++cdigits;
                }
             }
-            while (cdigits+czero-clead < (int)precision && fp > DBL_MIN);
+            while (cdigits+czero < precision+clead && fp > DBL_MIN);
 
             /* The total output count (max) is now 4+precision */
 
             /* Check for an exponent, if we don't need one we are
              * done and just need to terminate the string.  At
              * this point exp_b10==(-1) is effectively if flag - it got
-             * to '-1' because of the decrement after outputing
+             * to '-1' because of the decrement after outputting
              * the decimal point above (the exponent required is
              * *not* -1!)
              */
             if (exp_b10 >= (-1) && exp_b10 <= 2)
             {
                /* The following only happens if we didn't output the
                 * leading zeros above for negative exponent, so this
-                * doest add to the digit requirement.  Note that the
+                * doesn't add to the digit requirement.  Note that the
                 * two zeros here can only be output if the two leading
                 * zeros were *not* output, so this doesn't increase
                 * the output count.
                 */
                while (--exp_b10 >= 0) *ascii++ = 48;

@@ -3128,11 +3129,11 @@
             }
 
             /* Need another size check here for the exponent digits, so
              * this need not be considered above.
              */
-            if ((int)size > cdigits)
+            if (size > cdigits)
             {
                while (cdigits > 0) *ascii++ = exponent[--cdigits];
 
                *ascii = 0;
 

@@ -3176,11 +3177,11 @@
    {
       png_uint_32 num;
 
       /* Avoid overflow here on the minimum integer. */
       if (fp < 0)
-         *ascii++ = 45, --size, num = -fp;
+         *ascii++ = 45, num = -fp;
       else
          num = fp;
 
       if (num <= 0x80000000) /* else overflowed */
       {

@@ -3232,11 +3233,11 @@
 
    /* Here on buffer too small. */
    png_error(png_ptr, "ASCII conversion buffer too small");
 }
 #   endif /* FIXED_POINT */
-#endif /* READ_SCAL */
+#endif /* SCAL */
 
 #if defined(PNG_FLOATING_POINT_SUPPORTED) && \
    !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
    (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
    defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \

@@ -3431,46 +3432,49 @@
        gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
 }
 #endif
 
 #ifdef PNG_READ_GAMMA_SUPPORTED
-#if defined(PNG_16BIT_SUPPORTED) || !defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
+#ifdef PNG_16BIT_SUPPORTED
 /* A local convenience routine. */
 static png_fixed_point
 png_product2(png_fixed_point a, png_fixed_point b)
 {
    /* The required result is 1/a * 1/b; the following preserves accuracy. */
-#    ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    double r = a * 1E-5;
    r *= b;
    r = floor(r+.5);
 
    if (r <= 2147483647. && r >= -2147483648.)
       return (png_fixed_point)r;
-#    else
+#else
    png_fixed_point res;
 
    if (png_muldiv(&res, a, b, 100000) != 0)
       return res;
-#    endif
+#endif
 
    return 0; /* overflow */
 }
-#endif /* 16BIT || !FLOATING_ARITHMETIC */
+#endif /* 16BIT */
 
 /* The inverse of the above. */
 png_fixed_point
 png_reciprocal2(png_fixed_point a, png_fixed_point b)
 {
    /* The required result is 1/a * 1/b; the following preserves accuracy. */
 #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+   if (a != 0 && b != 0)
+   {
    double r = 1E15/a;
    r /= b;
    r = floor(r+.5);
 
    if (r <= 2147483647. && r >= -2147483648.)
       return (png_fixed_point)r;
+   }
 #else
    /* This may overflow because the range of png_fixed_point isn't symmetric,
     * but this API is only used for the product of file and screen gamma so it
     * doesn't matter that the smallest number it can produce is 1/21474, not
     * 1/100000

@@ -3704,11 +3708,11 @@
 png_exp(png_fixed_point x)
 {
    if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
    {
       /* Obtain a 4-bit approximation */
-      png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf];
+      png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f];
 
       /* Incorporate the low 12 bits - these decrease the returned value by
        * multiplying by a number less than 1 if the bit is set.  The multiplier
        * is determined by the above table and the shift. Notice that the values
        * converge on 45426 and this is used to allow linear interpolation of the

@@ -3757,11 +3761,11 @@
    /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the
     * second, rounding, step can't overflow because of the first, subtraction,
     * step.
     */
    x -= x >> 8;
-   return (png_byte)((x + 0x7fffffU) >> 24);
+   return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff);
 }
 
 #ifdef PNG_16BIT_SUPPORTED
 static png_uint_16
 png_exp16bit(png_fixed_point lg2)

@@ -3818,11 +3822,11 @@
          /* Overflow. */
          value = 0;
 #     endif
    }
 
-   return (png_byte)value;
+   return (png_byte)(value & 0xff);
 }
 
 #ifdef PNG_16BIT_SUPPORTED
 png_uint_16
 png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)

@@ -4040,11 +4044,11 @@
       for (i=0; i<256; i++)
          table[i] = png_gamma_8bit_correct(i, gamma_val);
 
    else
       for (i=0; i<256; ++i)
-         table[i] = (png_byte)i;
+         table[i] = (png_byte)(i & 0xff);
 }
 
 /* Used from png_read_destroy and below to release the memory used by the gamma
  * tables.
  */

@@ -4180,11 +4184,12 @@
       *
       *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
       *
       */
      if (sig_bit > 0 && sig_bit < 16U)
-        shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */
+        /* shift == insignificant bits */
+        shift = (png_byte)((16U - sig_bit) & 0xff);
 
      else
         shift = 0; /* keep all 16 bits */
 
      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)

@@ -4249,11 +4254,11 @@
    {
       int mask = 3 << option;
       int setting = (2 + (onoff != 0)) << option;
       int current = png_ptr->options;
 
-      png_ptr->options = (png_byte)((current & ~mask) | setting);
+      png_ptr->options = (png_byte)(((current & ~mask) | setting) & 0xff);
 
       return (current & mask) >> option;
    }
 
    return PNG_OPTION_INVALID;

@@ -4265,11 +4270,11 @@
    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
 /* sRGB conversion tables; these are machine generated with the code in
  * contrib/tools/makesRGB.c.  The actual sRGB transfer curve defined in the
  * specification (see the article at http://en.wikipedia.org/wiki/SRGB)
  * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
- * The sRGB to linear table is exact (to the nearest 16 bit linear fraction).
+ * The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
  * The inverse (linear to sRGB) table has accuracies as follows:
  *
  * For all possible (255*65535+1) input values:
  *
  *    error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact
< prev index next >