[devel] Addressed various issues identified by GCC, mostly signed/unsigned

and shortening problems on assignment but also a few difficult to optimize
(for GCC) loops (John Bowler).
diff --git a/ANNOUNCE b/ANNOUNCE
index e0cf2f7..1a78be9 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -354,7 +354,10 @@
     Also added scripts/chkfmt to validate the format of all the files that can
     reasonably be validated (it is suggested to run "make distclean" before
     checking, because some machine generated files have long lines.)
-    Reformatted the CHANGES file to be more consistent throughout.
+  Reformatted the CHANGES file to be more consistent throughout.
+  Made changes to address various issues identified by GCC, mostly
+    signed/unsigned and shortening problems on assignment but also a few
+    difficult to optimize (for GCC) loops.
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
 (subscription required; visit
diff --git a/CHANGES b/CHANGES
index e1cf546..4d03cbc 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2990,7 +2990,10 @@
     Also added scripts/chkfmt to validate the format of all the files that can
     reasonably be validated (it is suggested to run "make distclean" before
     checking, because some machine generated files have long lines.)
-    Reformatted the CHANGES file to be more consistent throughout.
+  Reformatted the CHANGES file to be more consistent throughout.
+  Made changes to address various issues identified by GCC, mostly
+    signed/unsigned and shortening problems on assignment but also a few
+    difficult to optimize (for GCC) loops.
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/png.c b/png.c
index e51722b..f6623d0 100644
--- a/png.c
+++ b/png.c
@@ -396,7 +396,7 @@
 
          if (info_ptr->unknown_chunks_num)
          {
-            for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
+            for (i = 0; i < info_ptr->unknown_chunks_num; i++)
                png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
 
             png_free(png_ptr, info_ptr->unknown_chunks);
@@ -1344,7 +1344,7 @@
 
             while (exp > 0)
             {
-               exponent[cdigits++] = 48 + exp % 10;
+               exponent[cdigits++] = (char)(48 + exp % 10);
                exp /= 10;
             }
 
@@ -1580,7 +1580,7 @@
                result = -result;
 
             /* Check for overflow. */
-            if (negative && result <= 0 || !negative && result >= 0)
+            if ((negative && result <= 0) || (!negative && result >= 0))
             {
                *res = result;
                return 1;
@@ -1792,7 +1792,7 @@
 #endif
 };
 
-static png_uint_32
+static png_int_32
 png_log8bit(unsigned int x)
 {
    unsigned int log = 0;
@@ -1814,7 +1814,8 @@
    if ((x & 0x80) == 0)
       log += 1, x <<= 1;
 
-   return (log << 16) + ((png_8bit_l2[x-128]+32768)>>16);
+   /* result is at most 19 bits, so this cast is safe: */
+   return (png_int_32)((log << 16) + ((png_8bit_l2[x-128]+32768)>>16));
 }
 
 /* The above gives exact (to 16 binary places) log2 values for 8 bit images,
@@ -1847,7 +1848,7 @@
  * Zero  (257):      0
  * End   (258):  23499
  */
-static png_uint_32
+static png_int_32
 png_log16bit(png_uint_32 x)
 {
    unsigned int log = 0;
@@ -1894,7 +1895,8 @@
    else
       log -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
 
-   return (log + 2048) >> 12;
+   /* Safe, because the result can't have more than 20 bits: */
+   return (png_int_32)((log + 2048) >> 12);
 }
 
 /* The 'exp()' case must invert the above, taking a 20 bit fixed point
@@ -1941,9 +1943,9 @@
 #endif
 
 static png_uint_32
-png_exp(png_uint_32 x)
+png_exp(png_fixed_point x)
 {
-   if (x <= 0xfffff) /* Else zero */
+   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];
@@ -1980,11 +1982,16 @@
       return e;
    }
 
+   /* Check for overflow */
+   if (x <= 0)
+      return png_32bit_exp[0];
+
+   /* Else underflow */
    return 0;
 }
 
 static png_byte
