]> granicus.if.org Git - imagemagick/blobdiff - coders/png.c
Avoid using NULL alpha_image in the JNG decoder.
[imagemagick] / coders / png.c
index ca7927ccdbce8470ab797cfa0933c94293fb8494..3719185735b530083310380c9742edc4e8513427 100644 (file)
@@ -18,7 +18,7 @@
 %                               November 1997                                 %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -138,7 +138,7 @@ struct sRGB_info_struct
 };
 
 const struct sRGB_info_struct sRGB_info[] =
-{ 
+{
     /* ICC v2 perceptual sRGB_IEC61966-2-1_black_scaled.icc */
     { 3048, 0x3b8772b9UL, 0},
 
@@ -1038,14 +1038,6 @@ Magick_RenderingIntentString_from_PNG_RenderingIntent(const int ping_intent)
     }
 }
 
-static inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
-{
-  if (x > y)
-    return(x);
-
-  return(y);
-}
-
 static const char *
 Magick_ColorType_from_PNG_ColorType(const int ping_colortype)
 {
@@ -1071,14 +1063,6 @@ Magick_ColorType_from_PNG_ColorType(const int ping_colortype)
     }
 }
 
-
-static inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
-{
-  if (x < y)
-    return(x);
-
-  return(y);
-}
 #endif /* PNG_LIBPNG_VER > 10011 */
 #endif /* MAGICKCORE_PNG_DELEGATE */
 \f
@@ -2338,12 +2322,12 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
   {
      const char
        *value;
+
      value=GetImageOption(image_info,"png:swap-bytes");
+
      if (value == NULL)
         value=GetImageArtifact(image,"png:swap-bytes");
+
      if (value != NULL)
         png_set_swap(ping);
   }
@@ -2878,7 +2862,7 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
       else
         {
           int
-             scale_to_short;
+            scale_to_short;
 
           scale_to_short = 65535L/((1UL << ping_file_depth)-1);
 
@@ -2971,7 +2955,7 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
 
       image->gamma = image_gamma;
     }
-  
+
   (void)LogMagickEvent(CoderEvent,GetMagickModule(),
       "    image->colorspace=%d",(int) image->colorspace);
 
@@ -3038,13 +3022,14 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
 
       else
         {
-          size_t
+          Quantum
             scale;
 
-          scale=(QuantumRange/((1UL << ping_file_depth)-1));
+          scale = (Quantum) (65535UL)/((1UL << ping_file_depth)-1);
 
-          if (scale < 1)
-             scale=1;
+#if (MAGICKCORE_QUANTUM_DEPTH > 16)
+          scale = ScaleShortToQuantum(scale);
+#endif
 
           for (i=0; i < (ssize_t) image->colors; i++)
           {
@@ -3260,10 +3245,10 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
               }
             }
 
-          if ((image->previous == (Image *) NULL) && (num_passes == 1))
+          if (num_passes == 1)
             {
-              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
-                  image->rows);
+              status=SetImageProgress(image,LoadImageTag,
+                  (MagickOffsetType) y, image->rows);
 
               if (status == MagickFalse)
                 break;
@@ -3272,7 +3257,7 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
             break;
         }
 
