Merge Upstream version 1.6.21 from branch 'upstream' into tizen
[platform/upstream/libpng.git] / pngwrite.c
index f03aeb2..f843796 100644 (file)
@@ -1,8 +1,8 @@
 
 /* pngwrite.c - general routines to write a PNG file
  *
- * Last changed in libpng 1.6.11 [June 5, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.19 [November 12, 2015]
+ * Copyright (c) 1998-2002,2004,2006-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.)
  *
@@ -24,7 +24,7 @@ static void
 write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
    unsigned int where)
 {
-   if (info_ptr->unknown_chunks_num)
+   if (info_ptr->unknown_chunks_num != 0)
    {
       png_const_unknown_chunkp up;
 
@@ -33,7 +33,7 @@ write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
       for (up = info_ptr->unknown_chunks;
            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
            ++up)
-         if (up->location & where)
+         if ((up->location & where) != 0)
       {
          /* If per-chunk unknown chunk handling is enabled use it, otherwise
           * just write the chunks the application has set.
@@ -69,7 +69,7 @@ write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
       }
    }
 }
-#endif /* PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED */
+#endif /* WRITE_UNKNOWN_CHUNKS */
 
 /* Writes all the PNG information.  This is the suggested way to use the
  * library.  If you have a new chunk to add, make a function to write it,
@@ -88,99 +88,100 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
    if (png_ptr == NULL || info_ptr == NULL)
       return;
 
-   if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+   if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0)
    {
-   /* Write PNG signature */
-   png_write_sig(png_ptr);
+      /* Write PNG signature */
+      png_write_sig(png_ptr);
 
 #ifdef PNG_MNG_FEATURES_SUPPORTED
-   if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \
-       (png_ptr->mng_features_permitted))
-   {
-      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
-      png_ptr->mng_features_permitted = 0;
-   }
+      if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \
+          png_ptr->mng_features_permitted != 0)
+      {
+         png_warning(png_ptr,
+             "MNG features are not allowed in a PNG datastream");
+         png_ptr->mng_features_permitted = 0;
+      }
 #endif
 
-   /* Write IHDR information. */
-   png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
-       info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
-       info_ptr->filter_type,
+      /* Write IHDR information. */
+      png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+          info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+          info_ptr->filter_type,
 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
-       info_ptr->interlace_type
+          info_ptr->interlace_type
 #else
-       0
+          0
 #endif
-      );
+         );
 
-   /* The rest of these check to see if the valid field has the appropriate
-    * flag set, and if it does, writes the chunk.
-    *
-    * 1.6.0: COLORSPACE support controls the writing of these chunks too, and
-    * the chunks will be written if the WRITE routine is there and information
-    * is available in the COLORSPACE.  (See png_colorspace_sync_info in png.c
-    * for where the valid flags get set.)
-    *
-    * Under certain circumstances the colorspace can be invalidated without
-    * syncing the info_struct 'valid' flags; this happens if libpng detects and
-    * error and calls png_error while the color space is being set, yet the
-    * application continues writing the PNG.  So check the 'invalid' flag here
-    * too.
-    */
+      /* The rest of these check to see if the valid field has the appropriate
+       * flag set, and if it does, writes the chunk.
+       *
+       * 1.6.0: COLORSPACE support controls the writing of these chunks too, and
+       * the chunks will be written if the WRITE routine is there and
+       * information * is available in the COLORSPACE. (See
+       * png_colorspace_sync_info in png.c for where the valid flags get set.)
+       *
+       * Under certain circumstances the colorspace can be invalidated without
+       * syncing the info_struct 'valid' flags; this happens if libpng detects
+       * an error and calls png_error while the color space is being set, yet
+       * the application continues writing the PNG.  So check the 'invalid'
+       * flag here too.
+       */
 #ifdef PNG_GAMMA_SUPPORTED
 #  ifdef PNG_WRITE_gAMA_SUPPORTED
-      if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
-         (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) &&
-         (info_ptr->valid & PNG_INFO_gAMA))
+      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+          (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 &&
+          (info_ptr->valid & PNG_INFO_gAMA) != 0)
          png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma);
 #  endif
 #endif
 
 #ifdef PNG_COLORSPACE_SUPPORTED
-   /* Write only one of sRGB or an ICC profile.  If a profile was supplied
-    * and it matches one of the known sRGB ones issue a warning.
-    */
+      /* Write only one of sRGB or an ICC profile.  If a profile was supplied
+       * and it matches one of the known sRGB ones issue a warning.
+       */
 #  ifdef PNG_WRITE_iCCP_SUPPORTED
-      if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
-         (info_ptr->valid & PNG_INFO_iCCP))
-      {
-#        ifdef PNG_WRITE_sRGB_SUPPORTED
-            if (info_ptr->valid & PNG_INFO_sRGB)
-               png_app_warning(png_ptr,
-                  "profile matches sRGB but writing iCCP instead");
-#        endif
-
-         png_write_iCCP(png_ptr, info_ptr->iccp_name,
-            info_ptr->iccp_profile);
-      }
+         if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+             (info_ptr->valid & PNG_INFO_iCCP) != 0)
+         {
+#    ifdef PNG_WRITE_sRGB_SUPPORTED
+               if ((info_ptr->valid & PNG_INFO_sRGB) != 0)
+                  png_app_warning(png_ptr,
+                     "profile matches sRGB but writing iCCP instead");
+#     endif
+
+            png_write_iCCP(png_ptr, info_ptr->iccp_name,
+               info_ptr->iccp_profile);
+         }
 #     ifdef PNG_WRITE_sRGB_SUPPORTED
          else
 #     endif
 #  endif
 
 #  ifdef PNG_WRITE_sRGB_SUPPORTED
-      if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
-         (info_ptr->valid & PNG_INFO_sRGB))
-         png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent);
+         if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+             (info_ptr->valid & PNG_INFO_sRGB) != 0)
+            png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent);
 #  endif /* WRITE_sRGB */
 #endif /* COLORSPACE */
 
 #ifdef PNG_WRITE_sBIT_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_sBIT)
