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 232243 31d28b1d4d7e99f08dd4ff541a95fd17db4f5f49
parent 232242 ccf50b47021dcb2492b49e217817f036b2f51ba8
child 232244 6d73cc06f9fed9512dd0cd2d531ff1445071679c
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmuizelaar
bugs1072340
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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