-png_exp8bit(png_uint_32 log)
+png_exp8bit(png_fixed_point log)
 {
    /* Get a 32 bit value: */
    png_uint_32 x = png_exp(log);
@@ -1994,18 +2001,18 @@
     * step.
     */
    x -= x >> 8;
-   return (x + 0x7fffffU) >> 24;
+   return (png_byte)((x + 0x7fffffU) >> 24);
 }
 
 static png_uint_16
-png_exp16bit(png_uint_32 log)
+png_exp16bit(png_fixed_point log)
 {
    /* Get a 32 bit value: */
    png_uint_32 x = png_exp(log);
 
    /* Convert the 32 bit value to 0..65535 by multiplying by 65536-1: */
    x -= x >> 16;
-   return (x + 32767U) >> 16;
+   return (png_uint_16)((x + 32767U) >> 16);
 }
 #endif /* FLOATING_ARITHMETIC */
 
@@ -2018,7 +2025,7 @@
          double r = floor(255*pow(value/255.,gamma*.00001)+.5);
          return (png_byte)r;
 #     else
-         png_uint_32 log = png_log8bit(value);
+         png_int_32 log = png_log8bit(value);
          png_fixed_point res;
 
          if (png_muldiv(&res, gamma, log, PNG_FP_1))
@@ -2041,7 +2048,7 @@
          double r = floor(65535*pow(value/65535.,gamma*.00001)+.5);
          return (png_uint_16)r;
 #     else
-         png_uint_32 log = png_log16bit(value);
+         png_int_32 log = png_log16bit(value);
          png_fixed_point res;
 
          if (png_muldiv(&res, gamma, log, PNG_FP_1))
@@ -2200,12 +2207,12 @@
       png_uint_16 out = (png_uint_16)(i * 257U); /* 16 bit output value */
 
       /* Find the boundary value in 16 bits: */
-      png_uint_16 bound = png_gamma_16bit_correct(out+128U, gamma);
+      png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma);
 
       /* Adjust (round) to (16-shift) bits: */
-      bound = (png_uint_16)(((png_uint_32)bound * max + 32768U)/65535U);
+      bound = (bound * max + 32768U)/65535U + 1U;
 
-      while (last <= bound)
+      while (last < bound)
       {
          table[last & (0xffU >> shift)][last >> (8U - shift)] = out;
          last++;
@@ -2244,7 +2251,7 @@
  * we don't need to allocate > 64K chunks for a full 16-bit table.
  */
 void /* PRIVATE */
-png_build_gamma_table(png_structp png_ptr, png_byte bit_depth)
+png_build_gamma_table(png_structp png_ptr, int bit_depth)
 {
   png_debug(1, "in png_build_gamma_table");
 
@@ -2302,8 +2309,8 @@
       *   <all high 8 bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
       *
       */
-     if (sig_bit > 0)
-        shift = 16U - sig_bit; /* shift == insignificant bits */
+     if (sig_bit > 0 && sig_bit < 16U)
+        shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */
 
      else
         shift = 0; /* keep all 16 bits */
diff --git a/png.h b/png.h
index 017dbec..c282821 100644
--- a/png.h
+++ b/png.h
@@ -1878,7 +1878,7 @@
     174);
 PNG_EXPORT(void, png_set_unknown_chunk_location, (png_structp png_ptr,
     png_infop info_ptr, int chunk, int location),,175);
-PNG_EXPORT(png_uint_32,png_get_unknown_chunks,(png_structp png_ptr,
+PNG_EXPORT(int,png_get_unknown_chunks,(png_structp png_ptr,
     png_infop info_ptr, png_unknown_chunkpp entries),,176);
 #endif
 
diff --git a/pnginfo.h b/pnginfo.h
index 81e2fca..c43454c 100644
--- a/pnginfo.h
+++ b/pnginfo.h
@@ -229,7 +229,7 @@
  defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
    /* Storage for unknown chunks that the library doesn't recognize. */
    png_unknown_chunkp unknown_chunks;
-   png_size_t unknown_chunks_num;
+   int unknown_chunks_num;
 #endif
 
 #ifdef PNG_iCCP_SUPPORTED
diff --git a/pngpread.c b/pngpread.c
index 7b85bf0..f22e225 100644
--- a/pngpread.c
+++ b/pngpread.c
@@ -1120,6 +1120,7 @@
 
             break;
          }
+
          case 6:
          {
             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
diff --git a/pngpriv.h b/pngpriv.h
index a3b0dc3..c46375c 100644
--- a/pngpriv.h
+++ b/pngpriv.h
@@ -1188,7 +1188,7 @@
 PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value,
     png_fixed_point gamma));
 PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr,
-    png_byte bit_depth));
+    int bit_depth));
 #endif
 
 /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