-      png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+         if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
+            png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
 #endif
 
 #ifdef PNG_COLORSPACE_SUPPORTED
 #  ifdef PNG_WRITE_cHRM_SUPPORTED
-      if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
-         (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) &&
-         (info_ptr->valid & PNG_INFO_cHRM))
-         png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy);
+         if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+             (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 &&
+             (info_ptr->valid & PNG_INFO_cHRM) != 0)
+            png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy);
 #  endif
 #endif
 
 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
-      write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR);
+         write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR);
 #endif
 
       png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
@@ -201,7 +202,7 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
 
    png_write_info_before_PLTE(png_ptr, info_ptr);
 
-   if (info_ptr->valid & PNG_INFO_PLTE)
+   if ((info_ptr->valid & PNG_INFO_PLTE) != 0)
       png_write_PLTE(png_ptr, info_ptr->palette,
           (png_uint_32)info_ptr->num_palette);
 
@@ -209,15 +210,20 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
       png_error(png_ptr, "Valid palette required for paletted images");
 
 #ifdef PNG_WRITE_tRNS_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_tRNS)
+   if ((info_ptr->valid & PNG_INFO_tRNS) !=0)
    {
 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
       /* Invert the alpha channel (in tRNS) */
-      if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
+      if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 &&
           info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
       {
-         int j;
-         for (j = 0; j<(int)info_ptr->num_trans; j++)
+         int j, jend;
+
+         jend = info_ptr->num_trans;
+         if (jend > PNG_MAX_PALETTE_LENGTH)
+            jend = PNG_MAX_PALETTE_LENGTH;
+
+         for (j = 0; j<jend; ++j)
             info_ptr->trans_alpha[j] =
                (png_byte)(255 - info_ptr->trans_alpha[j]);
       }
@@ -227,42 +233,42 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
    }
 #endif
 #ifdef PNG_WRITE_bKGD_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_bKGD)
+   if ((info_ptr->valid & PNG_INFO_bKGD) != 0)
       png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
 #endif
 
 #ifdef PNG_WRITE_hIST_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_hIST)
+   if ((info_ptr->valid & PNG_INFO_hIST) != 0)
       png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
 #endif
 
 #ifdef PNG_WRITE_oFFs_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_oFFs)
+   if ((info_ptr->valid & PNG_INFO_oFFs) != 0)
       png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
           info_ptr->offset_unit_type);
 #endif
 
 #ifdef PNG_WRITE_pCAL_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_pCAL)
+   if ((info_ptr->valid & PNG_INFO_pCAL) != 0)
       png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
           info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
           info_ptr->pcal_units, info_ptr->pcal_params);
 #endif
 
 #ifdef PNG_WRITE_sCAL_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_sCAL)
+   if ((info_ptr->valid & PNG_INFO_sCAL) != 0)
       png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
           info_ptr->scal_s_width, info_ptr->scal_s_height);
 #endif /* sCAL */
 
 #ifdef PNG_WRITE_pHYs_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_pHYs)
+   if ((info_ptr->valid & PNG_INFO_pHYs) != 0)
       png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
           info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
 #endif /* pHYs */
 
 #ifdef PNG_WRITE_tIME_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_tIME)
+   if ((info_ptr->valid & PNG_INFO_tIME) != 0)
    {
       png_write_tIME(png_ptr, &(info_ptr->mod_time));
       png_ptr->mode |= PNG_WROTE_tIME;
@@ -270,7 +276,7 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
 #endif /* tIME */
 
 #ifdef PNG_WRITE_sPLT_SUPPORTED
-   if (info_ptr->valid & PNG_INFO_sPLT)
+   if ((info_ptr->valid & PNG_INFO_sPLT) != 0)
       for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
          png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
 #endif /* sPLT */
@@ -292,11 +298,14 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
              info_ptr->text[i].lang,
              info_ptr->text[i].lang_key,
              info_ptr->text[i].text);
+         /* Mark this chunk as written */
+         if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+         else
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
 #else
-          png_warning(png_ptr, "Unable to write international text");
+         png_warning(png_ptr, "Unable to write international text");
 #endif
-          /* Mark this chunk as written */
-          info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
       }
 
       /* If we want a compressed text chunk */
@@ -305,13 +314,12 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
 #ifdef PNG_WRITE_zTXt_SUPPORTED
          /* Write compressed chunk */
          png_write_zTXt(png_ptr, info_ptr->text[i].key,
-             info_ptr->text[i].text, 0,
-             info_ptr->text[i].compression);
+             info_ptr->text[i].text, info_ptr->text[i].compression);
+         /* Mark this chunk as written */
+         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
 #else
          png_warning(png_ptr, "Unable to write compressed text");
 #endif
-         /* Mark this chunk as written */
-         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
       }
 
       else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
@@ -349,7 +357,7 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
    if (png_ptr == NULL)
       return;
 
-   if (!(png_ptr->mode & PNG_HAVE_IDAT))
+   if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)
       png_error(png_ptr, "No IDATs written into file");
 
 #ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
@@ -365,8 +373,8 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
 #endif
 #ifdef PNG_WRITE_tIME_SUPPORTED
       /* Check to see if user has supplied a time chunk */
-      if ((info_ptr->valid & PNG_INFO_tIME) &&
-          !(png_ptr->mode & PNG_WROTE_tIME))
+      if ((info_ptr->valid & PNG_INFO_tIME) != 0 &&
+          (png_ptr->mode & PNG_WROTE_tIME) == 0)
          png_write_tIME(png_ptr, &(info_ptr->mod_time));
 
 #endif
@@ -387,11 +395,14 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
                 info_ptr->text[i].lang,
                 info_ptr->text[i].lang_key,
                 info_ptr->text[i].text);