-        if ((image->previous == (Image *) NULL) && (num_passes != 1))
+        if (num_passes != 1)
           {
             status=SetImageProgress(image,LoadImageTag,pass,num_passes);
             if (status == MagickFalse)
@@ -3363,7 +3348,7 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
           {
             for (x=(ssize_t) image->columns-1; x >= 0; x--)
             {
-#if (MAGICKCORE_QUANTUM_DEPTH == 16) || (MAGICKCORE_QUANTUM_DEPTH == 32)
+#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
               unsigned short
                 quantum;
 
@@ -3437,7 +3422,7 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
         if (SyncAuthenticPixels(image,exception) == MagickFalse)
           break;
 
-        if ((image->previous == (Image *) NULL) && (num_passes == 1))
+        if (num_passes == 1)
           {
             status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
               image->rows);
@@ -3447,7 +3432,7 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
           }
       }
 
-      if ((image->previous == (Image *) NULL) && (num_passes != 1))
+      if (num_passes != 1)
         {
           status=SetImageProgress(image,LoadImageTag,pass,num_passes);
 
@@ -3620,7 +3605,8 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "    Reading PNG text chunk");
 
-        if (memcmp(text[i].key, "Raw profile type ",17) == 0)
+        if (strlen(text[i].key) > 16 &&
+            memcmp(text[i].key, "Raw profile type ",17) == 0)
           {
             const char
               *value;
@@ -3778,13 +3764,13 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
     if (image->alpha_trait != UndefinedPixelTrait)
     {
       if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-        (void) SetImageType(image,GrayscaleMatteType,exception);
+        (void) SetImageType(image,GrayscaleAlphaType,exception);
 
       else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
-        (void) SetImageType(image,PaletteMatteType,exception);
+        (void) SetImageType(image,PaletteAlphaType,exception);
 
       else
-        (void) SetImageType(image,TrueColorMatteType,exception);
+        (void) SetImageType(image,TrueColorAlphaType,exception);
     }
 
     else
@@ -3935,8 +3921,7 @@ static Image *ReadOnePNGImage(MngInfo *mng_info,
 static Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
   Image
-    *image,
-    *previous;
+    *image;
 
   MagickBooleanType
     have_mng_structure,
@@ -3996,21 +3981,11 @@ static Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
   mng_info->image=image;
   have_mng_structure=MagickTrue;
 
-  previous=image;
   image=ReadOnePNGImage(mng_info,image_info,exception);
   MngInfoFreeStruct(mng_info,&have_mng_structure);
 
   if (image == (Image *) NULL)
     {
-      if (previous != (Image *) NULL)
-        {
-          if (previous->signature != MagickSignature)
-            ThrowReaderException(CorruptImageError,"CorruptImage");
-
-          (void) CloseBlob(previous);
-          (void) DestroyImageList(previous);
-        }
-
       if (logging != MagickFalse)
         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "exit ReadPNGImage() with error");
@@ -4418,7 +4393,7 @@ static Image *ReadOneJNGImage(MngInfo *mng_info,
 
         /* Copy IDAT header and chunk data to alpha_image->blob */
 
-        if (image_info->ping == MagickFalse)
+        if (alpha_image != NULL && image_info->ping == MagickFalse)
           {
             if (logging != MagickFalse)
               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
@@ -4443,7 +4418,7 @@ static Image *ReadOneJNGImage(MngInfo *mng_info,
       {
         /* Copy chunk data to alpha_image->blob */
 
-        if (image_info->ping == MagickFalse)
+        if (alpha_image != NULL && image_info->ping == MagickFalse)
           {
             if (logging != MagickFalse)
               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
@@ -4758,6 +4733,9 @@ static Image *ReadOneJNGImage(MngInfo *mng_info,
   status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
     2*GetBlobSize(image));
 
+  if (status == MagickFalse)
+    return((Image *) NULL);
+
   if (logging != MagickFalse)
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
       "  exit ReadOneJNGImage()");
@@ -4890,8 +4868,7 @@ static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
     page_geometry[MaxTextExtent];
 
   Image
-    *image,
-    *previous;
+    *image;
 
   MagickBooleanType
     logging,
@@ -5082,7 +5059,10 @@ static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
            type[0],type[1],type[2],type[3],(double) length);
 
         if (length > PNG_UINT_31_MAX)
-          status=MagickFalse;
+          {
+            status=MagickFalse;
+            break;
+          }
 
         if (count == 0)
           ThrowReaderException(CorruptImageError,"CorruptImage");
@@ -5588,7 +5568,7 @@ static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
                         else
                           frame_timeout=PNG_UINT_31_MAX;
 
-                        if (change_delay == 2)
+                        if (change_timeout == 2)
                           default_frame_timeout=frame_timeout;
 
                         p+=4;
@@ -5683,6 +5663,7 @@ static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
             chunk=(unsigned char *) RelinquishMagickMemory(chunk);
             continue;
           }
+
         if (memcmp(type,mng_CLIP,4) == 0)
           {
             unsigned int
@@ -5692,24 +5673,31 @@ static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
             /*
               Read CLIP.
             */
-            first_object=(p[0] << 8) | p[1];
-            last_object=(p[2] << 8) | p[3];
+            if (length > 3)
+              {
+                first_object=(p[0] << 8) | p[1];
+                last_object=(p[2] << 8) | p[3];
+                p+=4;
 
-            for (i=(int) first_object; i <= (int) last_object; i++)
-            {
-              if (mng_info->exists[i] && !mng_info->frozen[i])
+                for (i=(int) first_object; i <= (int) last_object; i++)
                 {
-                  MngBox
-                    box;
+                  if (mng_info->exists[i] && !mng_info->frozen[i])
+                    {
+                      MngBox
+                        box;
 
-                  box=mng_info->object_clip[i];
-                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
+                      box=mng_info->object_clip[i];
+                      if ((p-chunk) < (ssize_t) (length-17))
+                        mng_info->object_clip[i]=
+                           mng_read_box(box,(char) p[0],&p[1]);
+                    }
                 }
-            }
 
+              }
             chunk=(unsigned char *) RelinquishMagickMemory(chunk);
             continue;
           }
+
         if (memcmp(type,mng_SAVE,4) == 0)
           {
             for (i=1; i < MNG_MAX_OBJECTS; i++)
@@ -5764,24 +5752,30 @@ static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
 
             /* read MOVE */
 
-            first_object=(p[0] << 8) | p[1];
-            last_object=(p[2] << 8) | p[3];
-            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
+            if (length > 3)
             {
-              if (mng_info->exists[i] && !mng_info->frozen[i])
-                {
-                  MngPair
-                    new_pair;
+              first_object=(p[0] << 8) | p[1];
+              last_object=(p[2] << 8) | p[3];
+              p+=4;
 
-                  MngPair
-                    old_pair;
+              for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
+              {
+                if (mng_info->exists[i] && !mng_info->frozen[i] &&
+                    (p-chunk) < (ssize_t) (length-8))
+                  {
+                    MngPair
+                      new_pair;
 
-                  old_pair.a=mng_info->x_off[i];
-                  old_pair.b=mng_info->y_off[i];
-                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
-                  mng_info->x_off[i]=new_pair.a;
-                  mng_info->y_off[i]=new_pair.b;
-                }
+                    MngPair
+                      old_pair;
+
+                    old_pair.a=mng_info->x_off[i];
+                    old_pair.b=mng_info->y_off[i];
+                    new_pair=mng_read_pair(old_pair,(int) p[0],&p[1]);
+                    mng_info->x_off[i]=new_pair.a;
+                    mng_info->y_off[i]=new_pair.b;
+                  }
+              }
             }
 
             chunk=(unsigned char *) RelinquishMagickMemory(chunk);
@@ -5791,84 +5785,91 @@ static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
         if (memcmp(type,mng_LOOP,4) == 0)
           {
             ssize_t loop_iters=1;
-            loop_level=chunk[0];
-            mng_info->loop_active[loop_level]=1;  /* mark loop active */
+            if (length > 4)
+              {
+                loop_level=chunk[0];
+                mng_info->loop_active[loop_level]=1;  /* mark loop active */
 
-            /* Record starting point.  */
-            loop_iters=mng_get_long(&chunk[1]);
+                /* Record starting point.  */
+                loop_iters=mng_get_long(&chunk[1]);
 
-            if (logging != MagickFalse)
-              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
-                (double) loop_iters);
+                if (logging != MagickFalse)
+                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                    "  LOOP level %.20g has %.20g iterations ",
+                    (double) loop_level, (double) loop_iters);
 
-            if (loop_iters == 0)
-              skipping_loop=loop_level;
+                if (loop_iters == 0)
+                  skipping_loop=loop_level;
 
-            else
-              {
-                mng_info->loop_jump[loop_level]=TellBlob(image);
-                mng_info->loop_count[loop_level]=loop_iters;
-              }
+                else
+                  {
+                    mng_info->loop_jump[loop_level]=TellBlob(image);
+                    mng_info->loop_count[loop_level]=loop_iters;
+                  }
 
-            mng_info->loop_iteration[loop_level]=0;
+                mng_info->loop_iteration[loop_level]=0;
+              }
             chunk=(unsigned char *) RelinquishMagickMemory(chunk);
             continue;
           }
 
         if (memcmp(type,mng_ENDL,4) == 0)
           {
-            loop_level=chunk[0];
-
-            if (skipping_loop > 0)
+            if (length > 0)
               {
-                if (skipping_loop == loop_level)
+                loop_level=chunk[0];
+
+                if (skipping_loop > 0)
                   {
-                    /*
-                      Found end of zero-iteration loop.
-                    */
-                    skipping_loop=(-1);
-                    mng_info->loop_active[loop_level]=0;
+                    if (skipping_loop == loop_level)
+                      {
+                        /*
+                          Found end of zero-iteration loop.
+                        */
+                        skipping_loop=(-1);
+                        mng_info->loop_active[loop_level]=0;
+                      }
                   }
-              }
 
-            else
-              {
-                if (mng_info->loop_active[loop_level] == 1)
+                else
                   {
-                    mng_info->loop_count[loop_level]--;
-                    mng_info->loop_iteration[loop_level]++;
-
-                    if (logging != MagickFalse)
-                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
-                        (double) loop_level,(double)
-                        mng_info->loop_count[loop_level]);
-
-                    if (mng_info->loop_count[loop_level] != 0)
+                    if (mng_info->loop_active[loop_level] == 1)
                       {
-                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
-                          SEEK_SET);
+                        mng_info->loop_count[loop_level]--;
+                        mng_info->loop_iteration[loop_level]++;
 
-                        if (offset < 0)
-                          ThrowReaderException(CorruptImageError,
-                            "ImproperImageHeader");
-                      }
+                        if (logging != MagickFalse)
+                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          "  ENDL: LOOP level %.20g has %.20g remaining iters ",
+                            (double) loop_level,(double)
+                            mng_info->loop_count[loop_level]);
 
-                    else
-                      {
-                        short
-                          last_level;
+                        if (mng_info->loop_count[loop_level] != 0)
+                          {
+                            offset=
+                              SeekBlob(image,mng_info->loop_jump[loop_level],
+                              SEEK_SET);
 
-                        /*
-                          Finished loop.
-                        */
-                        mng_info->loop_active[loop_level]=0;
-                        last_level=(-1);
-                        for (i=0; i < loop_level; i++)
-                          if (mng_info->loop_active[i] == 1)
-                            last_level=(short) i;
-                        loop_level=last_level;
+                            if (offset < 0)
+                              ThrowReaderException(CorruptImageError,
+                                "ImproperImageHeader");
+                          }
+
+                        else
+                          {
+                            short
+                              last_level;
+
+                            /*
+                              Finished loop.
+                            */
+                            mng_info->loop_active[loop_level]=0;
+                            last_level=(-1);
+                            for (i=0; i < loop_level; i++)
+                              if (mng_info->loop_active[i] == 1)
+                                last_level=(short) i;
+                            loop_level=last_level;
+                          }
                       }
                   }
               }
@@ -6351,7 +6352,6 @@ static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
           ThrowReaderException(CorruptImageError,"ImproperImageHeader");
       }
 
-    previous=image;
     mng_info->image=image;
     mng_info->mng_type=mng_type;
     mng_info->object_id=object_id;
@@ -6366,11 +6366,9 @@ static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
 
     if (image == (Image *) NULL)
       {
-        if (IsImageObject(previous) != MagickFalse)
-          {
-            (void) DestroyImageList(previous);
-            (void) CloseBlob(previous);
-          }
+        if (logging != MagickFalse)
+          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+            "exit ReadJNGImage() with error");
 
         MngInfoFreeStruct(mng_info,&have_mng_structure);
         return((Image *) NULL);
@@ -6568,7 +6566,7 @@ static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     "    Magnify the rows to %.20g",(double) large_image->rows);
                 m=(ssize_t) mng_info->magn_mt;
                 yy=0;