diff --git a/pngrtran.c b/pngrtran.c
index 00724e9..b8d278b 100644
--- a/pngrtran.c
+++ b/pngrtran.c
@@ -1273,7 +1273,8 @@
 #ifdef PNG_READ_BACKGROUND_SUPPORTED
    if (png_ptr->transformations & PNG_BACKGROUND)
    {
-      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+      info_ptr->color_type = (png_byte)(info_ptr->color_type &
+          ~PNG_COLOR_MASK_ALPHA);
       info_ptr->num_trans = 0;
       info_ptr->background = png_ptr->background;
    }
@@ -2609,8 +2610,9 @@
             }
          }
       }
-   row_info->channels -= (png_byte)2;
-      row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
+      row_info->channels -= 2;
+      row_info->color_type = (png_byte)(row_info->color_type &
+          ~PNG_COLOR_MASK_COLOR);
       row_info->pixel_depth = (png_byte)(row_info->channels *
           row_info->bit_depth);
       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
@@ -3408,7 +3410,8 @@
 
       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
       {
-         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+         row_info->color_type = (png_byte)(row_info->color_type &
+             ~PNG_COLOR_MASK_ALPHA);
          row_info->channels--;
          row_info->pixel_depth = (png_byte)(row_info->channels *
              row_info->bit_depth);
@@ -3715,9 +3718,8 @@
          row_info->rowbytes = row_width;
       }
 
-      switch (row_info->bit_depth)
+      else if (row_info->bit_depth == 8)
       {
-         case 8:
          {
             if (trans_alpha != NULL)
             {
@@ -3763,7 +3765,6 @@
                row_info->color_type = 2;
                row_info->channels = 3;
             }
-            break;
          }
       }
    }