+            /* Mark this chunk as written */
+            if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+               info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+            else
+               info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
 #else
             png_warning(png_ptr, "Unable to write international text");
 #endif
-            /* Mark this chunk as written */
-            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
          }
 
          else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
@@ -399,13 +410,12 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
 #ifdef PNG_WRITE_zTXt_SUPPORTED
             /* Write compressed chunk */
             png_write_zTXt(png_ptr, info_ptr->text[i].key,
-                info_ptr->text[i].text, 0,
-                info_ptr->text[i].compression);
+                info_ptr->text[i].text, info_ptr->text[i].compression);
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
 #else
             png_warning(png_ptr, "Unable to write compressed text");
 #endif
-            /* Mark this chunk as written */
-            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
          }
 
          else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
@@ -414,12 +424,11 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
             /* Write uncompressed chunk */
             png_write_tEXt(png_ptr, info_ptr->text[i].key,
                 info_ptr->text[i].text, 0);
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
 #else
             png_warning(png_ptr, "Unable to write uncompressed text");
 #endif
-
-            /* Mark this chunk as written */
-            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
          }
       }
 #endif
@@ -494,7 +503,7 @@ png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
 {
    png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
        error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif /* USER_MEM */
    if (png_ptr != NULL)
    {
       /* Set the zlib control values to defaults; they can be overridden by the
@@ -518,7 +527,7 @@ png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
       png_ptr->zlib_text_mem_level = 8;
       png_ptr->zlib_text_window_bits = 15;
       png_ptr->zlib_text_method = 8;
-#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
+#endif /* WRITE_COMPRESSED_TEXT */
 
       /* This is a highly dubious configuration option; by default it is off,
        * but it may be appropriate for private builds that are testing
@@ -535,7 +544,7 @@ png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
       /* App warnings are warnings in release (or release candidate) builds but
        * are errors during development.
        */
-#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+#if PNG_RELEASE_BUILD
       png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
 #endif
 
@@ -615,7 +624,7 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_write_intrapixel");
 
-   if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
+   if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
    {
       int bytes_per_pixel;
       png_uint_32 row_width = row_info->width;
@@ -635,8 +644,8 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
 
          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
          {
-            *(rp)     = (png_byte)((*rp       - *(rp + 1)) & 0xff);
-            *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
+            *(rp)     = (png_byte)(*rp       - *(rp + 1));
+            *(rp + 2) = (png_byte)(*(rp + 2) - *(rp + 1));
          }
       }
 
@@ -662,16 +671,16 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
             png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
             png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
             png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
-            *(rp    ) = (png_byte)((red >> 8) & 0xff);
-            *(rp + 1) = (png_byte)(red & 0xff);
-            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
-            *(rp + 5) = (png_byte)(blue & 0xff);
+            *(rp    ) = (png_byte)(red >> 8);
+            *(rp + 1) = (png_byte)red;
+            *(rp + 4) = (png_byte)(blue >> 8);
+            *(rp + 5) = (png_byte)blue;
          }
       }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
+#endif /* WRITE_16BIT */
    }
 }
-#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* MNG_FEATURES */
 
 /* Called by user to write a row of image data */
 void PNGAPI
@@ -690,44 +699,44 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
    if (png_ptr->row_number == 0 && png_ptr->pass == 0)
    {
       /* Make sure we wrote the header info */
-      if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+      if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0)
          png_error(png_ptr,
              "png_write_info was never called before png_write_row");
 
       /* Check for transforms that have been set but were defined out */
 #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
-      if (png_ptr->transformations & PNG_INVERT_MONO)
+      if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
          png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined");
 #endif
 
 #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
-      if (png_ptr->transformations & PNG_FILLER)
+      if ((png_ptr->transformations & PNG_FILLER) != 0)
          png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined");
 #endif
 #if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
     defined(PNG_READ_PACKSWAP_SUPPORTED)
-      if (png_ptr->transformations & PNG_PACKSWAP)
+      if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
          png_warning(png_ptr,
              "PNG_WRITE_PACKSWAP_SUPPORTED is not defined");
 #endif
 
 #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
-      if (png_ptr->transformations & PNG_PACK)
+      if ((png_ptr->transformations & PNG_PACK) != 0)
          png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined");
 #endif
 
 #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
-      if (png_ptr->transformations & PNG_SHIFT)
+      if ((png_ptr->transformations & PNG_SHIFT) != 0)
          png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined");
 #endif
 
 #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
-      if (png_ptr->transformations & PNG_BGR)
+      if ((png_ptr->transformations & PNG_BGR) != 0)
          png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined");
 #endif
 
 #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
-      if (png_ptr->transformations & PNG_SWAP_BYTES)
+      if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
          png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined");
 #endif
 
@@ -736,12 +745,13 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
 
 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
    /* If interlaced and not interested in row, return */