-                length=(size_t) image->columns*GetPixelChannels(image);
+                length=(size_t) GetPixelChannels(image)*image->columns;
                 next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
                 prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
 
@@ -7376,8 +7374,8 @@ ModuleExport size_t RegisterPNGImage(void)
     }
 #endif
 
-  entry=SetMagickInfo("MNG");
-  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
+  entry=AcquireMagickInfo("PNG","MNG","Multiple-image Network Graphics");
+  entry->flags|=CoderSeekableStreamFlag;  /* To do: eliminate this. */
 
 #if defined(MAGICKCORE_PNG_DELEGATE)
   entry->decoder=(DecodeImageHandler *) ReadMNGImage;
@@ -7385,17 +7383,15 @@ ModuleExport size_t RegisterPNGImage(void)
 #endif
 
   entry->magick=(IsImageFormatHandler *) IsMNG;
-  entry->description=ConstantString("Multiple-image Network Graphics");
 
   if (*version != '\0')
     entry->version=ConstantString(version);
 
   entry->mime_type=ConstantString("video/x-mng");
-  entry->module=ConstantString("PNG");
   entry->note=ConstantString(MNGNote);
   (void) RegisterMagickInfo(entry);
 
-  entry=SetMagickInfo("PNG");
+  entry=AcquireMagickInfo("PNG","PNG","Portable Network Graphics");
 
 #if defined(MAGICKCORE_PNG_DELEGATE)
   entry->decoder=(DecodeImageHandler *) ReadPNGImage;