@@ -3897,8 +3898,8 @@
 
             else if (row_info->bit_depth == 16)
             {
-               png_byte gray_high = (gray >> 8) & 0xff;
-               png_byte gray_low = gray & 0xff;
+               png_byte gray_high = (png_byte)((gray >> 8) & 0xff);
+               png_byte gray_low = (png_byte)(gray & 0xff);
                sp = row + row_info->rowbytes - 1;
                dp = row + (row_info->rowbytes << 1) - 1;
                for (i = 0; i < row_width; i++)
@@ -3931,9 +3932,9 @@
       {
          if (row_info->bit_depth == 8)
          {
-            png_byte red = trans_value->red & 0xff;
-            png_byte green = trans_value->green & 0xff;
-            png_byte blue = trans_value->blue & 0xff;
+            png_byte red = (png_byte)(trans_value->red & 0xff);
+            png_byte green = (png_byte)(trans_value->green & 0xff);
+            png_byte blue = (png_byte)(trans_value->blue & 0xff);
             sp = row + (png_size_t)row_info->rowbytes - 1;
             dp = row + (png_size_t)(row_width << 2) - 1;
             for (i = 0; i < row_width; i++)
@@ -3951,12 +3952,12 @@
          }
          else if (row_info->bit_depth == 16)
          {
-            png_byte red_high = (trans_value->red >> 8) & 0xff;
-            png_byte green_high = (trans_value->green >> 8) & 0xff;
-            png_byte blue_high = (trans_value->blue >> 8) & 0xff;
-            png_byte red_low = trans_value->red & 0xff;
-            png_byte green_low = trans_value->green & 0xff;
-            png_byte blue_low = trans_value->blue & 0xff;
+            png_byte red_high = (png_byte)((trans_value->red >> 8) & 0xff);
+            png_byte green_high = (png_byte)((trans_value->green >> 8) & 0xff);
+            png_byte blue_high = (png_byte)((trans_value->blue >> 8) & 0xff);
+            png_byte red_low = (png_byte)(trans_value->red & 0xff);
+            png_byte green_low = (png_byte)(trans_value->green & 0xff);
+            png_byte blue_low = (png_byte)(trans_value->blue & 0xff);
             sp = row + row_info->rowbytes - 1;
             dp = row + (png_size_t)(row_width << 3) - 1;
             for (i = 0; i < row_width; i++)
diff --git a/pngrutil.c b/pngrutil.c
index 43f25bf..5d8ba69 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -262,14 +262,15 @@
        */
       if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
       {
+         png_size_t space = avail; /* > 0, see above */
          if (output != 0 && output_size > count)
          {
-            int copy = output_size - count;
-            if (avail < copy)
-               copy = avail;
+            png_size_t copy = output_size - count;
+            if (space < copy)
+               copy = space;
             png_memcpy(output + count, png_ptr->zbuf, copy);
          }
-         count += avail;
+         count += space;
       }
 
       if (ret == Z_OK)
@@ -497,6 +498,7 @@
    /* Find number of channels */
    switch (png_ptr->color_type)
    {
+      default: /* invalid, png_set_IHDR calls png_error */
       case PNG_COLOR_TYPE_GRAY:
       case PNG_COLOR_TYPE_PALETTE:
          png_ptr->channels = 1;
diff --git a/pngset.c b/pngset.c
index b454426..17b020f 100644
--- a/pngset.c
+++ b/pngset.c
@@ -948,8 +948,8 @@
       return;
 
    np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
-       (png_size_t)((info_ptr->unknown_chunks_num + num_unknowns) *
-       png_sizeof(png_unknown_chunk)));
+       (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) *
+       png_sizeof(png_unknown_chunk));
 
    if (np == NULL)
    {
@@ -959,7 +959,8 @@
    }
 
    png_memcpy(np, info_ptr->unknown_chunks,
-       info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
+       (png_size_t)info_ptr->unknown_chunks_num *
+       png_sizeof(png_unknown_chunk));
 
    png_free(png_ptr, info_ptr->unknown_chunks);
    info_ptr->unknown_chunks = NULL;
@@ -999,12 +1000,13 @@
    info_ptr->unknown_chunks_num += num_unknowns;
    info_ptr->free_me |= PNG_FREE_UNKN;
 }
+
 void PNGAPI
 png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
     int chunk, int location)
 {
    if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
-       (int)info_ptr->unknown_chunks_num)
+       info_ptr->unknown_chunks_num)
       info_ptr->unknown_chunks[chunk].location = (png_byte)location;
 }
 #endif
diff --git a/pngtest.c b/pngtest.c
index 1299c26..a46d94b 100644
--- a/pngtest.c
+++ b/pngtest.c
@@ -1145,19 +1145,19 @@
 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
    {
       png_unknown_chunkp unknowns;
-      int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr,
+      int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr,
          &unknowns);
 
       if (num_unknowns)
       {
-         png_size_t i;
+         int i;
          png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
            num_unknowns);
          /* Copy the locations from the read_info_ptr.  The automatically
           * generated locations in write_info_ptr are wrong because we
           * haven't written anything yet.
           */