-   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   if (png_ptr->interlaced != 0 &&
+       (png_ptr->transformations & PNG_INTERLACE) != 0)
    {
       switch (png_ptr->pass)
       {
          case 0:
-            if (png_ptr->row_number & 0x07)
+            if ((png_ptr->row_number & 0x07) != 0)
             {
                png_write_finish_row(png_ptr);
                return;
@@ -749,7 +759,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
             break;
 
          case 1:
-            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+            if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5)
             {
                png_write_finish_row(png_ptr);
                return;
@@ -765,7 +775,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
             break;
 
          case 3:
-            if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
+            if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3)
             {
                png_write_finish_row(png_ptr);
                return;
@@ -781,7 +791,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
             break;
 
          case 5:
-            if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
+            if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2)
             {
                png_write_finish_row(png_ptr);
                return;
@@ -789,7 +799,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
             break;
 
          case 6:
-            if (!(png_ptr->row_number & 0x01))
+            if ((png_ptr->row_number & 0x01) == 0)
             {
                png_write_finish_row(png_ptr);
                return;
@@ -823,7 +833,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
 #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) != 0)
    {
       png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass);
       /* This should always get caught above, but still ... */
@@ -837,7 +847,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
 
 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
    /* Handle other transformations */
-   if (png_ptr->transformations)
+   if (png_ptr->transformations != 0)
       png_do_write_transformations(png_ptr, &row_info);
 #endif
 
@@ -845,7 +855,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
     * which is also the output depth.
     */
    if (row_info.pixel_depth != png_ptr->pixel_depth ||
-      row_info.pixel_depth != png_ptr->transformed_pixel_depth)
+       row_info.pixel_depth != png_ptr->transformed_pixel_depth)
       png_error(png_ptr, "internal write transform logic error");
 
 #ifdef PNG_MNG_FEATURES_SUPPORTED
@@ -858,7 +868,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
     * 4. The filter_method is 64 and
     * 5. The color_type is RGB or RGBA
     */
-   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
        (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
    {
       /* Intrapixel differencing */
@@ -911,11 +921,7 @@ png_write_flush(png_structrp png_ptr)
    png_ptr->flush_rows = 0;
    png_flush(png_ptr);
 }
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */
-#endif
+#endif /* WRITE_FLUSH */
 
 /* Free any memory used in png_ptr struct without freeing the struct itself. */
 static void
@@ -924,29 +930,25 @@ png_write_destroy(png_structrp png_ptr)
    png_debug(1, "in png_write_destroy");
 
    /* Free any memory zlib uses */
-   if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
+   if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
       deflateEnd(&png_ptr->zstream);
 
    /* Free our memory.  png_free checks NULL for us. */
    png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
    png_free(png_ptr, png_ptr->row_buf);
+   png_ptr->row_buf = NULL;
 #ifdef PNG_WRITE_FILTER_SUPPORTED
    png_free(png_ptr, png_ptr->prev_row);
-   png_free(png_ptr, png_ptr->sub_row);
-   png_free(png_ptr, png_ptr->up_row);
-   png_free(png_ptr, png_ptr->avg_row);
-   png_free(png_ptr, png_ptr->paeth_row);
-#endif
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-   /* Use this to save a little code space, it doesn't free the filter_costs */
-   png_reset_filter_heuristics(png_ptr);
-   png_free(png_ptr, png_ptr->filter_costs);
-   png_free(png_ptr, png_ptr->inv_filter_costs);
+   png_free(png_ptr, png_ptr->try_row);
+   png_free(png_ptr, png_ptr->tst_row);
+   png_ptr->prev_row = NULL;
+   png_ptr->try_row = NULL;
+   png_ptr->tst_row = NULL;
 #endif
 
 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
    png_free(png_ptr, png_ptr->chunk_list);
+   png_ptr->chunk_list = NULL;
 #endif
 
    /* The error handling and memory handling information is left intact at this
@@ -992,7 +994,7 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
       return;
 
 #ifdef PNG_MNG_FEATURES_SUPPORTED
-   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
        (method == PNG_INTRAPIXEL_DIFFERENCING))
       method = PNG_FILTER_TYPE_BASE;
 
@@ -1006,7 +1008,7 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
          case 6:
          case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
             /* FALL THROUGH */
-#endif /* PNG_WRITE_FILTER_SUPPORTED */
+#endif /* WRITE_FILTER */
          case PNG_FILTER_VALUE_NONE:
             png_ptr->do_filter = PNG_FILTER_NONE; break;
 
@@ -1028,211 +1030,88 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
 #else
          default:
             png_app_error(png_ptr, "Unknown row filter for method 0");
-#endif /* PNG_WRITE_FILTER_SUPPORTED */
+#endif /* WRITE_FILTER */
       }
 
+#ifdef PNG_WRITE_FILTER_SUPPORTED
       /* If we have allocated the row_buf, this means we have already started
        * with the image and we should have allocated all of the filter buffers
        * that have been selected.  If prev_row isn't already allocated, then
        * it is too late to start using the filters that need it, since we
        * will be missing the data in the previous row.  If an application
        * wants to start and stop using particular filters during compression,
-       * it should start out with all of the filters, and then add and
-       * remove them after the start of compression.
+       * it should start out with all of the filters, and then remove them
+       * or add them back after the start of compression.
+       *
+       * NOTE: this is a nasty constraint on the code, because it means that the
+       * prev_row buffer must be maintained even if there are currently no
+       * 'prev_row' requiring filters active.
        */
       if (png_ptr->row_buf != NULL)
       {
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-         if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
-         {
-            png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
-                (png_ptr->rowbytes + 1));
-            png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
-         }
-
-         if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
-         {
-            if (png_ptr->prev_row == NULL)
-            {
-               png_warning(png_ptr, "Can't add Up filter after starting");
-               png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
-                   ~PNG_FILTER_UP);
-            }
-
-            else
-            {
-               png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
-                   (png_ptr->rowbytes + 1));
-               png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
-            }
-         }
+         int num_filters;
+         png_alloc_size_t buf_size;
 
-         if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
-         {
-            if (png_ptr->prev_row == NULL)
-            {
-               png_warning(png_ptr, "Can't add Average filter after starting");
-               png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
-                   ~PNG_FILTER_AVG);
-            }
+         /* Repeat the checks in png_write_start_row; 1 pixel high or wide
+          * images cannot benefit from certain filters.  If this isn't done here
+          * the check below will fire on 1 pixel high images.
+          */
+         if (png_ptr->height == 1)
+            filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
 
-            else
-            {
-               png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
-                   (png_ptr->rowbytes + 1));
-               png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
-            }
-         }
+         if (png_ptr->width == 1)
+            filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH);
 