@@ -7403,10 +7399,8 @@ ModuleExport size_t RegisterPNGImage(void)
 #endif
 
   entry->magick=(IsImageFormatHandler *) IsPNG;
-  entry->adjoin=MagickFalse;
-  entry->description=ConstantString("Portable Network Graphics");
+  entry->flags^=CoderAdjoinFlag;
   entry->mime_type=ConstantString("image/png");
-  entry->module=ConstantString("PNG");
 
   if (*version != '\0')
     entry->version=ConstantString(version);
@@ -7414,7 +7408,8 @@ ModuleExport size_t RegisterPNGImage(void)
   entry->note=ConstantString(PNGNote);
   (void) RegisterMagickInfo(entry);
 
-  entry=SetMagickInfo("PNG8");
+  entry=AcquireMagickInfo("PNG","PNG8",
+    "8-bit indexed with optional binary transparency");
 
 #if defined(MAGICKCORE_PNG_DELEGATE)
   entry->decoder=(DecodeImageHandler *) ReadPNGImage;
@@ -7422,14 +7417,12 @@ ModuleExport size_t RegisterPNGImage(void)
 #endif
 
   entry->magick=(IsImageFormatHandler *) IsPNG;
-  entry->adjoin=MagickFalse;
-  entry->description=ConstantString(
-            "8-bit indexed with optional binary transparency");
+  entry->flags^=CoderAdjoinFlag;
   entry->mime_type=ConstantString("image/png");