-         for (i = 0; i < (png_size_t)num_unknowns; i++)
+         for (i = 0; i < num_unknowns; i++)
            png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
              unknowns[i].location);
       }
@@ -1318,21 +1318,19 @@
 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
    {
       png_unknown_chunkp unknowns;
-      int num_unknowns;
-
-      num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr,
+      int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr,
          &unknowns);
 
       if (num_unknowns)
       {
-         png_size_t i;
+         int i;
          png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
            num_unknowns);
          /* Copy the locations from the read_info_ptr.  The automatically
           * generated locations in write_end_info_ptr are wrong because we
           * haven't written the end_info yet.
           */
-         for (i = 0; i < (png_size_t)num_unknowns; i++)
+         for (i = 0; i < num_unknowns; i++)
            png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
              unknowns[i].location);
       }
diff --git a/pngtrans.c b/pngtrans.c
index fff5032..1c47061 100644
--- a/pngtrans.c
+++ b/pngtrans.c
@@ -581,7 +581,8 @@
       }
 
       if (flags & PNG_FLAG_STRIP_ALPHA)
-        row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+        row_info->color_type = (png_byte)(row_info->color_type &
+            ~PNG_COLOR_MASK_ALPHA);
    }
 }
 #endif
diff --git a/pngvalid.c b/pngvalid.c
index c17164c..ce7b663 100644
--- a/pngvalid.c
+++ b/pngvalid.c
@@ -82,40 +82,35 @@
       *colour_type = 0, *bit_depth = 1;
       return 1;
    }
-   else switch (*colour_type)
+
+   *bit_depth = (png_byte)(*bit_depth << 1);
+
+   /* Palette images are restricted to 8 bit depth */
+   if (*bit_depth <= 8 || (*colour_type != 3 && *bit_depth <= 16))
+      return 1;
+
+   /* Move to the next color type, or return 0 at the end. */
+   switch (*colour_type)
    {
    case 0:
-      *bit_depth <<= 1;
-      if (*bit_depth <= 16) return 1;
       *colour_type = 2;
       *bit_depth = 8;
       return 1;
    case 2:
-      *bit_depth <<= 1;
-      if (*bit_depth <= 16) return 1;
       *colour_type = 3;
       *bit_depth = 1;
       return 1;
    case 3:
-      *bit_depth <<= 1;
-      if (*bit_depth <= 8) return 1;
       *colour_type = 4;
       *bit_depth = 8;
       return 1;
    case 4:
-      *bit_depth <<= 1;
-      if (*bit_depth <= 16) return 1;
       *colour_type = 6;
       *bit_depth = 8;
       return 1;
-   case 6:
-      *bit_depth <<= 1;
-      if (*bit_depth <= 16) return 1;
-      break;
+   default:
+      return 0;
    }
-
-   /* Here at the end. */
-   return 0;
 }
 
 static unsigned int
@@ -171,10 +166,10 @@
 typedef struct png_store
 {
    jmp_buf            jmpbuf;
-   int                verbose;
+   unsigned int       verbose :1;
+   unsigned int       treat_warnings_as_errors :1;
    int                nerrors;
    int                nwarnings;
-   int                treat_warnings_as_errors;
    char               test[64]; /* Name of test */
    char               error[128];
    /* Read fields */
@@ -690,9 +685,9 @@
     * to add the chunk before the relevant chunk.
     */
    png_uint_32              add;
-   int                      modified :1;     /* Chunk was modified */
-   int                      added    :1;     /* Chunk was added */
-   int                      removed  :1;     /* Chunk was removed */
+   unsigned int             modified :1;     /* Chunk was modified */
+   unsigned int             added    :1;     /* Chunk was added */
+   unsigned int             removed  :1;     /* Chunk was removed */
 } png_modification;
 
 static void modification_reset(png_modification *pmm)
@@ -1142,11 +1137,19 @@
          ++i;
       }
       return;
+
+   default:
+      break;
    }
 
    png_error(pp, "internal error");
 }
 