-         if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
-             png_ptr->paeth_row == NULL)
+         if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0
+            && png_ptr->prev_row == NULL)
          {
-            if (png_ptr->prev_row == NULL)
-            {
-               png_warning(png_ptr, "Can't add Paeth filter after starting");
-               png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
-            }
-
-            else
-            {
-               png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
-                   (png_ptr->rowbytes + 1));
-               png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
-            }
+            /* This is the error case, however it is benign - the previous row
+             * is not available so the filter can't be used.  Just warn here.
+             */
+            png_app_warning(png_ptr,
+               "png_set_filter: UP/AVG/PAETH cannot be added after start");
+            filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
          }
 
-         if (png_ptr->do_filter == PNG_NO_FILTERS)
-#endif /* PNG_WRITE_FILTER_SUPPORTED */
-            png_ptr->do_filter = PNG_FILTER_NONE;
-      }
-   }
-   else
-      png_error(png_ptr, "Unknown custom filter method");
-}
+         num_filters = 0;
 
-/* This allows us to influence the way in which libpng chooses the "best"
- * filter for the current scanline.  While the "minimum-sum-of-absolute-
- * differences metric is relatively fast and effective, there is some
- * question as to whether it can be improved upon by trying to keep the
- * filtered data going to zlib more consistent, hopefully resulting in
- * better compression.
- */
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED      /* GRR 970116 */
-/* Convenience reset API. */
-static void
-png_reset_filter_heuristics(png_structrp png_ptr)
-{
-   /* Clear out any old values in the 'weights' - this must be done because if
-    * the app calls set_filter_heuristics multiple times with different
-    * 'num_weights' values we would otherwise potentially have wrong sized
-    * arrays.
-    */
-   png_ptr->num_prev_filters = 0;
-   png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
-   if (png_ptr->prev_filters != NULL)
-   {
-      png_bytep old = png_ptr->prev_filters;
-      png_ptr->prev_filters = NULL;
-      png_free(png_ptr, old);
-   }
-   if (png_ptr->filter_weights != NULL)
-   {
-      png_uint_16p old = png_ptr->filter_weights;
-      png_ptr->filter_weights = NULL;
-      png_free(png_ptr, old);
-   }
+         if (filters & PNG_FILTER_SUB)
+            num_filters++;
 
-   if (png_ptr->inv_filter_weights != NULL)
-   {
-      png_uint_16p old = png_ptr->inv_filter_weights;
-      png_ptr->inv_filter_weights = NULL;
-      png_free(png_ptr, old);
-   }
+         if (filters & PNG_FILTER_UP)
+            num_filters++;
 
-   /* Leave the filter_costs - this array is fixed size. */
-}
+         if (filters & PNG_FILTER_AVG)
+            num_filters++;
 
-static int
-png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method,
-   int num_weights)
-{
-   if (png_ptr == NULL)
-      return 0;
+         if (filters & PNG_FILTER_PAETH)
+            num_filters++;
 
-   /* Clear out the arrays */
-   png_reset_filter_heuristics(png_ptr);
-
-   /* Check arguments; the 'reset' function makes the correct settings for the
-    * unweighted case, but we must handle the weight case by initializing the
-    * arrays for the caller.
-    */
-   if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-   {
-      int i;
-
-      if (num_weights > 0)
-      {
-         png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)((sizeof (png_byte)) * num_weights));
-
-         /* To make sure that the weighting starts out fairly */
-         for (i = 0; i < num_weights; i++)
-         {
-            png_ptr->prev_filters[i] = 255;
-         }
-
-         png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
-             (png_uint_32)((sizeof (png_uint_16)) * num_weights));
+         /* Allocate needed row buffers if they have not already been
+          * allocated.
+          */
+         buf_size = PNG_ROWBYTES(png_ptr->usr_channels * png_ptr->usr_bit_depth,
+             png_ptr->width) + 1;
 
-         png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
-             (png_uint_32)((sizeof (png_uint_16)) * num_weights));
+         if (png_ptr->try_row == NULL)
+            png_ptr->try_row = png_voidcast(png_bytep,
+               png_malloc(png_ptr, buf_size));
 
-         for (i = 0; i < num_weights; i++)
+         if (num_filters > 1)
          {
-            png_ptr->inv_filter_weights[i] =
-            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+            if (png_ptr->tst_row == NULL)
+               png_ptr->tst_row = png_voidcast(png_bytep,
+                  png_malloc(png_ptr, buf_size));
          }
-
-         /* Safe to set this now */
-         png_ptr->num_prev_filters = (png_byte)num_weights;
-      }
-
-      /* If, in the future, there are other filter methods, this would
-       * need to be based on png_ptr->filter.
-       */
-      if (png_ptr->filter_costs == NULL)
-      {
-         png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
-             (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
-
-         png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
-             (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
-      }
-
-      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
-      {
-         png_ptr->inv_filter_costs[i] =
-         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
       }
-
-      /* All the arrays are inited, safe to set this: */
-      png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED;
-
-      /* Return the 'ok' code. */
-      return 1;
-   }
-   else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT ||
-      heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
-   {
-      return 1;
+      png_ptr->do_filter = (png_byte)filters;
+#endif
    }
    else
-   {
-      png_warning(png_ptr, "Unknown filter heuristic method");
-      return 0;
-   }
+      png_error(png_ptr, "Unknown custom filter method");
 }
 
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */
 /* Provide floating and fixed point APIs */
 #ifdef PNG_FLOATING_POINT_SUPPORTED
 void PNGAPI