-  entry->module=ConstantString("PNG");
   (void) RegisterMagickInfo(entry);
 
-  entry=SetMagickInfo("PNG24");
+  entry=AcquireMagickInfo("PNG","PNG24",
+    "opaque or binary transparent 24-bit RGB");
   *version='\0';
 
 #if defined(ZLIB_VERSION)
@@ -7452,13 +7445,11 @@ ModuleExport size_t RegisterPNGImage(void)
 #endif
 
   entry->magick=(IsImageFormatHandler *) IsPNG;
-  entry->adjoin=MagickFalse;
-  entry->description=ConstantString("opaque or binary transparent 24-bit RGB");
+  entry->flags^=CoderAdjoinFlag;
   entry->mime_type=ConstantString("image/png");
-  entry->module=ConstantString("PNG");
   (void) RegisterMagickInfo(entry);
 
-  entry=SetMagickInfo("PNG32");
+  entry=AcquireMagickInfo("PNG","PNG32","opaque or transparent 32-bit RGBA");
 
 #if defined(MAGICKCORE_PNG_DELEGATE)
   entry->decoder=(DecodeImageHandler *) ReadPNGImage;
@@ -7466,13 +7457,12 @@ ModuleExport size_t RegisterPNGImage(void)
 #endif
 
   entry->magick=(IsImageFormatHandler *) IsPNG;
-  entry->adjoin=MagickFalse;
-  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
+  entry->flags^=CoderAdjoinFlag;
   entry->mime_type=ConstantString("image/png");
-  entry->module=ConstantString("PNG");
   (void) RegisterMagickInfo(entry);
 
-  entry=SetMagickInfo("PNG48");
+  entry=AcquireMagickInfo("PNG","PNG48",
+    "opaque or binary transparent 48-bit RGB");
 
 #if defined(MAGICKCORE_PNG_DELEGATE)
   entry->decoder=(DecodeImageHandler *) ReadPNGImage;
@@ -7480,13 +7470,11 @@ ModuleExport size_t RegisterPNGImage(void)
 #endif
 
   entry->magick=(IsImageFormatHandler *) IsPNG;