+/* This is just to do the right cast - could be changed to a function to check
+ * 'bd' but there isn't much point.
+ */
+#define DEPTH(bd) ((png_byte)(1U << (bd)))
+
 static void
 make_standard(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
    int PNG_CONST bdloIn, int PNG_CONST bdhi)
@@ -1181,7 +1184,7 @@
          continue;
       }
 
-      bit_depth = 1U << bdlo;
+      bit_depth = DEPTH(bdlo);
       h = standard_height(pp, colour_type, bit_depth),
       png_set_IHDR(pp, pi, standard_width(pp, colour_type, bit_depth), h,
          bit_depth, colour_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
@@ -1239,7 +1242,7 @@
 
    for (; bdlo <= bdhi; ++bdlo)
    {
-      png_byte bit_depth = 1U << bdlo;
+      png_byte bit_depth = DEPTH(bdlo);
       png_uint_32 h, y;
       size_t cb;
       png_structp pp;
@@ -1761,6 +1764,8 @@
    /* Log the summary values too. */
    if (colour_type == 0 || colour_type == 4) switch (bit_depth)
    {
+   case 1:
+      break;
    case 2:
       if (maxerrout > pm->error_gray_2) pm->error_gray_2 = maxerrout; break;
    case 4:
@@ -1769,6 +1774,8 @@
       if (maxerrout > pm->error_gray_8) pm->error_gray_8 = maxerrout; break;
    case 16:
       if (maxerrout > pm->error_gray_16) pm->error_gray_16 = maxerrout; break;
+   default:
+      png_error(pp, "bad bit depth (internal: 1)");
    }
    else if (colour_type == 2 || colour_type == 6) switch (bit_depth)
    {
@@ -1776,6 +1783,8 @@
       if (maxerrout > pm->error_color_8) pm->error_color_8 = maxerrout; break;
    case 16:
       if (maxerrout > pm->error_color_16) pm->error_color_16 = maxerrout; break;
+   default:
+      png_error(pp, "bad bit depth (internal: 2)");
    }
 }
 
@@ -2029,7 +2038,7 @@
       else if (strcmp(*argv, "-l") == 0)
          pm.log = 1;
       else if (strcmp(*argv, "-q") == 0)
-         pm.this.verbose = pm.log = summary = 0;
+         summary = pm.this.verbose = pm.log = 0;
       else if (strcmp(*argv, "-g") == 0)
          pm.ngammas = (sizeof gammas)/(sizeof gammas[0]);
       else if (strcmp(*argv, "-w") == 0)
@@ -2073,7 +2082,7 @@
    /* Perform the standard and gamma tests. */
    if (!speed)
       perform_standard_test(&pm);
-   perform_gamma_test(&pm, speed, summary && !speed);
+   perform_gamma_test(&pm, speed != 0, summary && !speed);
    if (summary && !speed)
       printf("Results using %s point arithmetic %s\n",
 #if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500
diff --git a/pngwrite.c b/pngwrite.c
index 34131db..ea34a7c 100644
--- a/pngwrite.c
+++ b/pngwrite.c
@@ -712,6 +712,7 @@
                return;
             }
             break;
+
          case 1:
             if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
             {
@@ -719,6 +720,7 @@
                return;
             }
             break;
+
          case 2:
             if ((png_ptr->row_number & 0x07) != 4)
             {
@@ -726,6 +728,7 @@
                return;
             }
             break;
+
          case 3:
             if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
             {
@@ -733,6 +736,7 @@
                return;
             }
             break;
+
          case 4:
             if ((png_ptr->row_number & 0x03) != 2)
             {
@@ -740,6 +744,7 @@
                return;
             }
             break;
+
          case 5:
             if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
             {
@@ -747,6 +752,7 @@
                return;
             }
             break;
+
          case 6:
             if (!(png_ptr->row_number & 0x01))
             {
@@ -754,6 +760,9 @@
                return;
             }
             break;
+
+         default: /* error: ignore it */
+            break;
       }
    }
 #endif