@@ -1240,52 +1119,11 @@ png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method,
     int num_weights, png_const_doublep filter_weights,
     png_const_doublep filter_costs)
 {
-   png_debug(1, "in png_set_filter_heuristics");
-
-   /* The internal API allocates all the arrays and ensures that the elements of
-    * those arrays are set to the default value.
-    */
-   if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
-      return;
-
-   /* If using the weighted method copy in the weights. */
-   if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-   {
-      int i;
-      for (i = 0; i < num_weights; i++)
-      {
-         if (filter_weights[i] <= 0.0)
-         {
-            png_ptr->inv_filter_weights[i] =
-            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
-         }
-
-         else
-         {
-            png_ptr->inv_filter_weights[i] =
-                (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5);
-
-            png_ptr->filter_weights[i] =
-                (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5);
-         }
-      }
-
-      /* Here is where we set the relative costs of the different filters.  We
-       * should take the desired compression level into account when setting
-       * the costs, so that Paeth, for instance, has a high relative cost at low
-       * compression levels, while it has a lower relative cost at higher
-       * compression settings.  The filter types are in order of increasing
-       * relative cost, so it would be possible to do this with an algorithm.
-       */
-      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0)
-      {
-         png_ptr->inv_filter_costs[i] =
-             (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5);
-
-         png_ptr->filter_costs[i] =
-             (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5);
-      }
-   }
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(heuristic_method)
+   PNG_UNUSED(num_weights)
+   PNG_UNUSED(filter_weights)
+   PNG_UNUSED(filter_costs)
 }
 #endif /* FLOATING_POINT */
 
@@ -1295,67 +1133,16 @@ png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method,
     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");
-
-   /* The internal API allocates all the arrays and ensures that the elements of
-    * those arrays are set to the default value.
-    */
-   if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
-      return;
-
-   /* If using the weighted method copy in the weights. */
-   if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
-   {
-      int i;
-      for (i = 0; i < num_weights; i++)
-      {
-         if (filter_weights[i] <= 0)
-         {
-            png_ptr->inv_filter_weights[i] =
-            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
-         }
-
-         else
-         {
-            png_ptr->inv_filter_weights[i] = (png_uint_16)
-               ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1);
-
-            png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR*
-               PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]);
-         }
-      }
-
-      /* Here is where we set the relative costs of the different filters.  We
-       * should take the desired compression level into account when setting
-       * the costs, so that Paeth, for instance, has a high relative cost at low
-       * compression levels, while it has a lower relative cost at higher
-       * compression settings.  The filter types are in order of increasing
-       * relative cost, so it would be possible to do this with an algorithm.
-       */
-      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
-         if (filter_costs[i] >= PNG_FP_1)
-      {
-         png_uint_32 tmp;
-
-         /* 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;
-      }
-   }
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(heuristic_method)
+   PNG_UNUSED(num_weights)
+   PNG_UNUSED(filter_weights)
+   PNG_UNUSED(filter_costs)
 }
 #endif /* FIXED_POINT */
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+#endif /* WRITE_WEIGHTED_FILTER */
 
+#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
 void PNGAPI
 png_set_compression_level(png_structrp png_ptr, int level)
 {
@@ -1401,8 +1188,8 @@ png_set_compression_window_bits(png_structrp png_ptr, int window_bits)
    if (png_ptr == NULL)
       return;
 
-   /* Prior to 1.6.0 this would warn but then set the window_bits value, this
-    * meant that negative window bits values could be selected which would cause
+   /* Prior to 1.6.0 this would warn but then set the window_bits value. This
+    * meant that negative window bits values could be selected that would cause
     * libpng to write a non-standard PNG file with raw deflate or gzip
     * compressed IDAT or ancillary chunks.  Such files can be read and there is
     * no warning on read, so this seems like a very bad idea.
@@ -1438,6 +1225,7 @@ png_set_compression_method(png_structrp png_ptr, int method)
 
    png_ptr->zlib_method = method;
 }
+#endif /* WRITE_CUSTOMIZE_COMPRESSION */
 
 /* The following were added to libpng-1.5.4 */
 #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
@@ -1511,7 +1299,7 @@ png_set_text_compression_method(png_structrp png_ptr, int method)
 
    png_ptr->zlib_text_method = method;
 }
-#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */
+#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
 /* end of API added to libpng-1.5.4 */
 
 void PNGAPI
@@ -1559,7 +1347,7 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
    /* ------ these transformations don't touch the info structure ------- */
 
    /* Invert monochrome pixels */
-   if (transforms & PNG_TRANSFORM_INVERT_MONO)
+   if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)
 #ifdef PNG_WRITE_INVERT_SUPPORTED
       png_set_invert_mono(png_ptr);
 #else
@@ -1569,16 +1357,16 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
    /* Shift the pixels up to a legal bit depth and fill in
     * as appropriate to correctly scale the image.
     */
-   if (transforms & PNG_TRANSFORM_SHIFT)
+   if ((transforms & PNG_TRANSFORM_SHIFT) != 0)
 #ifdef PNG_WRITE_SHIFT_SUPPORTED
-      if (info_ptr->valid & PNG_INFO_sBIT)
+      if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
          png_set_shift(png_ptr, &info_ptr->sig_bit);
 #else
       png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
 #endif
 
    /* Pack pixels into bytes */
-   if (transforms & PNG_TRANSFORM_PACKING)
+   if ((transforms & PNG_TRANSFORM_PACKING) != 0)
 #ifdef PNG_WRITE_PACK_SUPPORTED
       png_set_packing(png_ptr);
 #else
@@ -1586,7 +1374,7 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
 #endif
 
    /* Swap location of alpha bytes from ARGB to RGBA */
-   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+   if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)
 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
       png_set_swap_alpha(png_ptr);
 #else
@@ -1597,21 +1385,21 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
     * RGB, note that the code expects the input color type to be G or RGB; no
     * alpha channel.
     */
-   if (transforms &
-      (PNG_TRANSFORM_STRIP_FILLER_AFTER|PNG_TRANSFORM_STRIP_FILLER_BEFORE))
+   if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER|
+       PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0)
    {
 #ifdef PNG_WRITE_FILLER_SUPPORTED
-      if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER)
+      if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0)
       {
-         if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
+         if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
             png_app_error(png_ptr,
-               "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported");
+                "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported");
 
          /* Continue if ignored - this is the pre-1.6.10 behavior */
          png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
       }
 
-      else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
+      else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
          png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
 #else
       png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported");