-  entry->adjoin=MagickFalse;
-  entry->description=ConstantString("opaque or binary transparent 48-bit RGB");
+  entry->flags^=CoderAdjoinFlag;
   entry->mime_type=ConstantString("image/png");
-  entry->module=ConstantString("PNG");
   (void) RegisterMagickInfo(entry);
 
-  entry=SetMagickInfo("PNG64");
+  entry=AcquireMagickInfo("PNG","PNG64","opaque or transparent 64-bit RGBA");
 
 #if defined(MAGICKCORE_PNG_DELEGATE)
   entry->decoder=(DecodeImageHandler *) ReadPNGImage;
@@ -7494,13 +7482,12 @@ ModuleExport size_t RegisterPNGImage(void)
 #endif
 
   entry->magick=(IsImageFormatHandler *) IsPNG;
-  entry->adjoin=MagickFalse;
-  entry->description=ConstantString("opaque or transparent 64-bit RGBA");
+  entry->flags^=CoderAdjoinFlag;
   entry->mime_type=ConstantString("image/png");
-  entry->module=ConstantString("PNG");
   (void) RegisterMagickInfo(entry);
 
-  entry=SetMagickInfo("PNG00");
+  entry=AcquireMagickInfo("PNG","PNG00",
+    "PNG inheriting bit-depth and color-type from original");
 
 #if defined(MAGICKCORE_PNG_DELEGATE)
   entry->decoder=(DecodeImageHandler *) ReadPNGImage;
@@ -7508,14 +7495,11 @@ ModuleExport size_t RegisterPNGImage(void)
 #endif
 
   entry->magick=(IsImageFormatHandler *) IsPNG;
-  entry->adjoin=MagickFalse;
-  entry->description=ConstantString(
-    "PNG inheriting bit-depth and color-type from original");
+  entry->flags^=CoderAdjoinFlag;
   entry->mime_type=ConstantString("image/png");
-  entry->module=ConstantString("PNG");
   (void) RegisterMagickInfo(entry);
 
-  entry=SetMagickInfo("JNG");
+  entry=AcquireMagickInfo("PNG","JNG","JPEG Network Graphics");
 
 #if defined(JNG_SUPPORTED)
 #if defined(MAGICKCORE_PNG_DELEGATE)
@@ -7525,10 +7509,8 @@ ModuleExport size_t RegisterPNGImage(void)
 #endif
 
   entry->magick=(IsImageFormatHandler *) IsJNG;
-  entry->adjoin=MagickFalse;
-  entry->description=ConstantString("JPEG Network Graphics");
+  entry->flags^=CoderAdjoinFlag;
   entry->mime_type=ConstantString("image/x-jng");
-  entry->module=ConstantString("PNG");
   entry->note=ConstantString(JNGNote);
   (void) RegisterMagickInfo(entry);
 
@@ -8943,7 +8925,7 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
           {
               if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
                 {
-                  SetPixelInfoPixel(image,&image->background_color,r);
+                  SetPixelViaPixelInfo(image,&image->background_color,r);
                   SetPixelAlpha(image,TransparentAlpha,r);
                 }
               else
@@ -9680,14 +9662,14 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
               image_matte=MagickFalse;
             }
 