@@ -782,10 +791,10 @@
 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
    /* Handle interlacing */
    if (png_ptr->interlaced && png_ptr->pass < 6 &&
-      (png_ptr->transformations & PNG_INTERLACE))
+       (png_ptr->transformations & PNG_INTERLACE))
    {
       png_do_write_interlace(&(png_ptr->row_info),
-         png_ptr->row_buf + 1, png_ptr->pass);
+          png_ptr->row_buf + 1, png_ptr->pass);
       /* This should always get caught above, but still ... */
       if (!(png_ptr->row_info.width))
       {
@@ -810,7 +819,7 @@
     * 5. The color_type is RGB or RGBA
     */
    if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
-      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
    {
       /* Intrapixel differencing */
       png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
@@ -931,20 +940,20 @@
    {
       if (png_ptr != NULL)
       {
-        png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+         png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
 
 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-        if (png_ptr->num_chunk_list)
-        {
-           png_free(png_ptr, png_ptr->chunk_list);
-           png_ptr->num_chunk_list = 0;
-        }
+         if (png_ptr->num_chunk_list)
+         {
+            png_free(png_ptr, png_ptr->chunk_list);
+            png_ptr->num_chunk_list = 0;
+         }
 #endif
       }
 
 #ifdef PNG_USER_MEM_SUPPORTED
       png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
-         (png_voidp)mem_ptr);
+          (png_voidp)mem_ptr);
 #else
       png_destroy_struct((png_voidp)info_ptr);
 #endif
@@ -1104,7 +1113,8 @@
             if (png_ptr->prev_row == NULL)
             {
                png_warning(png_ptr, "Can't add Up filter after starting");
-               png_ptr->do_filter &= ~PNG_FILTER_UP;
+               png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
+                   ~PNG_FILTER_UP);
             }
 
             else
@@ -1120,7 +1130,8 @@
             if (png_ptr->prev_row == NULL)
             {
                png_warning(png_ptr, "Can't add Average filter after starting");
-               png_ptr->do_filter &= ~PNG_FILTER_AVG;
+               png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
+                   ~PNG_FILTER_AVG);
             }
 
             else
@@ -1284,8 +1295,8 @@
 #ifdef PNG_FLOATING_POINT_SUPPORTED
 void PNGAPI
 png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
-   int num_weights, png_const_doublep filter_weights,
-   png_const_doublep filter_costs)
+    int num_weights, png_const_doublep filter_weights,
+    png_const_doublep filter_costs)
 {
    png_debug(1, "in png_set_filter_heuristics");
 
@@ -1339,8 +1350,8 @@
 #ifdef PNG_FIXED_POINT_SUPPORTED
 void PNGAPI
 png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method,
-   int num_weights, png_const_fixed_point_p filter_weights,
-   png_const_fixed_point_p filter_costs)
+    int num_weights, png_const_fixed_point_p filter_weights,
+    png_const_fixed_point_p filter_costs)
 {
    png_debug(1, "in png_set_filter_heuristics_fixed");
 
@@ -1382,11 +1393,21 @@
       for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
          if (filter_costs[i] >= PNG_FP_1)
       {
-         png_ptr->inv_filter_costs[i] = (png_uint_16)((PNG_COST_FACTOR*
-            PNG_FP_1+(filter_costs[i]/2)) / filter_costs[i]);
+         png_uint_32 tmp;
 
-         png_ptr->filter_costs[i] = (png_uint_16)
-            ((PNG_COST_FACTOR * filter_costs[i] +PNG_FP_HALF)/PNG_FP_1);
+         /* Use a 32 bit unsigned temporary here because otherwise the
+          * intermediate value will be a 32 bit *signed* integer (ANSI rules)
+          * and this will get the wrong answer on division.
+          */
+         tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2);
+         tmp /= filter_costs[i];
+
+         png_ptr->inv_filter_costs[i] = (png_uint_16)tmp;
+
+         tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF;
+         tmp /= PNG_FP_1;
+
+         png_ptr->filter_costs[i] = (png_uint_16)tmp;
       }
    }
 }