@@ -1619,7 +1407,7 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
    }
 
    /* Flip BGR pixels to RGB */
-   if (transforms & PNG_TRANSFORM_BGR)
+   if ((transforms & PNG_TRANSFORM_BGR) != 0)
 #ifdef PNG_WRITE_BGR_SUPPORTED
       png_set_bgr(png_ptr);
 #else
@@ -1627,15 +1415,15 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
 #endif
 
    /* Swap bytes of 16-bit files to most significant byte first */
-   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+   if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)
 #ifdef PNG_WRITE_SWAP_SUPPORTED
       png_set_swap(png_ptr);
 #else
       png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
 #endif
 
-   /* Swap bits of 1, 2, 4 bit packed pixel formats */
-   if (transforms & PNG_TRANSFORM_PACKSWAP)
+   /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */
+   if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
       png_set_packswap(png_ptr);
 #else
@@ -1643,7 +1431,7 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
 #endif
 
    /* Invert the alpha channel from opacity to transparency */
-   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+   if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)
 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
       png_set_invert_alpha(png_ptr);
 #else
@@ -1664,13 +1452,13 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
 
 
 #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
-#ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */
+# ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */
 /* Initialize the write structure - general purpose utility. */
 static int
 png_image_write_init(png_imagep image)
 {
    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,
-          png_safe_error, png_safe_warning);
+       png_safe_error, png_safe_warning);
 
    if (png_ptr != NULL)
    {
@@ -1679,7 +1467,7 @@ png_image_write_init(png_imagep image)
       if (info_ptr != NULL)
       {
          png_controlp control = png_voidcast(png_controlp,
-            png_malloc_warn(png_ptr, (sizeof *control)));
+             png_malloc_warn(png_ptr, (sizeof *control)));
 
          if (control != NULL)
          {
@@ -1726,31 +1514,32 @@ static int
 png_write_image_16bit(png_voidp argument)
 {
    png_image_write_control *display = png_voidcast(png_image_write_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
 
    png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
-      display->first_row);
+       display->first_row);
    png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
    png_uint_16p row_end;
-   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
+   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
    int aindex = 0;
    png_uint_32 y = image->height;
 
-   if (image->format & PNG_FORMAT_FLAG_ALPHA)
+   if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
    {
-#     ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
-         if (image->format & PNG_FORMAT_FLAG_AFIRST)
-         {
-            aindex = -1;
-            ++input_row; /* To point to the first component */
-            ++output_row;
-         }
-
+#   ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+      if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
+      {
+         aindex = -1;
+         ++input_row; /* To point to the first component */
+         ++output_row;
+      }
          else
-#     endif
+            aindex = channels;
+#     else
          aindex = channels;
+#     endif
    }
 
    else
@@ -1832,7 +1621,7 @@ png_write_image_16bit(png_voidp argument)
  * calculation can be done to 15 bits of accuracy; however, the output needs to
  * be scaled in the range 0..255*65535, so include that scaling here.
  */
-#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
+#   define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
 
 static png_byte
 png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
@@ -1883,32 +1672,32 @@ static int
 png_write_image_8bit(png_voidp argument)
 {
    png_image_write_control *display = png_voidcast(png_image_write_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
 
    png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
-      display->first_row);
+       display->first_row);
    png_bytep output_row = png_voidcast(png_bytep, display->local_row);
    png_uint_32 y = image->height;
-   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
+   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
 
-   if (image->format & PNG_FORMAT_FLAG_ALPHA)
+   if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
    {
       png_bytep row_end;
       int aindex;
 
-#     ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
-         if (image->format & PNG_FORMAT_FLAG_AFIRST)
-         {
-            aindex = -1;
-            ++input_row; /* To point to the first component */
-            ++output_row;
-         }
+#   ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+      if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
+      {
+         aindex = -1;
+         ++input_row; /* To point to the first component */
+         ++output_row;
+      }
 
-         else
-#     endif
-         aindex = channels;
+      else
+#   endif
+      aindex = channels;
 
       /* Use row_end in place of a loop counter: */
       row_end = output_row + image->width * (channels+1);
@@ -1942,7 +1731,7 @@ png_write_image_8bit(png_voidp argument)
          } /* while out_ptr < row_end */
 
          png_write_row(png_ptr, png_voidcast(png_const_bytep,
-            display->local_row));
+             display->local_row));
          input_row += display->row_bytes/(sizeof (png_uint_16));
       } /* while y */
    }
@@ -1981,25 +1770,25 @@ png_image_set_PLTE(png_image_write_control *display)
    const png_imagep image = display->image;
    const void *cmap = display->colormap;
    const int entries = image->colormap_entries > 256 ? 256 :
-      (int)image->colormap_entries;
+       (int)image->colormap_entries;
 
    /* NOTE: the caller must check for cmap != NULL and entries != 0 */
    const png_uint_32 format = image->format;
    const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
 
-#  if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
+#   if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
       defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
       const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
-         (format & PNG_FORMAT_FLAG_ALPHA) != 0;
-#  else
+          (format & PNG_FORMAT_FLAG_ALPHA) != 0;
+#   else
 #     define afirst 0
-#  endif
+#   endif
 
-#  ifdef PNG_FORMAT_BGR_SUPPORTED
-      const int bgr = (format & PNG_FORMAT_FLAG_BGR) ? 2 : 0;
-#  else
+#   ifdef PNG_FORMAT_BGR_SUPPORTED
+      const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
+#   else
 #     define bgr 0
-#  endif
+#   endif
 
    int i, num_trans;
    png_color palette[256];
@@ -2013,22 +1802,22 @@ png_image_set_PLTE(png_image_write_control *display)
       /* This gets automatically converted to sRGB with reversal of the
        * pre-multiplication if the color-map has an alpha channel.
        */