-          if (image_info->type == TrueColorMatteType)
+          if (image_info->type == TrueColorAlphaType)
             {
               ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
               image_matte=MagickTrue;
             }
 
           if (image_info->type == PaletteType ||
-              image_info->type == PaletteMatteType)
+              image_info->type == PaletteAlphaType)
             ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
 
           if (mng_info->write_png_colortype == 0 &&
@@ -9852,7 +9834,7 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
                 (ScaleQuantumToShort(image->colormap[0].blue) & mask);
 
               ping_trans_color.gray=(png_uint_16)
-                (ScaleQuantumToShort(GetPixelInfoIntensity(
+                (ScaleQuantumToShort(GetPixelInfoIntensity(image,
                    image->colormap)) & mask);
 
               ping_trans_color.index=(png_byte) 0;
@@ -10122,7 +10104,7 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
          {
 
          ping_background.gray=(png_uint_16) ((maxval/65535.)*
-           (ScaleQuantumToShort(((GetPixelInfoIntensity(
+           (ScaleQuantumToShort(((GetPixelInfoIntensity(image,
            &image->background_color))) +.5)));
 
          if (logging != MagickFalse)
@@ -10500,7 +10482,7 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
                  {
                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                           "  Setting up iCCP chunk");
-    
+
                        png_set_iCCP(ping,ping_info,(png_charp) name,0,
 #if (PNG_LIBPNG_VER < 10500)
                          (png_charp) GetStringInfoDatum(profile),
@@ -10701,7 +10683,7 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
           write_tIME_chunk(image,ping,ping_info,timestamp,exception);
     }
 #endif
-  
+
   if (mng_info->need_blob != MagickFalse)
   {
     if (OpenBlob(image_info,image,WriteBinaryBlobMode,exception) ==
@@ -10888,13 +10870,14 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
                 "    Writing row of pixels (1)");
 
           png_write_row(ping,ping_pixels);
+
+          status=SetImageProgress(image,LoadImageTag,
+              (MagickOffsetType) (pass * image->rows + y),
+              num_passes * image->rows);
+
+          if (status == MagickFalse)
+            break;
         }
-        if (image->previous == (Image *) NULL)
-          {
-            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
-            if (status == MagickFalse)
-              break;
-          }
       }
     }
 
@@ -10949,13 +10932,13 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
                   "    Writing row of pixels (2)");
 
             png_write_row(ping,ping_pixels);
-          }
 
-          if (image->previous == (Image *) NULL)
-            {
-              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
-              if (status == MagickFalse)
-                break;
+            status=SetImageProgress(image,LoadImageTag,
+              (MagickOffsetType) (pass * image->rows + y),
+              num_passes * image->rows);
+
+            if (status == MagickFalse)
+              break;
             }
           }
         }
@@ -11016,6 +10999,13 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
                       "    Writing row of pixels (3)");
 
                 png_write_row(ping,ping_pixels);
+
+                status=SetImageProgress(image,LoadImageTag,
+                  (MagickOffsetType) (pass * image->rows + y),
+                  num_passes * image->rows);
+
+                if (status == MagickFalse)
+                  break;
               }
             }
 
@@ -11083,15 +11073,15 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
                     }
                   }
                 png_write_row(ping,ping_pixels);
-              }
-            }
 
-            if (image->previous == (Image *) NULL)
-              {
-                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
+                status=SetImageProgress(image,LoadImageTag,
+                  (MagickOffsetType) (pass * image->rows + y),
+                  num_passes * image->rows);
+
                 if (status == MagickFalse)
                   break;
               }
+            }
           }
         }
     }
@@ -11544,47 +11534,47 @@ static MagickBooleanType WritePNGImage(const ImageInfo *image_info,
         {
           /* Retrieve png:IHDR.bit-depth-orig and png:IHDR.color-type-orig. */
           value=GetImageProperty(image,"png:IHDR.bit-depth-orig",exception);
-    
+
           if (value != (char *) NULL)
             {
               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "  png00 inherited bit depth=%s",value);
-    
+
               if (LocaleCompare(value,"1") == 0)
                 mng_info->write_png_depth = 1;
-    
+
               else if (LocaleCompare(value,"2") == 0)
                 mng_info->write_png_depth = 2;
-    
+
               else if (LocaleCompare(value,"4") == 0)
                 mng_info->write_png_depth = 4;
-    
+
               else if (LocaleCompare(value,"8") == 0)
                 mng_info->write_png_depth = 8;
-    
+
               else if (LocaleCompare(value,"16") == 0)
                 mng_info->write_png_depth = 16;
             }
-    
+
           value=GetImageProperty(image,"png:IHDR.color-type-orig",exception);
-    
+
           if (value != (char *) NULL)
             {
               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "  png00 inherited color type=%s",value);
-    
+
               if (LocaleCompare(value,"0") == 0)
                 mng_info->write_png_colortype = 1;
-    
+
               else if (LocaleCompare(value,"2") == 0)
                 mng_info->write_png_colortype = 3;
-    
+
               else if (LocaleCompare(value,"3") == 0)
                 mng_info->write_png_colortype = 4;
-    
+
               else if (LocaleCompare(value,"4") == 0)
                 mng_info->write_png_colortype = 5;
-    
+
               else if (LocaleCompare(value,"6") == 0)
                 mng_info->write_png_colortype = 7;
             }