@@ -1444,10 +1465,10 @@
 #ifndef WBITS_8_OK
    /* Avoid libpng bug with 256-byte windows */
    if (window_bits == 8)
-     {
-       png_warning(png_ptr, "Compression window is being reset to 512");
-       window_bits = 9;
-     }
+      {
+        png_warning(png_ptr, "Compression window is being reset to 512");
+        window_bits = 9;
+      }
 
 #endif
    png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
@@ -1497,7 +1518,7 @@
 #ifdef PNG_INFO_IMAGE_SUPPORTED
 void PNGAPI
 png_write_png(png_structp png_ptr, png_infop info_ptr,
-              int transforms, voidp params)
+    int transforms, voidp params)
 {
    if (png_ptr == NULL || info_ptr == NULL)
       return;
diff --git a/pngwutil.c b/pngwutil.c
index 435288e..59141ce 100644
--- a/pngwutil.c
+++ b/pngwutil.c
@@ -740,11 +740,13 @@
                half_z_window_size >>= 1;
             }
             z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
-            if (data[0] != (png_byte)z_cmf)
+            if (data[0] != z_cmf)
             {
+               int tmp;
                data[0] = (png_byte)z_cmf;
-               data[1] &= 0xe0;
-               data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
+               tmp = data[1] & 0xe0;
+               tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
+               data[1] = (png_byte)tmp;
             }
          }
       }
@@ -1868,14 +1870,14 @@
                break;
 
             png_ptr->usr_width = (png_ptr->width +
-               png_pass_inc[png_ptr->pass] - 1 -
-               png_pass_start[png_ptr->pass]) /
-               png_pass_inc[png_ptr->pass];
+                png_pass_inc[png_ptr->pass] - 1 -
+                png_pass_start[png_ptr->pass]) /
+                png_pass_inc[png_ptr->pass];
 
             png_ptr->num_rows = (png_ptr->height +
-               png_pass_yinc[png_ptr->pass] - 1 -
-               png_pass_ystart[png_ptr->pass]) /
-               png_pass_yinc[png_ptr->pass];
+                png_pass_yinc[png_ptr->pass] - 1 -
+                png_pass_ystart[png_ptr->pass]) /
+                png_pass_yinc[png_ptr->pass];
 
             if (png_ptr->transformations & PNG_INTERLACE)
                break;
@@ -1920,6 +1922,7 @@
       {
          if (png_ptr->zstream.msg != NULL)
             png_error(png_ptr, png_ptr->zstream.msg);
+
          else
             png_error(png_ptr, "zlib error");
       }
@@ -1999,6 +2002,7 @@
 
             break;
          }
+
          case 2:
          {
             png_bytep sp;
@@ -2035,6 +2039,7 @@
 
             break;
          }
+
          case 4:
          {
             png_bytep sp;
@@ -2068,6 +2073,7 @@
                *dp = (png_byte)d;
             break;
          }
+
          default:
          {
             png_bytep sp;
@@ -2135,8 +2141,8 @@
 #ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
   if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
   {
-      /* These will never be selected so we need not test them. */
-      filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
+     /* These will never be selected so we need not test them. */
+     filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
   }
 #endif
 
@@ -2275,10 +2281,10 @@
             if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
             {
                lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
-                  PNG_WEIGHT_SHIFT;
+                   PNG_WEIGHT_SHIFT;
 
                lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
-                  PNG_WEIGHT_SHIFT;
+                   PNG_WEIGHT_SHIFT;
             }
          }
 
@@ -2303,6 +2309,7 @@
 
          sum += (v < 128) ? v : 256 - v;
       }
+
       for (lp = row_buf + 1; i < row_bytes;
          i++, rp++, lp++, dp++)
       {