Bug 1072340 - Clean up PNG codecs in image/encoders,decoders. r=jmuizelaar
authorGlenn Randers-Pehrson <glennrp+bmo@gmail.com>
Wed, 24 Sep 2014 17:38:00 -0400
changeset 209028 31d28b1d4d7e99f08dd4ff541a95fd17db4f5f49
parent 209027 ccf50b47021dcb2492b49e217817f036b2f51ba8
child 209029 6d73cc06f9fed9512dd0cd2d531ff1445071679c
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjmuizelaar
bugs1072340
milestone35.0a1
Bug 1072340 - Clean up PNG codecs in image/encoders,decoders. r=jmuizelaar
image/decoders/nsPNGDecoder.cpp
image/decoders/nsPNGDecoder.h
image/encoders/png/nsPNGEncoder.cpp
image/encoders/png/nsPNGEncoder.h
--- a/image/decoders/nsPNGDecoder.cpp
+++ b/image/decoders/nsPNGDecoder.cpp
@@ -1,31 +1,26 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "ImageLogging.h"
-#include "nsPNGDecoder.h"
-
+#include "ImageLogging.h" // Must appear first
+#include "gfxColor.h"
+#include "gfxPlatform.h"
+#include "nsColor.h"
+#include "nsIInputStream.h"
 #include "nsMemory.h"
+#include "nsPNGDecoder.h"
 #include "nsRect.h"
-
-#include "nsIInputStream.h"
-
+#include "nspr.h"
+#include "png.h"
 #include "RasterImage.h"
 