@@ -11605,7 +11595,7 @@ static MagickBooleanType WritePNGImage(const ImageInfo *image_info,
       image->depth = 8;
 
       if (image->alpha_trait != UndefinedPixelTrait)
-        (void) SetImageType(image,TrueColorMatteType,exception);
+        (void) SetImageType(image,TrueColorAlphaType,exception);
 
       else
         (void) SetImageType(image,TrueColorType,exception);
@@ -11620,7 +11610,7 @@ static MagickBooleanType WritePNGImage(const ImageInfo *image_info,
       image->depth = 8;
       image->alpha_trait = BlendPixelTrait;
 
-      (void) SetImageType(image,TrueColorMatteType,exception);
+      (void) SetImageType(image,TrueColorAlphaType,exception);
       (void) SyncImage(image,exception);
     }
 
@@ -11631,7 +11621,7 @@ static MagickBooleanType WritePNGImage(const ImageInfo *image_info,
       image->depth = 16;
 
       if (image->alpha_trait != UndefinedPixelTrait)
-        (void) SetImageType(image,TrueColorMatteType,exception);
+        (void) SetImageType(image,TrueColorAlphaType,exception);
 
       else
         (void) SetImageType(image,TrueColorType,exception);
@@ -11646,7 +11636,7 @@ static MagickBooleanType WritePNGImage(const ImageInfo *image_info,
       image->depth = 16;
       image->alpha_trait = BlendPixelTrait;
 
-      (void) SetImageType(image,TrueColorMatteType,exception);
+      (void) SetImageType(image,TrueColorAlphaType,exception);
       (void) SyncImage(image,exception);
     }
 
@@ -12172,10 +12162,12 @@ static MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
   blob=(unsigned char *) NULL;
   jpeg_image=(Image *) NULL;
   jpeg_image_info=(ImageInfo *) NULL;
+  length=0;
 
   status=MagickTrue;
-  transparent=image_info->type==GrayscaleMatteType ||
-     image_info->type==TrueColorMatteType || image->alpha_trait != UndefinedPixelTrait;
+  transparent=image_info->type==GrayscaleAlphaType ||
+     image_info->type==TrueColorAlphaType ||
+     image->alpha_trait != UndefinedPixelTrait;
 
   jng_alpha_sample_depth = 0;
 
@@ -12231,8 +12223,8 @@ static MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
   /* To do: check bit depth of PNG alpha channel */
 
   /* Check if image is grayscale. */
-  if (image_info->type != TrueColorMatteType && image_info->type !=
-    TrueColorType && IsImageGray(image,exception))
+  if (image_info->type != TrueColorAlphaType && image_info->type !=
+    TrueColorType && SetImageGray(image,exception))
     jng_color_type-=2;
 
   if (logging != MagickFalse)
@@ -12262,6 +12254,9 @@ static MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
           /* Encode alpha as a grayscale PNG blob */
           status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
             exception);
+          if (status == MagickFalse)
+            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
           if (logging != MagickFalse)
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
               "  Creating PNG blob.");
@@ -12287,6 +12282,9 @@ static MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
 
           status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
             exception);
+          if (status == MagickFalse)
+            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
 
           (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
           (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
@@ -12535,7 +12533,6 @@ static MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
        (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
     }
 
-
   if (transparent != 0)
     {
       if (jng_alpha_compression_method==0)
@@ -12579,7 +12576,7 @@ static MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
             p+=(8+len);
           }
         }
-      else
+      else if (length != 0)
         {
           /* Write JDAA chunk header */
           if (logging != MagickFalse)
@@ -12626,6 +12623,9 @@ static MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
       "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
       (double) jpeg_image->rows);
 
+  if (status == MagickFalse)
+    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+
   if (jng_color_type == 8 || jng_color_type == 12)
     jpeg_image_info->type=GrayscaleType;
 
@@ -13010,7 +13010,7 @@ static MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
 
         if (need_local_plte == 0)
           {
-            if (IsImageGray(image,exception) == MagickFalse)
+            if (SetImageGray(image,exception) == MagickFalse)
               all_images_are_gray=MagickFalse;
             mng_info->equal_palettes=PalettesAreEqual(image,next_image);
             if (use_global_plte == 0)