-      if (format & PNG_FORMAT_FLAG_LINEAR)
+      if ((format & PNG_FORMAT_FLAG_LINEAR) != 0)
       {
          png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
 
          entry += i * channels;
 
-         if (channels & 1) /* no alpha */
+         if ((channels & 1) != 0) /* no alpha */
          {
             if (channels >= 3) /* RGB */
             {
                palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
-                  entry[(2 ^ bgr)]);
+                   entry[(2 ^ bgr)]);
                palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
-                  entry[1]);
+                   entry[1]);
                palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
-                  entry[bgr]);
+                   entry[bgr]);
             }
 
             else /* Gray */
@@ -2104,12 +1893,12 @@ png_image_set_PLTE(png_image_write_control *display)
       }
    }
 
-#  ifdef afirst
+#   ifdef afirst
 #     undef afirst
-#  endif
-#  ifdef bgr
+#   endif
+#   ifdef bgr
 #     undef bgr
-#  endif
+#   endif
 
    png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
       entries);
@@ -2131,22 +1920,23 @@ png_image_write_main(png_voidp argument)
    png_inforp info_ptr = image->opaque->info_ptr;
    png_uint_32 format = image->format;
 
-   int colormap = (format & PNG_FORMAT_FLAG_COLORMAP) != 0;
-   int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR) != 0; /* input */
-   int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0;
-   int write_16bit = linear && !colormap && !display->convert_to_8bit;
+   /* The following four ints are actually booleans */
+   int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
+   int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
+   int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
+   int write_16bit = linear && !colormap && (display->convert_to_8bit == 0);
 
-#  ifdef PNG_BENIGN_ERRORS_SUPPORTED
+#   ifdef PNG_BENIGN_ERRORS_SUPPORTED
       /* Make sure we error out on any bad situation */
       png_set_benign_errors(png_ptr, 0/*error*/);
-#  endif
+#   endif
 
    /* Default the 'row_stride' parameter if required. */
    if (display->row_stride == 0)
       display->row_stride = PNG_IMAGE_ROW_STRIDE(*image);
 
    /* Set the required transforms then write the rows in the correct order. */
-   if (format & PNG_FORMAT_FLAG_COLORMAP)
+   if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)
    {
       if (display->colormap != NULL && image->colormap_entries > 0)
       {
@@ -2183,7 +1973,7 @@ png_image_write_main(png_voidp argument)
       /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */
       png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR);
 
-      if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB))
+      if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
          png_set_cHRM_fixed(png_ptr, info_ptr,
             /* color      x       y */
             /* white */ 31270, 32900,
@@ -2193,7 +1983,7 @@ png_image_write_main(png_voidp argument)
          );
    }
 
-   else if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB))
+   else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
       png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
 
    /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit
@@ -2208,38 +1998,38 @@ png_image_write_main(png_voidp argument)
    /* Now set up the data transformations (*after* the header is written),
     * remove the handled transformations from the 'format' flags for checking.
     *
-    * First check for a little endian system if writing 16 bit files.
+    * First check for a little endian system if writing 16-bit files.
     */
    if (write_16bit != 0)
    {
       PNG_CONST png_uint_16 le = 0x0001;
 
-      if (*(png_const_bytep)&le)
+      if ((*(png_const_bytep) & le) != 0)
          png_set_swap(png_ptr);
    }
 
-#  ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
-      if (format & PNG_FORMAT_FLAG_BGR)
+#   ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+      if ((format & PNG_FORMAT_FLAG_BGR) != 0)
       {
-         if (!colormap && (format & PNG_FORMAT_FLAG_COLOR) != 0)
+         if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0)
             png_set_bgr(png_ptr);
          format &= ~PNG_FORMAT_FLAG_BGR;
       }
-#  endif
+#   endif
 
-#  ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
-      if (format & PNG_FORMAT_FLAG_AFIRST)
+#   ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+      if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
       {
-         if (!colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0)
+         if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0)
             png_set_swap_alpha(png_ptr);
          format &= ~PNG_FORMAT_FLAG_AFIRST;
       }
-#  endif
+#   endif
 
    /* If there are 16 or fewer color-map entries we wrote a lower bit depth
     * above, but the application data is still byte packed.
     */
-   if (colormap && image->colormap_entries <= 16)
+   if (colormap != 0 && image->colormap_entries <= 16)
       png_set_packing(png_ptr);
 
    /* That should have handled all (both) the transforms. */
@@ -2270,14 +2060,17 @@ png_image_write_main(png_voidp argument)
        * it about 50 times.  The speed-up in pngstest was about 10-20% of the
        * total (user) time on a heavily loaded system.
        */
+#   ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
       png_set_compression_level(png_ptr, 3);
+#   endif
    }
 
    /* Check for the cases that currently require a pre-transform on the row
     * before it is written.  This only applies when the input is 16-bit and
     * either there is an alpha channel or it is converted to 8-bit.
     */
-   if ((linear && alpha) || (!colormap && display->convert_to_8bit))
+   if ((linear != 0 && alpha != 0 ) ||
+       (colormap == 0 && display->convert_to_8bit != 0))
    {
       png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
          png_get_rowbytes(png_ptr, info_ptr)));
@@ -2326,7 +2119,7 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
    {
       if (file != NULL)
       {
-         if (png_image_write_init(image))
+         if (png_image_write_init(image) != 0)
          {
             png_image_write_control display;
             int result;
@@ -2381,7 +2174,7 @@ png_image_write_to_file(png_imagep image, const char *file_name,
          if (fp != NULL)
          {
             if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
-               row_stride, colormap))
+               row_stride, colormap) != 0)
             {
                int error; /* from fflush/fclose */
 
@@ -2432,6 +2225,6 @@ png_image_write_to_file(png_imagep image, const char *file_name,
    else
       return 0;
 }
-#endif /* PNG_STDIO_SUPPORTED */
+# endif /* STDIO */
 #endif /* SIMPLIFIED_WRITE */
-#endif /* PNG_WRITE_SUPPORTED */
+#endif /* WRITE */