-#include "gfxColor.h"
-#include "nsColor.h"
-
-#include "nspr.h"
-#include "png.h"
-
-#include "gfxPlatform.h"
 #include <algorithm>
 
 namespace mozilla {
 namespace image {
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo *
 GetPNGLog()
@@ -41,17 +36,17 @@ GetPNGDecoderAccountingLog()
 {
   static PRLogModuleInfo *sPNGDecoderAccountingLog;
   if (!sPNGDecoderAccountingLog)
     sPNGDecoderAccountingLog = PR_NewLogModule("PNGDecoderAccounting");
   return sPNGDecoderAccountingLog;
 }
 #endif
 
-/* limit image dimensions (bug #251381, #591822, and #967656) */
+// Limit image dimensions (bug #251381, #591822, and #967656)
 #ifndef MOZ_PNG_MAX_DIMENSION
 #  define MOZ_PNG_MAX_DIMENSION 32767
 #endif
 
 // For size decodes
 #define WIDTH_OFFSET 16
 #define HEIGHT_OFFSET (WIDTH_OFFSET + 4)
 #define BYTES_NEEDED_FOR_DIMENSIONS (HEIGHT_OFFSET + 4)
@@ -64,33 +59,34 @@ nsPNGDecoder::AnimFrameInfo::AnimFrameIn
 
 #ifdef PNG_APNG_SUPPORTED
 nsPNGDecoder::AnimFrameInfo::AnimFrameInfo(png_structp aPNG, png_infop aInfo)
  : mDispose(FrameBlender::kDisposeKeep)
  , mBlend(FrameBlender::kBlendOver)
  , mTimeout(0)
 {
   png_uint_16 delay_num, delay_den;
-  /* delay, in seconds is delay_num/delay_den */
+  // delay, in seconds is delay_num/delay_den
   png_byte dispose_op;
   png_byte blend_op;
   delay_num = png_get_next_frame_delay_num(aPNG, aInfo);
   delay_den = png_get_next_frame_delay_den(aPNG, aInfo);
   dispose_op = png_get_next_frame_dispose_op(aPNG, aInfo);
   blend_op = png_get_next_frame_blend_op(aPNG, aInfo);
 
   if (delay_num == 0) {
     mTimeout = 0; // SetFrameTimeout() will set to a minimum
   } else {
     if (delay_den == 0)
       delay_den = 100; // so says the APNG spec
 
     // Need to cast delay_num to float to have a proper division and
     // the result to int to avoid compiler warning
-    mTimeout = static_cast<int32_t>(static_cast<double>(delay_num) * 1000 / delay_den);
+    mTimeout = static_cast<int32_t>(static_cast<double>(delay_num) *
+                                    1000 / delay_den);
   }
 
   if (dispose_op == PNG_DISPOSE_OP_PREVIOUS) {
     mDispose = FrameBlender::kDisposeRestorePrevious;
   } else if (dispose_op == PNG_DISPOSE_OP_BACKGROUND) {
     mDispose = FrameBlender::kDisposeClear;
   } else {
     mDispose = FrameBlender::kDisposeKeep;
@@ -126,17 +122,17 @@ nsPNGDecoder::~nsPNGDecoder()
     png_destroy_read_struct(&mPNG, mInfo ? &mInfo : nullptr, nullptr);
   if (mCMSLine)
     nsMemory::Free(mCMSLine);
   if (interlacebuf)
     nsMemory::Free(interlacebuf);
   if (mInProfile) {
     qcms_profile_release(mInProfile);
 
-    /* mTransform belongs to us only if mInProfile is non-null */
+    // mTransform belongs to us only if mInProfile is non-null
     if (mTransform)
       qcms_transform_release(mTransform);
   }
 }
 
 // CreateFrame() is used for both simple and animated images
 void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
                                int32_t width, int32_t height,
@@ -190,55 +186,57 @@ void nsPNGDecoder::EndImageFrame()
   uint32_t numFrames = GetFrameCount();
 
   // We can't use mPNG->num_frames_read as it may be one ahead.
   if (numFrames > 1) {
     PostInvalidation(mFrameRect);
   }
 #endif
 
-  PostFrameStop(alpha, mAnimInfo.mDispose, mAnimInfo.mTimeout, mAnimInfo.mBlend);
+  PostFrameStop(alpha, mAnimInfo.mDispose, mAnimInfo.mTimeout,
+                mAnimInfo.mBlend);
 }
 
 void
 nsPNGDecoder::InitInternal()
 {
   // For size decodes, we don't need to initialize the png decoder
   if (IsSizeDecode()) {
     return;
   }
 
   mCMSMode = gfxPlatform::GetCMSMode();
   if ((mDecodeFlags & DECODER_NO_COLORSPACE_CONVERSION) != 0)
     mCMSMode = eCMSMode_Off;
-  mDisablePremultipliedAlpha = (mDecodeFlags & DECODER_NO_PREMULTIPLY_ALPHA) != 0;
+  mDisablePremultipliedAlpha = (mDecodeFlags & DECODER_NO_PREMULTIPLY_ALPHA)
+                                != 0;
 
 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   static png_byte color_chunks[]=
-       { 99,  72,  82,  77, '\0',   /* cHRM */
-        105,  67,  67,  80, '\0'};  /* iCCP */
+       { 99,  72,  82,  77, '\0',   // cHRM
+        105,  67,  67,  80, '\0'};  // iCCP
   static png_byte unused_chunks[]=
-       { 98,  75,  71,  68, '\0',   /* bKGD */
-        104,  73,  83,  84, '\0',   /* hIST */
-        105,  84,  88, 116, '\0',   /* iTXt */
-        111,  70,  70, 115, '\0',   /* oFFs */
-        112,  67,  65,  76, '\0',   /* pCAL */
-        115,  67,  65,  76, '\0',   /* sCAL */
-        112,  72,  89, 115, '\0',   /* pHYs */
-        115,  66,  73,  84, '\0',   /* sBIT */
-        115,  80,  76,  84, '\0',   /* sPLT */
-        116,  69,  88, 116, '\0',   /* tEXt */
-        116,  73,  77,  69, '\0',   /* tIME */
-        122,  84,  88, 116, '\0'};  /* zTXt */
+       { 98,  75,  71,  68, '\0',   // bKGD
+        104,  73,  83,  84, '\0',   // hIST
+        105,  84,  88, 116, '\0',   // iTXt
+        111,  70,  70, 115, '\0',   // oFFs
+        112,  67,  65,  76, '\0',   // pCAL
+        115,  67,  65,  76, '\0',   // sCAL
+        112,  72,  89, 115, '\0',   // pHYs
+        115,  66,  73,  84, '\0',   // sBIT
+        115,  80,  76,  84, '\0',   // sPLT
+        116,  69,  88, 116, '\0',   // tEXt
+        116,  73,  77,  69, '\0',   // tIME
+        122,  84,  88, 116, '\0'};  // zTXt
 #endif
 
-  /* For full decodes, do png init stuff */
+  // For full decodes, do png init stuff
 
-  /* Initialize the container's source image header. */
-  /* Always decode to 24 bit pixdepth */
+  // Initialize the container's source image header
+  // Always decode to 24 bit pixdepth
 
   mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                 nullptr, nsPNGDecoder::error_callback,
                                 nsPNGDecoder::warning_callback);
   if (!mPNG) {
     PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
@@ -246,57 +244,57 @@ nsPNGDecoder::InitInternal()
   mInfo = png_create_info_struct(mPNG);
   if (!mInfo) {
     PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
     png_destroy_read_struct(&mPNG, nullptr, nullptr);
     return;
   }
 
 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-  /* Ignore unused chunks */
+  // Ignore unused chunks
   if (mCMSMode == eCMSMode_Off)
     png_set_keep_unknown_chunks(mPNG, 1, color_chunks, 2);
 
   png_set_keep_unknown_chunks(mPNG, 1, unused_chunks,
                               (int)sizeof(unused_chunks)/5);
 #endif
 
 #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
   if (mCMSMode != eCMSMode_Off)
     png_set_chunk_malloc_max(mPNG, 4000000L);
 #endif
 
 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
 #ifndef PR_LOGGING
-  /* Disallow palette-index checking, for speed; we would ignore the warning
-   * anyhow unless we have defined PR_LOGGING.  This feature was added at
-   * libpng version 1.5.10 and is disabled in the embedded libpng but enabled
-   * by default in the system libpng.  This call also disables it in the
-   * system libpng, for decoding speed.  Bug #745202.
-   */
+  // Disallow palette-index checking, for speed; we would ignore the warning
+  // anyhow unless we have defined PR_LOGGING.  This feature was added at
+  // libpng version 1.5.10 and is disabled in the embedded libpng but enabled
+  // by default in the system libpng.  This call also disables it in the
+  // system libpng, for decoding speed.  Bug #745202.
   png_set_check_for_invalid_index(mPNG, 0);
 #endif
 #endif
 
 #if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_sRGB_PROFILE_CHECKS) && \
             PNG_sRGB_PROFILE_CHECKS >= 0
-  /* Skip checking of sRGB ICC profiles */
+  // Skip checking of sRGB ICC profiles
   png_set_option(mPNG, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON);
 #endif
 
-  /* use this as libpng "progressive pointer" (retrieve in callbacks) */
+  // use this as libpng "progressive pointer" (retrieve in callbacks)
   png_set_progressive_read_fn(mPNG, static_cast<png_voidp>(this),
                               nsPNGDecoder::info_callback,
                               nsPNGDecoder::row_callback,
                               nsPNGDecoder::end_callback);
 
 }
 
 void
-nsPNGDecoder::WriteInternal(const char *aBuffer, uint32_t aCount, DecodeStrategy)
+nsPNGDecoder::WriteInternal(const char *aBuffer, uint32_t aCount,
+                            DecodeStrategy)
 {
   NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");
 
   // If we only want width/height, we don't need to go through libpng
   if (IsSizeDecode()) {
 
     // Are we done?
     if (mHeaderBytesRead == BYTES_NEEDED_FOR_DIMENSIONS)
@@ -388,34 +386,24 @@ PNGGetColorProfile(png_structp png_ptr, 
                    int color_type, qcms_data_type *inType, uint32_t *intent)
 {
   qcms_profile *profile = nullptr;
   *intent = QCMS_INTENT_PERCEPTUAL; // Our default
 
   // First try to see if iCCP chunk is present
   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) {
     png_uint_32 profileLen;
-#if (PNG_LIBPNG_VER < 10500)
-    char *profileData, *profileName;
-#else
     png_bytep profileData;
     png_charp profileName;
-#endif
     int compression;
 
     png_get_iCCP(png_ptr, info_ptr, &profileName, &compression,
                  &profileData, &profileLen);
 
-    profile = qcms_profile_from_memory(
-#if (PNG_LIBPNG_VER < 10500)
-                                       profileData,
-#else
-                                       (char *)profileData,
-#endif
-                                       profileLen);
+    profile = qcms_profile_from_memory((char *)profileData, profileLen);
     if (profile) {
       uint32_t profileSpace = qcms_profile_get_color_space(profile);
 
       bool mismatch = false;
       if (color_type & PNG_COLOR_MASK_COLOR) {
         if (profileSpace != icSigRgbData)
           mismatch = true;
       } else {
@@ -493,81 +481,81 @@ PNGGetColorProfile(png_structp png_ptr, 
   }
 
   return profile;
 }
 
 void
 nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr)
 {
-/*  int number_passes;   NOT USED  */
+//  int number_passes;   NOT USED
   png_uint_32 width, height;
   int bit_depth, color_type, interlace_type, compression_type, filter_type;
   unsigned int channels;
 
   png_bytep trans = nullptr;
   int num_trans = 0;
 
   nsPNGDecoder *decoder =
                static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
 
-  /* always decode to 24-bit RGB or 32-bit RGBA  */
+  // Always decode to 24-bit RGB or 32-bit RGBA
   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
                &interlace_type, &compression_type, &filter_type);
 
-  /* Are we too big? */
+  // Are we too big?
   if (width > MOZ_PNG_MAX_DIMENSION || height > MOZ_PNG_MAX_DIMENSION)
-    longjmp(png_jmpbuf(decoder->mPNG), 1);
+    png_longjmp(decoder->mPNG, 1);
 
   // Post our size to the superclass
   decoder->PostSize(width, height);
   if (decoder->HasError()) {
     // Setting the size led to an error.
-    longjmp(png_jmpbuf(decoder->mPNG), 1);
+    png_longjmp(decoder->mPNG, 1);
   }
 
   if (color_type == PNG_COLOR_TYPE_PALETTE)
     png_set_expand(png_ptr);
 
   if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
     png_set_expand(png_ptr);
 
   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
     int sample_max = (1 << bit_depth);
     png_color_16p trans_values;
     png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values);
-    /* libpng doesn't reject a tRNS chunk with out-of-range samples
-       so we check it here to avoid setting up a useless opacity
-       channel or producing unexpected transparent pixels when using
-       libpng-1.2.19 through 1.2.26 (bug #428045) */
+    // libpng doesn't reject a tRNS chunk with out-of-range samples
+    // so we check it here to avoid setting up a useless opacity
+    // channel or producing unexpected transparent pixels when using
+    // libpng-1.2.19 through 1.2.26 (bug #428045)
     if ((color_type == PNG_COLOR_TYPE_GRAY &&
        (int)trans_values->gray > sample_max) ||
        (color_type == PNG_COLOR_TYPE_RGB &&
        ((int)trans_values->red > sample_max ||
        (int)trans_values->green > sample_max ||
        (int)trans_values->blue > sample_max)))
       {
-        /* clear the tRNS valid flag and release tRNS memory */
+        // clear the tRNS valid flag and release tRNS memory
         png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
       }
     else
       png_set_expand(png_ptr);
   }
 
   if (bit_depth == 16)
     png_set_scale_16(png_ptr);
 
   qcms_data_type inType = QCMS_DATA_RGBA_8;
   uint32_t intent = -1;
   uint32_t pIntent;
   if (decoder->mCMSMode != eCMSMode_Off) {
     intent = gfxPlatform::GetRenderingIntent();
     decoder->mInProfile = PNGGetColorProfile(png_ptr, info_ptr,
                                              color_type, &inType, &pIntent);
-    /* If we're not mandating an intent, use the one from the image. */
+    // If we're not mandating an intent, use the one from the image.
     if (intent == uint32_t(-1))
       intent = pIntent;
   }
   if (decoder->mInProfile && gfxPlatform::GetCMSOutputProfile()) {
     qcms_data_type outType;
 
     if (color_type & PNG_COLOR_MASK_ALPHA || num_trans)
       outType = QCMS_DATA_RGBA_8;
@@ -589,52 +577,30 @@ nsPNGDecoder::info_callback(png_structp 
     if (decoder->mCMSMode == eCMSMode_All) {
       if (color_type & PNG_COLOR_MASK_ALPHA || num_trans)
         decoder->mTransform = gfxPlatform::GetCMSRGBATransform();
       else
         decoder->mTransform = gfxPlatform::GetCMSRGBTransform();
     }
   }
 
-  /* let libpng expand interlaced images */
+  // let libpng expand interlaced images
   if (interlace_type == PNG_INTERLACE_ADAM7) {
-    /* number_passes = */
+    // number_passes =
     png_set_interlace_handling(png_ptr);
   }
 
-  /* now all of those things we set above are used to update various struct
-   * members and whatnot, after which we can get channels, rowbytes, etc. */
+  // now all of those things we set above are used to update various struct
+  // members and whatnot, after which we can get channels, rowbytes, etc.
   png_read_update_info(png_ptr, info_ptr);
   decoder->mChannels = channels = png_get_channels(png_ptr, info_ptr);
 
-  /*---------------------------------------------------------------*/
-  /* copy PNG info into imagelib structs (formerly png_set_dims()) */
-  /*---------------------------------------------------------------*/
-
-  // This code is currently unused, but it will be needed for bug 517713.
-#if 0
-  int32_t alpha_bits = 1;
-
-  if (channels == 2 || channels == 4) {
-    /* check if alpha is coming from a tRNS chunk and is binary */
-    if (num_trans) {
-      /* if it's not an indexed color image, tRNS means binary */
-      if (color_type == PNG_COLOR_TYPE_PALETTE) {
-        for (int i=0; i<num_trans; i++) {
-          if ((trans[i] != 0) && (trans[i] != 255)) {
-            alpha_bits = 8;
-            break;
-          }
-        }
-      }
-    } else {
-      alpha_bits = 8;
-    }
-  }
-#endif
+  //---------------------------------------------------------------//
+  // copy PNG info into imagelib structs (formerly png_set_dims()) //
+  //---------------------------------------------------------------//
 
   if (channels == 1 || channels == 3)
     decoder->format = gfx::SurfaceFormat::B8G8R8X8;
   else if (channels == 2 || channels == 4)
     decoder->format = gfx::SurfaceFormat::B8G8R8A8;
 
 #ifdef PNG_APNG_SUPPORTED
   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL))
@@ -651,32 +617,31 @@ nsPNGDecoder::info_callback(png_structp 
 #endif
 
   if (decoder->mTransform &&
       (channels <= 2 || interlace_type == PNG_INTERLACE_ADAM7)) {
     uint32_t bpp[] = { 0, 3, 4, 3, 4 };
     decoder->mCMSLine =
       (uint8_t *)moz_malloc(bpp[channels] * width);
     if (!decoder->mCMSLine) {
-      longjmp(png_jmpbuf(decoder->mPNG), 5); // NS_ERROR_OUT_OF_MEMORY
+      png_longjmp(decoder->mPNG, 5); // NS_ERROR_OUT_OF_MEMORY
     }
   }
 
   if (interlace_type == PNG_INTERLACE_ADAM7) {
     if (height < INT32_MAX / (width * channels))
       decoder->interlacebuf = (uint8_t *)moz_malloc(channels * width * height);
     if (!decoder->interlacebuf) {
-      longjmp(png_jmpbuf(decoder->mPNG), 5); // NS_ERROR_OUT_OF_MEMORY
+      png_longjmp(decoder->mPNG, 5); // NS_ERROR_OUT_OF_MEMORY
     }
   }
 
   if (decoder->NeedsNewFrame()) {
-    /* We know that we need a new frame, so pause input so the decoder
-     * infrastructure can give it to us.
-     */
+    // We know that we need a new frame, so pause input so the decoder
+    // infrastructure can give it to us.
     png_process_data_pause(png_ptr, /* save = */ 1);
   }
 }
 
 void
 nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
                            png_uint_32 row_num, int pass)
 {
@@ -730,17 +695,17 @@ nsPNGDecoder::row_callback(png_structp p
     uint32_t bpr = width * sizeof(uint32_t);
     uint32_t *cptr32 = (uint32_t*)(decoder->mImageData + (row_num*bpr));
     bool rowHasNoAlpha = true;
 
     if (decoder->mTransform) {
       if (decoder->mCMSLine) {
         qcms_transform_data(decoder->mTransform, line, decoder->mCMSLine,
                             iwidth);
-        /* copy alpha over */
+        // copy alpha over
         uint32_t channels = decoder->mChannels;
         if (channels == 2 || channels == 4) {
           for (uint32_t i = 0; i < iwidth; i++)
             decoder->mCMSLine[4 * i + 3] = line[channels * i + channels - 1];
         }
         line = decoder->mCMSLine;
       } else {
         qcms_transform_data(decoder->mTransform, line, line, iwidth);
@@ -781,26 +746,27 @@ nsPNGDecoder::row_callback(png_structp p
           for (uint32_t x=width; x>0; --x) {
             *cptr32++ = gfxPackedPixel(line[3], line[0], line[1], line[2]);
             if (line[3] != 0xff)
               rowHasNoAlpha = false;
             line += 4;
           }
         } else {
           for (uint32_t x=width; x>0; --x) {
-            *cptr32++ = gfxPackedPixelNoPreMultiply(line[3], line[0], line[1], line[2]);
+            *cptr32++ = gfxPackedPixelNoPreMultiply(line[3], line[0], line[1],
+                                                    line[2]);
             if (line[3] != 0xff)
               rowHasNoAlpha = false;
             line += 4;
           }
         }
       }
       break;
       default:
-        longjmp(png_jmpbuf(decoder->mPNG), 1);
+        png_longjmp(decoder->mPNG, 1);
     }
 
     if (!rowHasNoAlpha)
       decoder->mFrameHasNoAlpha = false;
 
     if (decoder->mNumFrames <= 1) {
       // Only do incremental image display for the first frame
       // XXXbholley - this check should be handled in the superclass
@@ -830,19 +796,18 @@ nsPNGDecoder::frame_info_callback(png_st
   x_offset = png_get_next_frame_x_offset(png_ptr, decoder->mInfo);
   y_offset = png_get_next_frame_y_offset(png_ptr, decoder->mInfo);
   width = png_get_next_frame_width(png_ptr, decoder->mInfo);
   height = png_get_next_frame_height(png_ptr, decoder->mInfo);
 
   decoder->CreateFrame(x_offset, y_offset, width, height, decoder->format);
 
   if (decoder->NeedsNewFrame()) {
-    /* We know that we need a new frame, so pause input so the decoder
-     * infrastructure can give it to us.
-     */
+    // We know that we need a new frame, so pause input so the decoder
+    // infrastructure can give it to us.
     png_process_data_pause(png_ptr, /* save = */ 1);
   }
 }
 #endif
 
 void
 nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr)
 {
@@ -877,17 +842,17 @@ nsPNGDecoder::end_callback(png_structp p
   decoder->PostDecodeDone(loop_count);
 }
 
 
 void
 nsPNGDecoder::error_callback(png_structp png_ptr, png_const_charp error_msg)
 {
   PR_LOG(GetPNGLog(), PR_LOG_ERROR, ("libpng error: %s\n", error_msg));
-  longjmp(png_jmpbuf(png_ptr), 1);
+  png_longjmp(png_ptr, 1);
 }
 
 
 void
 nsPNGDecoder::warning_callback(png_structp png_ptr, png_const_charp warning_msg)
 {
   PR_LOG(GetPNGLog(), PR_LOG_WARNING, ("libpng warning: %s\n", warning_msg));
 }
--- a/image/decoders/nsPNGDecoder.h
+++ b/image/decoders/nsPNGDecoder.h
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef nsPNGDecoder_h__
-#define nsPNGDecoder_h__
+#ifndef nsPNGDecoder_h
+#define nsPNGDecoder_h
 
 #include "Decoder.h"
 
 #include "gfxTypes.h"
 
 #include "nsCOMPtr.h"
 
 #include "png.h"
@@ -128,9 +128,9 @@ public:
   // This is defined in the PNG spec as an invariant. We use it to
   // do manual validation without libpng.
   static const uint8_t pngSignatureBytes[];
 };
 
 } // namespace image
 } // namespace mozilla
 
-#endif // nsPNGDecoder_h__
+#endif // nsPNGDecoder_h
--- a/image/encoders/png/nsPNGEncoder.cpp
+++ b/image/encoders/png/nsPNGEncoder.cpp
@@ -1,31 +1,45 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "ImageLogging.h"
 #include "nsCRT.h"
 #include "nsPNGEncoder.h"
-#include "prprf.h"
+#include "nsStreamUtils.h"
 #include "nsString.h"
-#include "nsStreamUtils.h"
+#include "prprf.h"
 
 using namespace mozilla;
 
-NS_IMPL_ISUPPORTS(nsPNGEncoder, imgIEncoder, nsIInputStream, nsIAsyncInputStream)
+#ifdef PR_LOGGING
+static PRLogModuleInfo *
+GetPNGEncoderLog()
+{
+  static PRLogModuleInfo *sPNGEncoderLog;
+  if (!sPNGEncoderLog)
+    sPNGEncoderLog = PR_NewLogModule("PNGEncoder");
+  return sPNGEncoderLog;
+}
+#endif
+
+NS_IMPL_ISUPPORTS(nsPNGEncoder, imgIEncoder, nsIInputStream,
+                  nsIAsyncInputStream)
 
 nsPNGEncoder::nsPNGEncoder() : mPNG(nullptr), mPNGinfo(nullptr),
                                mIsAnimation(false),
                                mFinished(false),
                                mImageBuffer(nullptr), mImageBufferSize(0),
                                mImageBufferUsed(0), mImageBufferReadPoint(0),
                                mCallback(nullptr),
                                mCallbackTarget(nullptr), mNotifyThreshold(0),
-                               mReentrantMonitor("nsPNGEncoder.mReentrantMonitor")
+                               mReentrantMonitor(
+                                              "nsPNGEncoder.mReentrantMonitor")
 {
 }
 
 nsPNGEncoder::~nsPNGEncoder()
 {
   if (mImageBuffer) {
     moz_free(mImageBuffer);
     mImageBuffer = nullptr;
@@ -67,17 +81,17 @@ NS_IMETHODIMP nsPNGEncoder::InitFromData
   rv = EndImageEncode();
 
   return rv;
 }
 
 
 // nsPNGEncoder::StartImageEncode
 //
-// 
+//
 // See ::InitFromData for other info.
 NS_IMETHODIMP nsPNGEncoder::StartImageEncode(uint32_t aWidth,
                                              uint32_t aHeight,
                                              uint32_t aInputFormat,
                                              const nsAString& aOutputOptions)
 {
   bool useTransparency = true, skipFirstFrame = false;
   uint32_t numFrames = 1;
@@ -236,17 +250,17 @@ NS_IMETHODIMP nsPNGEncoder::AddImageFram
   if (mIsAnimation) {
     // XXX the row pointers arg (#3) is unused, can it be removed?
     png_write_frame_head(mPNG, mPNGinfo, nullptr,
                          aWidth, aHeight, x_offset, y_offset,
                          delay_ms, 1000, dispose_op, blend_op);
   }
 #endif
 
-  // Stride is the padded width of each row, so it better be longer 
+  // Stride is the padded width of each row, so it better be longer
   // (I'm afraid people will not understand what stride means, so
   // check it well)
   if ((aInputFormat == INPUT_FORMAT_RGB &&
       aStride < aWidth * 3) ||
       ((aInputFormat == INPUT_FORMAT_RGBA ||
       aInputFormat == INPUT_FORMAT_HOSTARGB) &&
       aStride < aWidth * 4)) {
     NS_WARNING("Invalid stride for InitFromData/AddImageFrame");
@@ -562,17 +576,18 @@ NS_IMETHODIMP nsPNGEncoder::AsyncWait(ns
   // 0 means "any number of bytes except 0"
   mNotifyThreshold = aRequestedCount;
   if (!aRequestedCount)
     mNotifyThreshold = 1024; // We don't want to notify incessantly
 
   // We set the callback absolutely last, because NotifyListener uses it to
   // determine if someone needs to be notified.  If we don't set it last,
   // NotifyListener might try to fire off a notification to a null target
-  // which will generally cause non-threadsafe objects to be used off the main thread
+  // which will generally cause non-threadsafe objects to be used off the main
+  // thread
   mCallback = aCallback;
 
   // What we are being asked for may be present already
   NotifyListener();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPNGEncoder::CloseWithStatus(nsresult aStatus)
@@ -626,47 +641,35 @@ nsPNGEncoder::StripAlpha(const uint8_t* 
     pixelOut[1] = pixelIn[1];
     pixelOut[2] = pixelIn[2];
   }
 }
 
 
 // nsPNGEncoder::WarningCallback
 
-void // static
+void
 nsPNGEncoder::WarningCallback(png_structp png_ptr,
                             png_const_charp warning_msg)
 {
-#ifdef DEBUG
-	// XXX: these messages are probably useful callers...
-        // use nsIConsoleService?
-	PR_fprintf(PR_STDERR, "PNG Encoder: %s\n", warning_msg);;
-#endif
+  PR_LOG(GetPNGEncoderLog(), PR_LOG_WARNING,
+         ("libpng warning: %s\n", warning_msg));
 }
 
 
 // nsPNGEncoder::ErrorCallback
 
-void // static
+void
 nsPNGEncoder::ErrorCallback(png_structp png_ptr,
                             png_const_charp error_msg)
 {
-#ifdef DEBUG
-	// XXX: these messages are probably useful callers...
-        // use nsIConsoleService?
-	PR_fprintf(PR_STDERR, "PNG Encoder: %s\n", error_msg);;
-#endif
-#if PNG_LIBPNG_VER < 10500
-        longjmp(png_ptr->jmpbuf, 1);
-#else
-        png_longjmp(png_ptr, 1);
-#endif
+  PR_LOG(GetPNGEncoderLog(), PR_LOG_ERROR, ("libpng error: %s\n", error_msg));
+  png_longjmp(png_ptr, 1);
 }
 
-
 // nsPNGEncoder::WriteCallback
 
 void // static
 nsPNGEncoder::WriteCallback(png_structp png, png_bytep data,
                             png_size_t size)
 {
   nsPNGEncoder* that = static_cast<nsPNGEncoder*>(png_get_io_ptr(png));
   if (! that->mImageBuffer)
--- a/image/encoders/png/nsPNGEncoder.h
+++ b/image/encoders/png/nsPNGEncoder.h
@@ -1,21 +1,22 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/Attributes.h"
-#include "mozilla/ReentrantMonitor.h"
+#ifndef nsPNGEncoder_h
+
+#include <png.h>
 
 #include "imgIEncoder.h"
-
 #include "nsCOMPtr.h"
 
-#include <png.h>
+#include "mozilla/Attributes.h"
+#include "mozilla/ReentrantMonitor.h"
 
 #define NS_PNGENCODER_CID \
 { /* 38d1592e-b81e-432b-86f8-471878bbfe07 */         \
      0x38d1592e,                                     \
      0xb81e,                                         \
      0x432b,                                         \
     {0x86, 0xf8, 0x47, 0x18, 0x78, 0xbb, 0xfe, 0x07} \
 }
@@ -67,16 +68,16 @@ protected:
   uint32_t mImageBufferUsed;
 
   uint32_t mImageBufferReadPoint;
 
   nsCOMPtr<nsIInputStreamCallback> mCallback;
   nsCOMPtr<nsIEventTarget> mCallbackTarget;
   uint32_t mNotifyThreshold;
 
-  /*
-    nsPNGEncoder is designed to allow one thread to pump data into it while another
-    reads from it.  We lock to ensure that the buffer remains append-only while
-    we read from it (that it is not realloced) and to ensure that only one thread
-    dispatches a callback for each call to AsyncWait.
-   */
+  // nsPNGEncoder is designed to allow one thread to pump data into it while
+  // another reads from it.  We lock to ensure that the buffer remains
+  // append-only while we read from it (that it is not realloced) and to
+  // ensure that only one thread dispatches a callback for each call to
+  // AsyncWait.
   ReentrantMonitor mReentrantMonitor;
 };
+#endif // nsPNGEncoder_h