/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%                            PPPP   N   N   GGGG                              %
%                            P   P  NN  N  G                                  %
%                            PPPP   N N N  G  GG                              %
%                            P      N  NN  G   G                              %
%                            P      N   N   GGG                               %
%                                                                             %
%                                                                             %
%              Read/Write Portable Network Graphics Image Format              %
%                                                                             %
%                              Software Design                                %
%                                John Cristy                                  %
%                           Glenn Randers-Pehrson                             %
%                               November 1997                                 %
%                                                                             %
%                                                                             %
%  Copyright 1999-2010 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  %
%  obtain a copy of the License at                                            %
%                                                                             %
%    http://www.imagemagick.org/script/license.php                            %
%                                                                             %
%  Unless required by applicable law or agreed to in writing, software        %
%  distributed under the License is distributed on an "AS IS" BASIS,          %
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
%  See the License for the specific language governing permissions and        %
%  limitations under the License.                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
*/


/*
  Include declarations.
*/
#include "magick/studio.h"
#include "magick/attribute.h"
#include "magick/blob.h"
#include "magick/blob-private.h"
#include "magick/cache.h"
#include "magick/color.h"
#include "magick/color-private.h"
#include "magick/colormap.h"
#include "magick/colorspace.h"
#include "magick/constitute.h"
#include "magick/enhance.h"
#include "magick/exception.h"
#include "magick/exception-private.h"
#include "magick/geometry.h"
#include "magick/histogram.h"
#include "magick/image.h"
#include "magick/image-private.h"
#include "magick/layer.h"
#include "magick/list.h"
#include "magick/log.h"
#include "magick/magick.h"
#include "magick/memory_.h"
#include "magick/module.h"
#include "magick/monitor.h"
#include "magick/monitor-private.h"
#include "magick/option.h"
#include "magick/quantum-private.h"
#include "magick/profile.h"
#include "magick/property.h"
#include "magick/quantize.h"
#include "magick/resource_.h"
#include "magick/semaphore.h"
#include "magick/quantum-private.h"
#include "magick/static.h"
#include "magick/statistic.h"
#include "magick/string_.h"
#include "magick/string-private.h"
#include "magick/transform.h"
#include "magick/utility.h"
#if defined(MAGICKCORE_PNG_DELEGATE)

/* Suppress libpng pedantic warnings that were added in
 * libpng-1.2.41 and libpng-1.4.0.  If you are working on
 * migration to libpng-1.5, remove these defines and then
 * fix any code that generates warnings.
 */
/* #define PNG_DEPRECATED   Use of this function is deprecated */
/* #define PNG_USE_RESULT   The result of this function must be checked */
/* #define PNG_NORETURN     This function does not return */
/* #define PNG_ALLOCATED    The result of the function is new memory */
/* #define PNG_DEPSTRUCT    Access to this struct member is deprecated */

#include "png.h"
#include "zlib.h"

/* ImageMagick differences */
#define first_scene scene

#if PNG_LIBPNG_VER > 10011
/*
  Optional declarations. Define or undefine them as you like.
*/
/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */

/*
  Features under construction.  Define these to work on them.
*/
#undef MNG_OBJECT_BUFFERS
#undef MNG_BASI_SUPPORTED
#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
#define PNG_BUILD_PALETTE   /* This works as of 5.4.3. */
#define PNG_SORT_PALETTE    /* This works as of 5.4.0. */
#if defined(MAGICKCORE_JPEG_DELEGATE)
#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
#endif
#if !defined(RGBColorMatchExact)
#define IsPNGColorEqual(color,target) \
   (((color).red == (target).red) && \
    ((color).green == (target).green) && \
    ((color).blue == (target).blue))
#endif

/*
  Establish thread safety.
  setjmp/longjmp is claimed to be safe on these platforms:
  setjmp/longjmp is alleged to be unsafe on these platforms:
*/
#ifndef SETJMP_IS_THREAD_SAFE
#define PNG_SETJMP_NOT_THREAD_SAFE
#endif

#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
static SemaphoreInfo
  *png_semaphore = (SemaphoreInfo *) NULL;
#endif

/*
  This temporary until I set up malloc'ed object attributes array.
  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
  waste more memory.
*/
#define MNG_MAX_OBJECTS 256

/*
  If this not defined, spec is interpreted strictly.  If it is
  defined, an attempt will be made to recover from some errors,
  including
      o global PLTE too short
*/
#undef MNG_LOOSE

/*
  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
  will be enabled by default in libpng-1.2.0.
*/
#ifdef PNG_MNG_FEATURES_SUPPORTED
#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
#    define PNG_READ_EMPTY_PLTE_SUPPORTED
#  endif
#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
#  endif
#endif

/*
  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
  This macro is only defined in libpng-1.0.3 and later.
  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
*/
#ifndef PNG_UINT_31_MAX
#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
#endif

/*
  Constant strings for known chunk types.  If you need to add a chunk,
  add a string holding the name here.   To make the code more
  portable, we use ASCII numbers like this, not characters.
*/

static png_byte FARDATA mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
static png_byte FARDATA mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
static png_byte FARDATA mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
static png_byte FARDATA mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
static png_byte FARDATA mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
static png_byte FARDATA mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
static png_byte FARDATA mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
static png_byte FARDATA mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
static png_byte FARDATA mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
static png_byte FARDATA mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
static png_byte FARDATA mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
static png_byte FARDATA mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
static png_byte FARDATA mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
static png_byte FARDATA mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
static png_byte FARDATA mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
static png_byte FARDATA mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
static png_byte FARDATA mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
static png_byte FARDATA mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
static png_byte FARDATA mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
static png_byte FARDATA mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
static png_byte FARDATA mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
static png_byte FARDATA mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
static png_byte FARDATA mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
static png_byte FARDATA mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
static png_byte FARDATA mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
static png_byte FARDATA mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
static png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
static png_byte FARDATA mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
static png_byte FARDATA mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
static png_byte FARDATA mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
static png_byte FARDATA mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
static png_byte FARDATA mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
static png_byte FARDATA mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
static png_byte FARDATA mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};

#if defined(JNG_SUPPORTED)
static png_byte FARDATA mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
static png_byte FARDATA mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
static png_byte FARDATA mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
static png_byte FARDATA mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
static png_byte FARDATA mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
static png_byte FARDATA mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
#endif

/*
Other known chunks that are not yet supported by ImageMagick:
static png_byte FARDATA mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
static png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
static png_byte FARDATA mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
static png_byte FARDATA mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
static png_byte FARDATA mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
static png_byte FARDATA mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
static png_byte FARDATA mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
static png_byte FARDATA mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
*/

typedef struct _UShortPixelPacket
{
  unsigned short
    red,
    green,
    blue,
    opacity,
    index;
} UShortPixelPacket;

typedef struct _MngBox
{
  long
    left,
    right,
    top,
    bottom;
} MngBox;

typedef struct _MngPair
{
  volatile long
    a,
    b;
} MngPair;

#ifdef MNG_OBJECT_BUFFERS
typedef struct _MngBuffer
{

  size_t
    height,
    width;

  Image
    *image;

  png_color
    plte[256];

  int
    reference_count;

  unsigned char
    alpha_sample_depth,
    compression_method,
    color_type,
    concrete,
    filter_method,
    frozen,
    image_type,
    interlace_method,
    pixel_sample_depth,
    plte_length,
    sample_depth,
    viewable;
} MngBuffer;
#endif

typedef struct _MngInfo
{

#ifdef MNG_OBJECT_BUFFERS
  MngBuffer
    *ob[MNG_MAX_OBJECTS];
#endif

  Image *
    image;

  RectangleInfo
    page;

  int
    adjoin,
#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
    bytes_in_read_buffer,
    found_empty_plte,
#endif
    equal_backgrounds,
    equal_chrms,
    equal_gammas,
#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
    defined(PNG_MNG_FEATURES_SUPPORTED)
    equal_palettes,
#endif
    equal_physs,
    equal_srgbs,
    framing_mode,
    have_global_bkgd,
    have_global_chrm,
    have_global_gama,
    have_global_phys,
    have_global_sbit,
    have_global_srgb,
    have_saved_bkgd_index,
    have_write_global_chrm,
    have_write_global_gama,
    have_write_global_plte,
    have_write_global_srgb,
    need_fram,
    object_id,
    old_framing_mode,
    optimize,
    saved_bkgd_index;

  int
    new_number_colors;

  ssize_t
    image_found,
    loop_count[256],
    loop_iteration[256],
    scenes_found,
    x_off[MNG_MAX_OBJECTS],
    y_off[MNG_MAX_OBJECTS];

  MngBox
    clip,
    frame,
    image_box,
    object_clip[MNG_MAX_OBJECTS];

  unsigned char
    /* These flags could be combined into one byte */
    exists[MNG_MAX_OBJECTS],
    frozen[MNG_MAX_OBJECTS],
    loop_active[256],
    invisible[MNG_MAX_OBJECTS],
    viewable[MNG_MAX_OBJECTS];

  MagickOffsetType
    loop_jump[256];

  png_colorp
    global_plte;

  png_color_8
    global_sbit;

  png_byte
#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
    read_buffer[8],
#endif
    global_trns[256];

  float
    global_gamma;

  ChromaticityInfo
    global_chrm;

  RenderingIntent
    global_srgb_intent;

  unsigned int
    delay,
    global_plte_length,
    global_trns_length,
    global_x_pixels_per_unit,
    global_y_pixels_per_unit,
    mng_width,
    mng_height,
    ticks_per_second;

  unsigned int
    IsPalette,
    global_phys_unit_type,
    basi_warning,
    clon_warning,
    dhdr_warning,
    jhdr_warning,
    magn_warning,
    past_warning,
    phyg_warning,
    phys_warning,
    sbit_warning,
    show_warning,
    mng_type,
    write_mng,
    write_png_colortype,
    write_png_depth,
    write_png8,
    write_png24,
    write_png32;

#ifdef MNG_BASI_SUPPORTED
  size_t
    basi_width,
    basi_height;

  unsigned int
    basi_depth,
    basi_color_type,
    basi_compression_method,
    basi_filter_type,
    basi_interlace_method,
    basi_red,
    basi_green,
    basi_blue,
    basi_alpha,
    basi_viewable;
#endif

  png_uint_16
    magn_first,
    magn_last,
    magn_mb,
    magn_ml,
    magn_mr,
    magn_mt,
    magn_mx,
    magn_my,
    magn_methx,
    magn_methy;

  PixelPacket
    mng_global_bkgd;

} MngInfo;
#endif /* VER */

/*
  Forward declarations.
*/
static MagickBooleanType
  WritePNGImage(const ImageInfo *,Image *);
static MagickBooleanType
  WriteMNGImage(const ImageInfo *,Image *);
#if defined(JNG_SUPPORTED)
static MagickBooleanType
  WriteJNGImage(const ImageInfo *,Image *);
#endif

static int
PNG_RenderingIntent_from_Magick_RenderingIntent(const RenderingIntent intent)
{  
  switch (intent)
  {
    case PerceptualIntent:
       return 0;
    case RelativeIntent:
       return 1;
    case SaturationIntent:
       return 2;
    case AbsoluteIntent:
       return 3;
    default:
       return -1;
  }
}

static RenderingIntent
PNG_RenderingIntent_to_Magick_RenderingIntent(const int png_intent)
{  
  switch (png_intent)
  {
    case 0:
      return PerceptualIntent;
    case 1:
      return RelativeIntent;
    case 2:
      return SaturationIntent;
    case 3:
      return AbsoluteIntent;
    default:
      return UndefinedIntent;
    }
}

static inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
{
  if (x > y)
    return(x);
  return(y);
}
static inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
{
  if (x < y)
    return(x);
  return(y);
}

#if PNG_LIBPNG_VER > 10011
#if defined(PNG_SORT_PALETTE)
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   C o m p r e s s C o l o r m a p T r a n s F i r s t                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  CompressColormapTransFirst compresses an image colormap removing
%  any duplicate and unused color entries and putting the transparent colors
%  first.  Returns MagickTrue on success, MagickFalse on error.
%
%  The format of the CompressColormapTransFirst method is:
%
%      unsigned int CompressColormapTransFirst(Image *image)
%
%  A description of each parameter follows:
%
%    o image: the address of a structure of type Image.
%      This function updates image->colors and image->colormap.
%
*/
static MagickBooleanType CompressColormapTransFirst(Image *image)
{
  int
    remap_needed,
    k;

  ssize_t
    j,
    new_number_colors,
    number_colors,
    y;

  PixelPacket
    *colormap;

  register const IndexPacket
    *indexes;

  register const PixelPacket
    *p;

  IndexPacket
    top_used;

  register ssize_t
    i,
    x;

  IndexPacket
    *map,
    *opacity;

  unsigned char
    *marker,
    have_transparency;

  /*
    Determine if colormap can be compressed.
  */
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "    CompressColorMapTransFirst %s (%.20g colors)",image->filename,
      (double) image->colors);
  if (image->storage_class != PseudoClass || image->colors > 256 ||
      image->colors < 2)
    {
      if (image->debug != MagickFalse)
        {
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
               "    Could not compress colormap");
          if (image->colors > 256 || image->colors == 0)
            return(MagickFalse);
          else
            return(MagickTrue);
        }
    }
  marker=(unsigned char *) AcquireQuantumMemory(image->colors,sizeof(*marker));
  if (marker == (unsigned char *) NULL)
    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
      image->filename);
  opacity=(IndexPacket *) AcquireQuantumMemory(image->colors,sizeof(*opacity));
  if (opacity == (IndexPacket *) NULL)
    {
      marker=(unsigned char *) RelinquishMagickMemory(marker);
      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
        image->filename);
    }
  /*
    Mark colors that are present.
  */
  number_colors=(ssize_t) image->colors;
  for (i=0; i < number_colors; i++)
  {
    marker[i]=MagickFalse;
    opacity[i]=OpaqueOpacity;
  }
  top_used=0;
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
    if (p == (const PixelPacket *) NULL)
      break;
    indexes=GetVirtualIndexQueue(image);
    if (image->matte != MagickFalse)
      for (x=0; x < (ssize_t) image->columns; x++)
      {
        marker[(int) indexes[x]]=MagickTrue;
        opacity[(int) indexes[x]]=GetOpacityPixelComponent(p);
        if (indexes[x] > top_used)
           top_used=indexes[x];
        p++;
      }
    else
      for (x=0; x < (ssize_t) image->columns; x++)
      {
        marker[(int) indexes[x]]=MagickTrue;
        if (indexes[x] > top_used)
           top_used=indexes[x];
      }
  }

  if (image->matte != MagickFalse)
  {
    /*
      Mark background color, topmost occurrence if more than one.
    */
    for (i=number_colors-1; i; i--)
    {
      if (IsColorEqual(image->colormap+i,&image->background_color))
        {
          marker[i]=MagickTrue;
          break;
        }
    }
  }
  /*
    Unmark duplicates.
  */
  for (i=0; i < number_colors-1; i++)
    if (marker[i])
      {
        for (j=i+1; j < number_colors; j++)
          if ((opacity[i] == opacity[j]) &&
              (IsColorEqual(image->colormap+i,image->colormap+j)))
            marker[j]=MagickFalse;
       }
  /*
    Count colors that still remain.
  */
  have_transparency=MagickFalse;
  new_number_colors=0;
  for (i=0; i < number_colors; i++)
    if (marker[i])
      {
        new_number_colors++;
        if (opacity[i] != OpaqueOpacity)
          have_transparency=MagickTrue;
      }
  if ((!have_transparency || (marker[0] &&
      (opacity[0] == (Quantum) TransparentOpacity)))
      && (new_number_colors == number_colors))
    {
      /*
        No duplicate or unused entries, and transparency-swap not needed.
      */
      marker=(unsigned char *) RelinquishMagickMemory(marker);
      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
      return(MagickTrue);
    }

  remap_needed=MagickFalse;
  if ((ssize_t) top_used >= new_number_colors)
     remap_needed=MagickTrue;

  /*
    Compress colormap.
  */

  colormap=(PixelPacket *) AcquireQuantumMemory(image->colors,
    sizeof(*colormap));
  if (colormap == (PixelPacket *) NULL)
    {
      marker=(unsigned char *) RelinquishMagickMemory(marker);
      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
        image->filename);
    }
  /*
    Eliminate unused colormap entries.
  */
  map=(IndexPacket *) AcquireQuantumMemory((size_t) number_colors,
    sizeof(*map));
  if (map == (IndexPacket *) NULL)
    {
      marker=(unsigned char *) RelinquishMagickMemory(marker);
      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
      colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
        image->filename);
    }
  k=0;
  for (i=0; i < number_colors; i++)
  {
    map[i]=(IndexPacket) k;
    if (marker[i])
      {
        for (j=i+1; j < number_colors; j++)
        {
          if ((opacity[i] == opacity[j]) &&
              (IsColorEqual(image->colormap+i,image->colormap+j)))
            {
               map[j]=(IndexPacket) k;
               marker[j]=MagickFalse;
            }
        }
        k++;
      }
  }
  j=0;
  for (i=0; i < number_colors; i++)
  {
    if (marker[i])
      {
        colormap[j]=image->colormap[i];
        j++;
      }
  }
  if (have_transparency && (opacity[0] != (Quantum) TransparentOpacity))
    {
      /*
        Move the first transparent color to palette entry 0.
      */
      for (i=1; i < number_colors; i++)
      {
        if (marker[i] && opacity[i] == (Quantum) TransparentOpacity)
          {
            PixelPacket
              temp_colormap;

            temp_colormap=colormap[0];
            colormap[0]=colormap[(int) map[i]];
            colormap[(ssize_t) map[i]]=temp_colormap;
            for (j=0; j < number_colors; j++)
            {
              if (map[j] == 0)
                map[j]=map[i];
              else if (map[j] == map[i])
                map[j]=0;
            }
            remap_needed=MagickTrue;
            break;
          }
      }
   }

  opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
  marker=(unsigned char *) RelinquishMagickMemory(marker);

  if (remap_needed)
    {
      ExceptionInfo
        *exception;

      register IndexPacket
        *pixels;

      register PixelPacket
        *q;

      /*
        Remap pixels.
      */
      exception=(&image->exception);
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
        if (q == (PixelPacket *) NULL)
          break;
        pixels=GetAuthenticIndexQueue(image);
        for (x=0; x < (ssize_t) image->columns; x++)
        {
          j=(int) pixels[x];
          pixels[x]=map[j];
        }
        if (SyncAuthenticPixels(image,exception) == MagickFalse)
          break;
      }
      for (i=0; i < new_number_colors; i++)
        image->colormap[i]=colormap[i];
    }
  colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
  image->colors=(size_t) new_number_colors;
  map=(IndexPacket *) RelinquishMagickMemory(map);
  return(MagickTrue);
}
#endif

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   I m a g e I s G r a y                                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
static MagickBooleanType ImageIsGray(Image *image)
{
  register const PixelPacket
    *p;

  register ssize_t
    i,
    x,
    y;

  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);

  if (image->storage_class == PseudoClass)
    {
      for (i=0; i < (ssize_t) image->colors; i++)
        if (IsGray(image->colormap+i) == MagickFalse)
          return(MagickFalse);
      return(MagickTrue);
    }
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
    if (p == (const PixelPacket *) NULL)
      return(MagickFalse);
    for (x=(ssize_t) image->columns-1; x >= 0; x--)
    {
       if (IsGray(p) == MagickFalse)
          return(MagickFalse);
       p++;
    }
  }
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   I m a g e I s M o n o c h r o m e                                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
%   and is more accurate.                                                     %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
static MagickBooleanType ImageIsMonochrome(Image *image)
{
  register const PixelPacket
    *p;

  register ssize_t
    i,
    x,
    y;

  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  if (image->storage_class == PseudoClass)
    {
      for (i=0; i < (ssize_t) image->colors; i++)
      {
        if ((IsGray(image->colormap+i) == MagickFalse) ||
            ((image->colormap[i].red != 0) &&
             (image->colormap[i].red != (Quantum) QuantumRange)))
          return(MagickFalse);
      }
      return(MagickTrue);
    }
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
    if (p == (const PixelPacket *) NULL)
      return(MagickFalse);
    for (x=(ssize_t) image->columns-1; x >= 0; x--)
    {
      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
        return(MagickFalse);
      if (IsGray(p) == MagickFalse)
        return(MagickFalse);
      if ((p->opacity != OpaqueOpacity) &&
          (p->opacity != (Quantum) TransparentOpacity))
        return(MagickFalse);
      p++;
    }
  }
  return(MagickTrue);
}
#endif /* PNG_LIBPNG_VER > 10011 */
#endif /* MAGICKCORE_PNG_DELEGATE */

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   I s M N G                                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  IsMNG() returns MagickTrue if the image format type, identified by the
%  magick string, is MNG.
%
%  The format of the IsMNG method is:
%
%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
%
%  A description of each parameter follows:
%
%    o magick: compare image format pattern against these bytes.
%
%    o length: Specifies the length of the magick string.
%
%
*/
static MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
{
  if (length < 8)
    return(MagickFalse);
  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
    return(MagickTrue);
  return(MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   I s J N G                                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  IsJNG() returns MagickTrue if the image format type, identified by the
%  magick string, is JNG.
%
%  The format of the IsJNG method is:
%
%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
%
%  A description of each parameter follows:
%
%    o magick: compare image format pattern against these bytes.
%
%    o length: Specifies the length of the magick string.
%
%
*/
static MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
{
  if (length < 8)
    return(MagickFalse);
  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
    return(MagickTrue);
  return(MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   I s P N G                                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  IsPNG() returns MagickTrue if the image format type, identified by the
%  magick string, is PNG.
%
%  The format of the IsPNG method is:
%
%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
%
%  A description of each parameter follows:
%
%    o magick: compare image format pattern against these bytes.
%
%    o length: Specifies the length of the magick string.
%
*/
static MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
{
  if (length < 8)
    return(MagickFalse);
  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
    return(MagickTrue);
  return(MagickFalse);
}

#if defined(MAGICKCORE_PNG_DELEGATE)
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

#if (PNG_LIBPNG_VER > 10011)
static size_t WriteBlobMSBULong(Image *image,const size_t value)
{
  unsigned char
    buffer[4];

  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  buffer[0]=(unsigned char) (value >> 24);
  buffer[1]=(unsigned char) (value >> 16);
  buffer[2]=(unsigned char) (value >> 8);
  buffer[3]=(unsigned char) value;
  return((size_t) WriteBlob(image,4,buffer));
}

static void PNGLong(png_bytep p,png_uint_32 value)
{
  *p++=(png_byte) ((value >> 24) & 0xff);
  *p++=(png_byte) ((value >> 16) & 0xff);
  *p++=(png_byte) ((value >> 8) & 0xff);
  *p++=(png_byte) (value & 0xff);
}

static void PNGsLong(png_bytep p,png_int_32 value)
{
  *p++=(png_byte) ((value >> 24) & 0xff);
  *p++=(png_byte) ((value >> 16) & 0xff);
  *p++=(png_byte) ((value >> 8) & 0xff);
  *p++=(png_byte) (value & 0xff);
}

static void PNGShort(png_bytep p,png_uint_16 value)
{
  *p++=(png_byte) ((value >> 8) & 0xff);
  *p++=(png_byte) (value & 0xff);
}

static void PNGType(png_bytep p,png_bytep type)
{
  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
}

static void LogPNGChunk(int logging, png_bytep type, size_t length)
{
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Writing %c%c%c%c chunk, length: %.20g",
      type[0],type[1],type[2],type[3],(double) length);
}
#endif /* PNG_LIBPNG_VER > 10011 */

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif

#if PNG_LIBPNG_VER > 10011
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d P N G I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
%  Multiple-image Network Graphics (MNG) image file and returns it.  It
%  allocates the memory necessary for the new Image structure and returns a
%  pointer to the new image or set of images.
%
%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
%
%  The format of the ReadPNGImage method is:
%
%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
%  To do, more or less in chronological order (as of version 5.5.2,
%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
%
%    Get 16-bit cheap transparency working.
%
%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
%
%    Preserve all unknown and not-yet-handled known chunks found in input
%    PNG file and copy them into output PNG files according to the PNG
%    copying rules.
%
%    (At this point, PNG encoding should be in full MNG compliance)
%
%    Provide options for choice of background to use when the MNG BACK
%    chunk is not present or is not mandatory (i.e., leave transparent,
%    user specified, MNG BACK, PNG bKGD)
%
%    Implement LOOP/ENDL [done, but could do discretionary loops more
%    efficiently by linking in the duplicate frames.].
%
%    Decode and act on the MHDR simplicity profile (offer option to reject
%    files or attempt to process them anyway when the profile isn't LC or VLC).
%
%    Upgrade to full MNG without Delta-PNG.
%
%        o  BACK [done a while ago except for background image ID]
%        o  MOVE [done 15 May 1999]
%        o  CLIP [done 15 May 1999]
%        o  DISC [done 19 May 1999]
%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
%        o  SEEK [partially done 19 May 1999 (discard function only)]
%        o  SHOW
%        o  PAST
%        o  BASI
%        o  MNG-level tEXt/iTXt/zTXt
%        o  pHYg
%        o  pHYs
%        o  sBIT
%        o  bKGD
%        o  iTXt (wait for libpng implementation).
%
%    Use the scene signature to discover when an identical scene is
%    being reused, and just point to the original image->exception instead
%    of storing another set of pixels.  This not specific to MNG
%    but could be applied generally.
%
%    Upgrade to full MNG with Delta-PNG.
%
%    JNG tEXt/iTXt/zTXt
%
%    We will not attempt to read files containing the CgBI chunk.
%    They are really Xcode files meant for display on the iPhone.
%    These are not valid PNG files and it is impossible to recover
%    the orginal PNG from files that have been converted to Xcode-PNG,
%    since irretrievable loss of color data has occurred due to the
%    use of premultiplied alpha.
*/

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

/*
  This the function that does the actual reading of data.  It is
  the same as the one supplied in libpng, except that it receives the
  datastream from the ReadBlob() function instead of standard input.
*/
static void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
{
  Image
    *image;

  image=(Image *) png_get_io_ptr(png_ptr);
  if (length)
    {
      png_size_t
        check;

      check=(png_size_t) ReadBlob(image,(size_t) length,data);
      if (check != length)
        {
          char
            msg[MaxTextExtent];

          (void) FormatMagickString(msg,MaxTextExtent,
            "Expected %.20g bytes; found %.20g bytes",(double) length,
            (double) check);
          png_warning(png_ptr,msg);
          png_error(png_ptr,"Read Exception");
        }
    }
}

#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
    !defined(PNG_MNG_FEATURES_SUPPORTED)
/* We use mng_get_data() instead of png_get_data() if we have a libpng
 * older than libpng-1.0.3a, which was the first to allow the empty
 * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
 * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
 * encountered after an empty PLTE, so we have to look ahead for bKGD
 * chunks and remove them from the datastream that is passed to libpng,
 * and store their contents for later use.
 */
static void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
{
  MngInfo
    *mng_info;

  Image
    *image;

  png_size_t
    check;

  register ssize_t
    i;

  i=0;
  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
  image=(Image *) mng_info->image;
  while (mng_info->bytes_in_read_buffer && length)
  {
    data[i]=mng_info->read_buffer[i];
    mng_info->bytes_in_read_buffer--;
    length--;
    i++;
  }
  if (length)
    {
      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
      if (check != length)
        png_error(png_ptr,"Read Exception");
      if (length == 4)
        {
          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
              (data[3] == 0))
            {
              check=(png_size_t) ReadBlob(image,(size_t) length,
                (char *) mng_info->read_buffer);
              mng_info->read_buffer[4]=0;
              mng_info->bytes_in_read_buffer=4;
              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
                mng_info->found_empty_plte=MagickTrue;
              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
                {
                  mng_info->found_empty_plte=MagickFalse;
                  mng_info->have_saved_bkgd_index=MagickFalse;
                }
            }
          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
              (data[3] == 1))
            {
              check=(png_size_t) ReadBlob(image,(size_t) length,
                (char *) mng_info->read_buffer);
              mng_info->read_buffer[4]=0;
              mng_info->bytes_in_read_buffer=4;
              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
                if (mng_info->found_empty_plte)
                  {
                    /*
                      Skip the bKGD data byte and CRC.
                    */
                    check=(png_size_t)
                      ReadBlob(image,5,(char *) mng_info->read_buffer);
                    check=(png_size_t) ReadBlob(image,(size_t) length,
                      (char *) mng_info->read_buffer);
                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
                    mng_info->have_saved_bkgd_index=MagickTrue;
                    mng_info->bytes_in_read_buffer=0;
                  }
            }
        }
    }
}
#endif

static void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
{
  Image
    *image;

  image=(Image *) png_get_io_ptr(png_ptr);
  if (length)
    {
      png_size_t
        check;

      check=(png_size_t) WriteBlob(image,(size_t) length,data);
      if (check != length)
        png_error(png_ptr,"WriteBlob Failed");
    }
}

static void png_flush_data(png_structp png_ptr)
{
  (void) png_ptr;
}

#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
static int PalettesAreEqual(Image *a,Image *b)
{
  ssize_t
    i;

  if ((a == (Image *) NULL) || (b == (Image *) NULL))
    return((int) MagickFalse);
  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
    return((int) MagickFalse);
  if (a->colors != b->colors)
    return((int) MagickFalse);
  for (i=0; i < (ssize_t) a->colors; i++)
  {
    if ((a->colormap[i].red != b->colormap[i].red) ||
        (a->colormap[i].green != b->colormap[i].green) ||
        (a->colormap[i].blue != b->colormap[i].blue))
      return((int) MagickFalse);
  }
  return((int) MagickTrue);
}
#endif

static void MngInfoDiscardObject(MngInfo *mng_info,int i)
{
  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
      mng_info->exists[i] && !mng_info->frozen[i])
    {
#ifdef MNG_OBJECT_BUFFERS
      if (mng_info->ob[i] != (MngBuffer *) NULL)
        {
          if (mng_info->ob[i]->reference_count > 0)
            mng_info->ob[i]->reference_count--;
          if (mng_info->ob[i]->reference_count == 0)
            {
              if (mng_info->ob[i]->image != (Image *) NULL)
                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
            }
        }
      mng_info->ob[i]=(MngBuffer *) NULL;
#endif
      mng_info->exists[i]=MagickFalse;
      mng_info->invisible[i]=MagickFalse;
      mng_info->viewable[i]=MagickFalse;
      mng_info->frozen[i]=MagickFalse;
      mng_info->x_off[i]=0;
      mng_info->y_off[i]=0;
      mng_info->object_clip[i].left=0;
      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
      mng_info->object_clip[i].top=0;
      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
    }
}

static void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
{
  if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
    {
      register ssize_t
        i;

      for (i=1; i < MNG_MAX_OBJECTS; i++)
        MngInfoDiscardObject(mng_info,i);
      if (mng_info->global_plte != (png_colorp) NULL)
        mng_info->global_plte=(png_colorp)
          RelinquishMagickMemory(mng_info->global_plte);
      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
      *have_mng_structure=MagickFalse;
    }
}

static MngBox mng_minimum_box(MngBox box1,MngBox box2)
{
  MngBox
    box;

  box=box1;
  if (box.left < box2.left)
    box.left=box2.left;
  if (box.top < box2.top)
    box.top=box2.top;
  if (box.right > box2.right)
    box.right=box2.right;
  if (box.bottom > box2.bottom)
    box.bottom=box2.bottom;
  return box;
}

static MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
{
   MngBox
      box;

  /*
    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
  */
  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
  if (delta_type != 0)
    {
      box.left+=previous_box.left;
      box.right+=previous_box.right;
      box.top+=previous_box.top;
      box.bottom+=previous_box.bottom;
    }
  return(box);
}

static MngPair mng_read_pair(MngPair previous_pair,int delta_type,
  unsigned char *p)
{
  MngPair
    pair;
  /*
    Read two ssize_ts from CLON, MOVE or PAST chunk
  */
  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
  if (delta_type != 0)
    {
      pair.a+=previous_pair.a;
      pair.b+=previous_pair.b;
    }
  return(pair);
}

static long mng_get_long(unsigned char *p)
{
  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
}

static void PNGErrorHandler(png_struct *ping,png_const_charp message)
{
  Image
    *image;

  image=(Image *) png_get_error_ptr(ping);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
    message,"`%s'",image->filename);
#if PNG_LIBPNG_VER < 10500
  longjmp(ping->jmpbuf,1);
#else
  png_longjmp(ping,1);
#endif
}

static void PNGWarningHandler(png_struct *ping,png_const_charp message)
{
  Image
    *image;

  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
    png_error(ping, message);
  image=(Image *) png_get_error_ptr(ping);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
    message,"`%s'",image->filename);
}

#ifdef PNG_USER_MEM_SUPPORTED
static png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
{
#if (PNG_LIBPNG_VER < 10011)
  png_voidp
    ret;

  png_ptr=png_ptr;
  ret=((png_voidp) AcquireMagickMemory((size_t) size));
  if (ret == NULL)
    png_error("Insufficient memory.");
  return(ret);
#else
  png_ptr=png_ptr;
  return((png_voidp) AcquireMagickMemory((size_t) size));
#endif
}

/*
  Free a pointer.  It is removed from the list at the same time.
*/
static png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
{
  png_ptr=png_ptr;
  ptr=RelinquishMagickMemory(ptr);
  return((png_free_ptr) NULL);
}
#endif

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif

static int
png_read_raw_profile(Image *image, const ImageInfo *image_info,
   png_textp text,int ii)
{
  register ssize_t
    i;

  register unsigned char
    *dp;

  register png_charp
    sp;

  png_uint_32
    length,
    nibbles;

  StringInfo
    *profile;

  unsigned char
    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
                 13,14,15};

  sp=text[ii].text+1;
  /* look for newline */
  while (*sp != '\n')
     sp++;
  /* look for length */
  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
     sp++;
  length=(png_uint_32) StringToLong(sp);
  while (*sp != ' ' && *sp != '\n')
     sp++;
  /* allocate space */
  if (length == 0)
  {
    (void) ThrowMagickException(&image->exception,GetMagickModule(),
      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
    return(MagickFalse);
  }
  profile=AcquireStringInfo(length);
  if (profile == (StringInfo *) NULL)
  {
    (void) ThrowMagickException(&image->exception,GetMagickModule(),
      ResourceLimitError,"MemoryAllocationFailed","`%s'",
      "unable to copy profile");
    return(MagickFalse);
  }
  /* copy profile, skipping white space and column 1 "=" signs */
  dp=GetStringInfoDatum(profile);
  nibbles=length*2;
  for (i=0; i < (ssize_t) nibbles; i++)
  {
    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
    {
      if (*sp == '\0')
        {
          (void) ThrowMagickException(&image->exception,GetMagickModule(),
            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
          profile=DestroyStringInfo(profile);
          return(MagickFalse);
        }
      sp++;
    }
    if (i%2 == 0)
      *dp=(unsigned char) (16*unhex[(int) *sp++]);
    else
      (*dp++)+=unhex[(int) *sp++];
  }
  /*
    We have already read "Raw profile type.
  */
  (void) SetImageProfile(image,&text[ii].key[17],profile);
  profile=DestroyStringInfo(profile);
  if (image_info->verbose)
    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
  return MagickTrue;
}

#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
static int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
{
  Image
    *image;


  /* The unknown chunk structure contains the chunk data:
     png_byte name[5];
     png_byte *data;
     png_size_t size;

     Note that libpng has already taken care of the CRC handling.
  */


  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
      chunk->name[2] != 65 ||chunk-> name[3] != 103)
    return(0); /* Did not recognize */

  /* recognized vpAg */

  if (chunk->size != 9)
    return(-1); /* Error return */

  if (chunk->data[8] != 0)
    return(0);  /* ImageMagick requires pixel units */

  image=(Image *) png_get_user_chunk_ptr(ping);

  image->page.width=(size_t) ((chunk->data[0] << 24) |
     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
  image->page.height=(size_t) ((chunk->data[4] << 24) |
     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);

  /* Return one of the following: */
     /* return(-n);  chunk had an error */
     /* return(0);  did not recognize */
     /* return(n);  success */

  return(1);

}
#endif

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d O n e P N G I m a g e                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
%  (minus the 8-byte signature)  and returns it.  It allocates the memory
%  necessary for the new Image structure and returns a pointer to the new
%  image.
%
%  The format of the ReadOnePNGImage method is:
%
%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
%         ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o mng_info: Specifies a pointer to a MngInfo structure.
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadOnePNGImage(MngInfo *mng_info,
    const ImageInfo *image_info, ExceptionInfo *exception)
{
  /* Read one PNG image */

  Image
    *image;

  int
    logging,
    num_text,
    num_passes,
    pass,
    ping_bit_depth,
    ping_color_type,
    ping_interlace_method,
    ping_compression_method,
    ping_filter_method,
    ping_num_trans;

  MagickBooleanType
    status;

  UShortPixelPacket
    transparent_color;

  png_bytep
     ping_trans_alpha;

  png_color_16p
     ping_background,
     ping_trans_color;

  png_info
    *end_info,
    *ping_info;

  png_struct
    *ping;

  png_textp
    text;

  png_uint_32
    ping_height,
    ping_width,
    ping_rowbytes;

  QuantumInfo
    *quantum_info;

  unsigned char
    *png_pixels;

  ssize_t
    y;

  register unsigned char
    *p;

  register IndexPacket
    *indexes;

  register ssize_t
    i,
    x;

  register PixelPacket
    *q;

  size_t
    length;

  size_t
    row_offset;

#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
  png_byte unused_chunks[]=
  {
    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
  };
#endif

  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
    "  enter ReadOnePNGImage()");

#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
  LockSemaphoreInfo(png_semaphore);
#endif

#if (PNG_LIBPNG_VER < 10200)
  if (image_info->verbose)
    printf("Your PNG library (libpng-%s) is rather old.\n",
       PNG_LIBPNG_VER_STRING);
#endif

#if (PNG_LIBPNG_VER >= 10400)
#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
  if (image_info->verbose)
    {
      printf("Your PNG library (libpng-%s) is an old beta version.\n",
           PNG_LIBPNG_VER_STRING);
      printf("Please update it.\n");
    }
#  endif
#endif


  quantum_info = (QuantumInfo *) NULL;
  image=mng_info->image;

  /*
    Allocate the PNG structures
  */
#ifdef PNG_USER_MEM_SUPPORTED
 ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
   PNGErrorHandler,PNGWarningHandler, NULL,
   (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
#else
  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
    PNGErrorHandler,PNGWarningHandler);
#endif
  if (ping == (png_struct *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  ping_info=png_create_info_struct(ping);
  if (ping_info == (png_info *) NULL)
    {
      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  end_info=png_create_info_struct(ping);
  if (end_info == (png_info *) NULL)
    {
      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  png_pixels=(unsigned char *) NULL;
  if (setjmp(png_jmpbuf(ping)))
    {
      /*
        PNG image is corrupt.
      */
      png_destroy_read_struct(&ping,&ping_info,&end_info);
#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
      UnlockSemaphoreInfo(png_semaphore);
#endif
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "  exit ReadOnePNGImage() with error.");
      if (image != (Image *) NULL)
        {
          InheritException(exception,&image->exception);
          image->columns=0;
        }
      return(GetFirstImageInList(image));
    }
  /*
    Prepare PNG for reading.
  */

  mng_info->image_found++;
  png_set_sig_bytes(ping,8);
  if (LocaleCompare(image_info->magick,"MNG") == 0)
    {
#if defined(PNG_MNG_FEATURES_SUPPORTED)
      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
      png_set_read_fn(ping,image,png_get_data);
#else
#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
      png_permit_empty_plte(ping,MagickTrue);
      png_set_read_fn(ping,image,png_get_data);
#else
      mng_info->image=image;
      mng_info->bytes_in_read_buffer=0;
      mng_info->found_empty_plte=MagickFalse;
      mng_info->have_saved_bkgd_index=MagickFalse;
      png_set_read_fn(ping,mng_info,mng_get_data);
#endif
#endif
    }
  else
    png_set_read_fn(ping,image,png_get_data);

#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
  /* Ignore unused chunks and all unknown chunks except for vpAg */
  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
     (int)sizeof(unused_chunks)/5);
  /* Callback for other unknown chunks */
  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
#endif

#if (PNG_LIBPNG_VER < 10400)
#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
  /* Disable thread-unsafe features of pnggccrd */
  if (png_access_version_number() >= 10200)
  {
    png_uint_32 mmx_disable_mask=0;
    png_uint_32 asm_flags;

    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
    asm_flags=png_get_asm_flags(ping);
    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
  }
#  endif
#endif

  png_read_info(ping,ping_info);

  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
               &ping_bit_depth,&ping_color_type,
               &ping_interlace_method,&ping_compression_method,
               &ping_filter_method);

  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
                      &ping_trans_color);

  (void) png_get_bKGD(ping, ping_info, &ping_background);

  if (ping_bit_depth < 8)
    {
      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
        {
          png_set_packing(ping);
          ping_bit_depth = 8;
        }
    }

  image->depth=ping_bit_depth;
  image->depth=GetImageQuantumDepth(image,MagickFalse);
  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
  if (logging != MagickFalse)
    {
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    PNG width: %.20g, height: %.20g",
        (double) ping_width, (double) ping_height);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    PNG color_type: %d, bit_depth: %d",
        ping_color_type, ping_bit_depth);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    PNG compression_method: %d",
        ping_compression_method);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    PNG interlace_method: %d, filter_method: %d",
        ping_interlace_method,ping_filter_method);
    }

#ifdef PNG_READ_iCCP_SUPPORTED
  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
    {
      int
        compression;

      png_charp
        info,
        name;

      png_uint_32
        profile_length;

      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
        &profile_length);
      if (profile_length != 0)
        {
          StringInfo
            *profile;

          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "    Reading PNG iCCP chunk.");
          profile=AcquireStringInfo(profile_length);
          SetStringInfoDatum(profile,(const unsigned char *) info);
          (void) SetImageProfile(image,"icc",profile);
          profile=DestroyStringInfo(profile);
      }
    }
#endif
#if defined(PNG_READ_sRGB_SUPPORTED)
  {
    int
      intent;

    if (mng_info->have_global_srgb)
      image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
        mng_info->global_srgb_intent);
    if (png_get_sRGB(ping,ping_info,&intent))
      {
        image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
          intent);
        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
      }
  }
#endif
  {
     double
        file_gamma;

     if (!png_get_gAMA(ping,ping_info,&file_gamma))
       if (mng_info->have_global_gama)
         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
     if (png_get_gAMA(ping,ping_info,&file_gamma))
       {
         image->gamma=(float) file_gamma;
         if (logging != MagickFalse)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
       }
  }
  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
    {
      if (mng_info->have_global_chrm != MagickFalse)
        {
          (void) png_set_cHRM(ping,ping_info,
            mng_info->global_chrm.white_point.x,
            mng_info->global_chrm.white_point.y,
            mng_info->global_chrm.red_primary.x,
            mng_info->global_chrm.red_primary.y,
            mng_info->global_chrm.green_primary.x,
            mng_info->global_chrm.green_primary.y,
            mng_info->global_chrm.blue_primary.x,
            mng_info->global_chrm.blue_primary.y);
        }
    }
  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
    {
      (void) png_get_cHRM(ping,ping_info,
        &image->chromaticity.white_point.x,
        &image->chromaticity.white_point.y,
        &image->chromaticity.red_primary.x,
        &image->chromaticity.red_primary.y,
        &image->chromaticity.green_primary.x,
        &image->chromaticity.green_primary.y,
        &image->chromaticity.blue_primary.x,
        &image->chromaticity.blue_primary.y);
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Reading PNG cHRM chunk.");
    }
  if (image->rendering_intent != UndefinedIntent)
    {
      png_set_sRGB(ping,ping_info,
         PNG_RenderingIntent_from_Magick_RenderingIntent(
         image->rendering_intent));
      png_set_gAMA(ping,ping_info,0.45455f);
      png_set_cHRM(ping,ping_info,
                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
    }
#if defined(PNG_oFFs_SUPPORTED)
  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
    {
      image->page.x=png_get_x_offset_pixels(ping, ping_info);
      image->page.y=png_get_y_offset_pixels(ping, ping_info);
      if (logging != MagickFalse)
        if (image->page.x || image->page.y)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
            image->page.x,(double) image->page.y);
    }
#endif
#if defined(PNG_pHYs_SUPPORTED)
  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
    {
      if (mng_info->have_global_phys)
        {
          png_set_pHYs(ping,ping_info,
                       mng_info->global_x_pixels_per_unit,
                       mng_info->global_y_pixels_per_unit,
                       mng_info->global_phys_unit_type);
        }
    }

  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
    {
      int
        unit_type;

      png_uint_32
        x_resolution,
        y_resolution;

      /*
        Set image resolution.
      */
      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
        &unit_type);
      image->x_resolution=(double) x_resolution;
      image->y_resolution=(double) y_resolution;
      if (unit_type == PNG_RESOLUTION_METER)
        {
          image->units=PixelsPerCentimeterResolution;
          image->x_resolution=(double) x_resolution/100.0;
          image->y_resolution=(double) y_resolution/100.0;
        }
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
          (double) x_resolution,(double) y_resolution,unit_type);
    }
#endif
  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
    {
      int
        number_colors;

      png_colorp
        palette;

      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
      if ((number_colors == 0) &&
          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
        {
          if (mng_info->global_plte_length)
            {
              png_set_PLTE(ping,ping_info,mng_info->global_plte,
                (int) mng_info->global_plte_length);
              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
                if (mng_info->global_trns_length)
                  {
                    if (mng_info->global_trns_length >
                        mng_info->global_plte_length)
                      (void) ThrowMagickException(&image->exception,
                        GetMagickModule(),CoderError,
                        "global tRNS has more entries than global PLTE",
                        "`%s'",image_info->filename);
                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
                      (int) mng_info->global_trns_length,NULL);
                  }
#if defined(PNG_READ_bKGD_SUPPORTED)
              if (
#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
                   mng_info->have_saved_bkgd_index ||
#endif
                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
                    {
                      png_color_16
                         background;

#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
                      if (mng_info->have_saved_bkgd_index)
                        background.index=mng_info->saved_bkgd_index;
#endif
                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
                        background.index=ping_background->index;
                      background.red=(png_uint_16)
                        mng_info->global_plte[background.index].red;
                      background.green=(png_uint_16)
                        mng_info->global_plte[background.index].green;
                      background.blue=(png_uint_16)
                        mng_info->global_plte[background.index].blue;
                      png_set_bKGD(ping,ping_info,&background);
                    }
#endif
                }
              else
                (void) ThrowMagickException(&image->exception,GetMagickModule(),
                  CoderError,"No global PLTE in file","`%s'",
                  image_info->filename);
            }
        }

#if defined(PNG_READ_bKGD_SUPPORTED)
  if (mng_info->have_global_bkgd &&
          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
      image->background_color=mng_info->mng_global_bkgd;
  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
    {
      /*
        Set image background color.
      */
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Reading PNG bKGD chunk.");
      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
        {
          image->background_color.red=ping_background->red;
          image->background_color.green=ping_background->green;
          image->background_color.blue=ping_background->blue;
        }
      else /* Scale background components to 16-bit */
        {
          unsigned int
            bkgd_scale;

          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "    raw ping_background=(%d,%d,%d).",ping_background->red,
              ping_background->green,ping_background->blue);

          bkgd_scale = 1;
          if (ping_bit_depth == 1)
             bkgd_scale = 255;
          else if (ping_bit_depth == 2)
             bkgd_scale = 85;
          else if (ping_bit_depth == 4)
             bkgd_scale = 17;
          if (ping_bit_depth <= 8)
             bkgd_scale *= 257;

          ping_background->red *= bkgd_scale;
          ping_background->green *= bkgd_scale;
          ping_background->blue *= bkgd_scale;

          if (logging != MagickFalse)
            {
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "    bkgd_scale=%d.",bkgd_scale);
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "    ping_background=(%d,%d,%d).",ping_background->red,
              ping_background->green,ping_background->blue);
            }

          image->background_color.red=
            ScaleShortToQuantum(ping_background->red);
          image->background_color.green=
            ScaleShortToQuantum(ping_background->green);
          image->background_color.blue=
            ScaleShortToQuantum(ping_background->blue);
          image->background_color.opacity=OpaqueOpacity;

          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "    image->background_color=(%.20g,%.20g,%.20g).",
              (double) image->background_color.red,
              (double) image->background_color.green,
              (double) image->background_color.blue);
        }
    }
#endif
  transparent_color.red=0;
  transparent_color.green=0;
  transparent_color.blue=0;
  transparent_color.opacity=0;
  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
    {
      /*
        Image has a transparent background.
      */
      int
        max_sample;

      size_t
        one=1;

      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Reading PNG tRNS chunk.");

      max_sample = (int) ((one << ping_bit_depth) - 1);

      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
          (int)ping_trans_color->gray > max_sample) ||
          (ping_color_type == PNG_COLOR_TYPE_RGB &&
          ((int)ping_trans_color->red > max_sample ||
          (int)ping_trans_color->green > max_sample ||
          (int)ping_trans_color->blue > max_sample)))
        {
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "    Ignoring PNG tRNS chunk with out-of-range sample.");
          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
          image->matte=MagickFalse;
        }
      else
        {
          transparent_color.red= (unsigned short)(ping_trans_color->red);
          transparent_color.green= (unsigned short) (ping_trans_color->green);
          transparent_color.blue= (unsigned short) (ping_trans_color->blue);
          transparent_color.opacity= (unsigned short) (ping_trans_color->gray);

          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
            {
#if (MAGICKCORE_QUANTUM_DEPTH == 8)
              if (ping_bit_depth < MAGICKCORE_QUANTUM_DEPTH)
#endif
              transparent_color.opacity=(unsigned short) (
                  ping_trans_color->gray *
                  (65535L/((1UL << ping_bit_depth)-1)));

#if (MAGICKCORE_QUANTUM_DEPTH == 8)
              else
                transparent_color.opacity=(unsigned short) (
                    (ping_trans_color->gray * 65535L)/
                   ((1UL << ping_bit_depth)-1));
#endif
              if (logging != MagickFalse)
              {
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    scaled graylevel is %d.",transparent_color.opacity);
              }
              transparent_color.red=transparent_color.opacity;
              transparent_color.green=transparent_color.opacity;
              transparent_color.blue=transparent_color.opacity;
            }
        }
    }
#if defined(PNG_READ_sBIT_SUPPORTED)
  if (mng_info->have_global_sbit)
    {
      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
    }
#endif
  num_passes=png_set_interlace_handling(ping);

  png_read_update_info(ping,ping_info);

  ping_rowbytes=png_get_rowbytes(ping,ping_info);

  /*
    Initialize image structure.
  */
  mng_info->image_box.left=0;
  mng_info->image_box.right=(ssize_t) ping_width;
  mng_info->image_box.top=0;
  mng_info->image_box.bottom=(ssize_t) ping_height;
  if (mng_info->mng_type == 0)
    {
      mng_info->mng_width=ping_width;
      mng_info->mng_height=ping_height;
      mng_info->frame=mng_info->image_box;
      mng_info->clip=mng_info->image_box;
    }
  else
    {
      image->page.y=mng_info->y_off[mng_info->object_id];
    }
  image->compression=ZipCompression;
  image->columns=ping_width;
  image->rows=ping_height;
  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
    {
      size_t
        one;

      image->storage_class=PseudoClass;
      one=1;
      image->colors=one << ping_bit_depth;
#if (MAGICKCORE_QUANTUM_DEPTH == 8)
      if (image->colors > 256)
        image->colors=256;
#else
      if (image->colors > 65536L)
        image->colors=65536L;
#endif
      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
        {
          int
            number_colors;

          png_colorp
            palette;

          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
          image->colors=(size_t) number_colors;
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
        }
    }

  if (image->storage_class == PseudoClass)
    {
      /*
        Initialize image colormap.
      */
      if (AcquireImageColormap(image,image->colors) == MagickFalse)
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
        {
          int
            number_colors;

          png_colorp
            palette;

          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
          for (i=0; i < (ssize_t) image->colors; i++)
          {
            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
          }
        }
      else
        {
          size_t
            scale;

          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
          if (scale < 1)
             scale=1;
          for (i=0; i < (ssize_t) image->colors; i++)
          {
            image->colormap[i].red=(Quantum) (i*scale);
            image->colormap[i].green=(Quantum) (i*scale);
            image->colormap[i].blue=(Quantum) (i*scale);
          }
       }
    }
  /*
    Read image scanlines.
  */
  if (image->delay != 0)
    mng_info->scenes_found++;
  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
      (image_info->first_scene+image_info->number_scenes))))
    {
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Skipping PNG image data for scene %.20g",(double)
          mng_info->scenes_found-1);
      png_destroy_read_struct(&ping,&ping_info,&end_info);
#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
      UnlockSemaphoreInfo(png_semaphore);
#endif
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "  exit ReadOnePNGImage().");
      return(image);
    }
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "    Reading PNG IDAT chunk(s)");
  if (num_passes > 1)
    png_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
      ping_rowbytes*sizeof(*png_pixels));
  else
    png_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
      sizeof(*png_pixels));
  if (png_pixels == (unsigned char *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "    Converting PNG pixels to pixel packets");
  /*
    Convert PNG pixels to pixel packets.
  */
  if (setjmp(png_jmpbuf(ping)))
    {
      /*
        PNG image is corrupt.
      */
      png_destroy_read_struct(&ping,&ping_info,&end_info);
#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
      UnlockSemaphoreInfo(png_semaphore);
#endif
      if (quantum_info != (QuantumInfo *) NULL)
        quantum_info = DestroyQuantumInfo(quantum_info);
      if (png_pixels != (unsigned char *) NULL)
        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "  exit ReadOnePNGImage() with error.");
      if (image != (Image *) NULL)
        {
          InheritException(exception,&image->exception);
          image->columns=0;
        }
      return(GetFirstImageInList(image));
    }
  quantum_info=AcquireQuantumInfo(image_info,image);
  if (quantum_info == (QuantumInfo *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  if (image->storage_class == DirectClass)
    for (pass=0; pass < num_passes; pass++)
    {
      /*
        Convert image to DirectClass pixel packets.
      */
#if (MAGICKCORE_QUANTUM_DEPTH == 8)
      int
        depth;

      depth=(ssize_t) ping_bit_depth;
#endif
      image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
          ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
          (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
          MagickTrue : MagickFalse;

      for (y=0; y < (ssize_t) image->rows; y++)
      {
        if (num_passes > 1)
          row_offset=ping_rowbytes*y;
        else
          row_offset=0;
        png_read_row(ping,png_pixels+row_offset,NULL);
        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
        if (q == (PixelPacket *) NULL)
          break;
#if (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
        if (depth == 16)
          {
            register Quantum
              *p,
              *r;

            r=png_pixels+row_offset;
            p=r;
            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
              {
                for (x=(ssize_t) image->columns-1; x >= 0; x--)
                {
                  *r++=*p++;
                  p++;
                  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS)) &&
                     (((*(p-2) << 8)|*(p-1)) == transparent_color.opacity))
                    {
                       /* Cheap transparency */
                       *r++=TransparentOpacity;
                    }
                  else
                       *r++=OpaqueOpacity;
                }
              }
            else if (ping_color_type == PNG_COLOR_TYPE_RGB)
              {
              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
                for (x=(ssize_t) image->columns-1; x >= 0; x--)
                {
                  *r++=*p++;
                  p++;
                  *r++=*p++;
                  p++;
                  *r++=*p++;
                  p++;
                  if ((((*(p-6) << 8)|*(p-5)) == transparent_color.red) &&
                       (((*(p-4) << 8)|*(p-3)) == transparent_color.green) &&
                       (((*(p-2) << 8)|*(p-1)) == transparent_color.blue))
                    {
                       /* Cheap transparency */
                       *r++=TransparentOpacity;
                    }
                  else
                       *r++=OpaqueOpacity;
                }
              else
                for (x=(ssize_t) image->columns-1; x >= 0; x--)
                {
                  *r++=*p++;
                  p++;
                  *r++=*p++;
                  p++;
                  *r++=*p++;
                  p++;
                  *r++=OpaqueOpacity;
                }
              }
            else if (ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
              for (x=(ssize_t) (4*image->columns); x != 0; x--)
              {
                *r++=*p++;
                p++;
              }
            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
              for (x=(ssize_t) (2*image->columns); x != 0; x--)
              {
                *r++=*p++;
                p++;
              }
          }
        if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_GRAY)
          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
            GrayQuantum,png_pixels+row_offset);
        if (ping_color_type == PNG_COLOR_TYPE_GRAY ||
            ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
          {
            quantum_info->depth=8;
            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
              GrayAlphaQuantum,png_pixels+row_offset);
          }
        else if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_RGB)
           (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
             RGBQuantum,png_pixels+row_offset);
        else if (ping_color_type == PNG_COLOR_TYPE_RGB ||
              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
          {
            quantum_info->depth=8;
            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
              RGBAQuantum,png_pixels+row_offset);
          }
        else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
              IndexQuantum,png_pixels+row_offset);
#else /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
        if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
            GrayQuantum,png_pixels+row_offset,exception);
        else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
            GrayAlphaQuantum,png_pixels+row_offset,exception);
        else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
            RGBAQuantum,png_pixels+row_offset,exception);
        else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
            IndexQuantum,png_pixels+row_offset,exception);
        else
          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
            RGBQuantum,png_pixels+row_offset,exception);
#endif
        if ((image->previous == (Image *) NULL) && (num_passes == 1))
          {
            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                image->rows);
            if (status == MagickFalse)
              break;
          }
        if (SyncAuthenticPixels(image,exception) == MagickFalse)
          break;
      }
      if ((image->previous == (Image *) NULL) && (num_passes != 1))
        {
          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
          if (status == MagickFalse)
            break;
        }
    }
  else /* image->storage_class != DirectClass */
    for (pass=0; pass < num_passes; pass++)
    {
      Quantum
        *quantum_scanline;

      register Quantum
        *r;

      /*
        Convert grayscale image to PseudoClass pixel packets.
      */
      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
        MagickTrue : MagickFalse;
      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
      if (quantum_scanline == (Quantum *) NULL)
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        if (num_passes > 1)
          row_offset=ping_rowbytes*y;
        else
          row_offset=0;
        png_read_row(ping,png_pixels+row_offset,NULL);
        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
        if (q == (PixelPacket *) NULL)
          break;
        indexes=GetAuthenticIndexQueue(image);
        p=png_pixels+row_offset;
        r=quantum_scanline;
        switch (ping_bit_depth)
        {
          case 1:
          {
            register ssize_t
              bit;

            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
            {
              for (bit=7; bit >= 0; bit--)
                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
              p++;
            }
            if ((image->columns % 8) != 0)
              {
                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
              }
            break;
          }
          case 2:
          {
            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
            {
              *r++=(*p >> 6) & 0x03;
              *r++=(*p >> 4) & 0x03;
              *r++=(*p >> 2) & 0x03;
              *r++=(*p++) & 0x03;
            }
            if ((image->columns % 4) != 0)
              {
                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
              }
            break;
          }
          case 4:
          {
            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
            {
              *r++=(*p >> 4) & 0x0f;
              *r++=(*p++) & 0x0f;
            }
            if ((image->columns % 2) != 0)
              *r++=(*p++ >> 4) & 0x0f;
            break;
          }
          case 8:
          {
            if (ping_color_type == 4)
              for (x=(ssize_t) image->columns-1; x >= 0; x--)
              {
                *r++=*p++;
                /* In image.h, OpaqueOpacity is 0
                 * TransparentOpacity is QuantumRange
                 * In a PNG datastream, Opaque is QuantumRange
                 * and Transparent is 0.
                 */
                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
                q++;
              }
            else
              for (x=(ssize_t) image->columns-1; x >= 0; x--)
                *r++=*p++;
            break;
          }
          case 16:
          {
            for (x=(ssize_t) image->columns-1; x >= 0; x--)
            {
#if (MAGICKCORE_QUANTUM_DEPTH == 16)
              size_t
                quantum;

              if (image->colors > 256)
                *r=((*p++) << 8);
              else
                *r=0;
              quantum=(*r);
              quantum|=(*p++);
              *r=(Quantum) quantum;
              r++;
              if (ping_color_type == 4)
                {
                  quantum=((*p++) << 8);
                  quantum|=(*p++);
                  q->opacity=(Quantum) (QuantumRange-quantum);
                  q++;
                }
#else
#if (MAGICKCORE_QUANTUM_DEPTH == 32)
              size_t
                quantum;

              if (image->colors > 256)
                *r=((*p++) << 8);
              else
                *r=0;
              quantum=(*r);
              quantum|=(*p++);
              *r=quantum;
              r++;
              if (ping_color_type == 4)
                {
                  q->opacity=(*p << 8) | *(p+1);
                  q->opacity*=65537L;
                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
                  p+=2;
                  q++;
                }
#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
              *r++=(*p++);
              p++; /* strip low byte */
              if (ping_color_type == 4)
                {
                  q->opacity=(Quantum) (QuantumRange-(*p++));
                  p++;
                  q++;
                }
#endif
#endif
            }
            break;
          }
          default:
            break;
        }
        /*
          Transfer image scanline.
        */
        r=quantum_scanline;
        for (x=0; x < (ssize_t) image->columns; x++)
          indexes[x]=(IndexPacket) (*r++);
        if (SyncAuthenticPixels(image,exception) == MagickFalse)
          break;
        if ((image->previous == (Image *) NULL) && (num_passes == 1))
          {
            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                image->rows);
            if (status == MagickFalse)
              break;
          }
      }
      if ((image->previous == (Image *) NULL) && (num_passes != 1))
        {
          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
          if (status == MagickFalse)
            break;
        }
      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
    }
  if (quantum_info != (QuantumInfo *) NULL)
    quantum_info=DestroyQuantumInfo(quantum_info);
  if (image->storage_class == PseudoClass)
    {
      MagickBooleanType
        matte;

      matte=image->matte;
      image->matte=MagickFalse;
      (void) SyncImage(image);
      image->matte=matte;
    }
  png_read_end(ping,ping_info);

  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
      (ssize_t) image_info->first_scene && image->delay != 0)
    {
      png_destroy_read_struct(&ping,&ping_info,&end_info);
      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
      image->colors=2;
      (void) SetImageBackgroundColor(image);
#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
      UnlockSemaphoreInfo(png_semaphore);
#endif
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "  exit ReadOnePNGImage() early.");
      return(image);
    }
  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
    {
      ClassType
        storage_class;

      /*
        Image has a transparent background.
      */
      storage_class=image->storage_class;
      image->matte=MagickTrue;

#if 1  /* balfour fix */
/* From imagemagick discourse server, 5 Feb 2010 */

    if (storage_class == PseudoClass)
   {
      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
      {
         for (x=0; x < ping_num_trans; x++)
         {
            image->colormap[x].opacity =
              ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
         }
      }
      else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
      {
         for (x=0; x < (int) image->colors; x++)
         {
            if (ScaleQuantumToShort(image->colormap[x].red) ==
                transparent_color.opacity)
            {
               image->colormap[x].opacity = (Quantum) TransparentOpacity;
            }
         }
      }
      (void) SyncImage(image);
   }
   else
   {

      for (y=0; y < (ssize_t) image->rows; y++)
      {
        image->storage_class=storage_class;
        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
        if (q == (PixelPacket *) NULL)
          break;
        indexes=GetAuthenticIndexQueue(image);

          for (x=(ssize_t) image->columns-1; x >= 0; x--)
          {
            if (ScaleQuantumToShort(q->red) == transparent_color.red &&
                ScaleQuantumToShort(q->green) == transparent_color.green &&
                ScaleQuantumToShort(q->blue) == transparent_color.blue)
               q->opacity=(Quantum) TransparentOpacity;
            else
              SetOpacityPixelComponent(q,OpaqueOpacity);
            q++;
          }
        if (SyncAuthenticPixels(image,exception) == MagickFalse)
          break;
      }
   }

#else /* not balfour */


      for (y=0; y < (ssize_t) image->rows; y++)
      {
        image->storage_class=storage_class;
        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
        if (q == (PixelPacket *) NULL)
          break;
        indexes=GetAuthenticIndexQueue(image);

        if (storage_class == PseudoClass)
          {
            IndexPacket
              indexpacket;

            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
              for (x=0; x < (ssize_t) image->columns; x++)
              {
                indexpacket=indexes[x];
                if (indexpacket < ping_num_trans)
                  q->opacity=ScaleCharToQuantum((unsigned char)
                    (255-ping_trans_alpha[(ssize_t) indexpacket]));
                else
                  SetOpacityPixelComponent(q,OpaqueOpacity);
                q++;
              }
            else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
              for (x=0; x < (ssize_t) image->columns; x++)
              {
                indexpacket=indexes[x];
                q->red=image->colormap[(ssize_t) indexpacket].red;
                q->green=q->red;
                q->blue=q->red;
                if (ScaleQuantomToShort(q->red) == transparent_color.opacity)
                  q->opacity=(Quantum) TransparentOpacity;
                else
                  SetOpacityPixelComponent(q,OpaqueOpacity);
                q++;
              }
          }
        else
          for (x=(ssize_t) image->columns-1; x >= 0; x--)
          {
            if (ScaleQuantumToShort(q->red) == transparent_color.red &&
                ScaleQuantumToShort(q->green) == transparent_color.green &&
                ScaleQuantumToShort(q->blue) == transparent_color.blue)
               q->opacity=(Quantum) TransparentOpacity;
            else
              SetOpacityPixelComponent(q,OpaqueOpacity);
            q++;
          }
        if (SyncAuthenticPixels(image,exception) == MagickFalse)
          break;
      }
#endif /* not balfour */
      image->storage_class=DirectClass;
    }
  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
    image->colorspace=GRAYColorspace;
  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
    for (i=0; i < (ssize_t) num_text; i++)
    {
      /* Check for a profile */

      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Reading PNG text chunk");
      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
          (void) png_read_raw_profile(image,image_info,text,(int) i);
      else
        {
          char
            *value;

          length=text[i].text_length;
          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
            sizeof(*value));
          if (value == (char *) NULL)
            {
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                ResourceLimitError,"MemoryAllocationFailed","`%s'",
                image->filename);
              break;
            }
          *value='\0';
          (void) ConcatenateMagickString(value,text[i].text,length+2);
          (void) SetImageProperty(image,text[i].key,value);
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "      Keyword: %s",text[i].key);
          value=DestroyString(value);
        }
    }
#ifdef MNG_OBJECT_BUFFERS
  /*
    Store the object if necessary.
  */
  if (object_id && !mng_info->frozen[object_id])
    {
      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
        {
          /*
            create a new object buffer.
          */
          mng_info->ob[object_id]=(MngBuffer *)
            AcquireQuantumMemory(1,sizeof(MngBuffer));
          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
            {
              mng_info->ob[object_id]->image=(Image *) NULL;
              mng_info->ob[object_id]->reference_count=1;
            }
        }
      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
          mng_info->ob[object_id]->frozen)
        {
          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
            (void) ThrowMagickException(&image->exception,GetMagickModule(),
              ResourceLimitError,"MemoryAllocationFailed","`%s'",
              image->filename);
          if (mng_info->ob[object_id]->frozen)
            (void) ThrowMagickException(&image->exception,GetMagickModule(),
              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
              "`%s'",image->filename);
        }
      else
        {

          if (mng_info->ob[object_id]->image != (Image *) NULL)
            mng_info->ob[object_id]->image=DestroyImage
                (mng_info->ob[object_id]->image);
          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
            &image->exception);
          if (mng_info->ob[object_id]->image != (Image *) NULL)
            mng_info->ob[object_id]->image->file=(FILE *) NULL;
          else
            (void) ThrowMagickException(&image->exception,GetMagickModule(),
              ResourceLimitError,"Cloning image for object buffer failed",
              "`%s'",image->filename);
          if (ping_width > 250000L || ping_height > 250000L)
             png_error(ping,"PNG Image dimensions are too large.");
          mng_info->ob[object_id]->width=ping_width;
          mng_info->ob[object_id]->height=ping_height;
          mng_info->ob[object_id]->color_type=ping_color_type;
          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
          mng_info->ob[object_id]->compression_method=
             ping_compression_method;
          mng_info->ob[object_id]->filter_method=ping_filter_method;
          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
            {
              int
                number_colors;

              png_colorp
                plte;

              /*
                Copy the PLTE to the object buffer.
              */
              png_get_PLTE(ping,ping_info,&plte,&number_colors);
              mng_info->ob[object_id]->plte_length=number_colors;
              for (i=0; i < number_colors; i++)
              {
                mng_info->ob[object_id]->plte[i]=plte[i];
              }
            }
          else
              mng_info->ob[object_id]->plte_length=0;
        }
    }
#endif
  /*
    Relinquish resources.
  */
  png_destroy_read_struct(&ping,&ping_info,&end_info);

  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
  UnlockSemaphoreInfo(png_semaphore);
#endif

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  exit ReadOnePNGImage()");
  return(image);

/* end of reading one PNG image */
}

static Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image,
    *previous;

  MagickBooleanType
    status;

  MngInfo
    *mng_info;

  char
    magic_number[MaxTextExtent];

  int
    have_mng_structure,
    logging;

  ssize_t
    count;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
  image=AcquireImage(image_info);
  mng_info=(MngInfo *) NULL;
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    ThrowReaderException(FileOpenError,"UnableToOpenFile");
  /*
    Verify PNG signature.
  */
  count=ReadBlob(image,8,(unsigned char *) magic_number);
  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  /*
    Allocate a MngInfo structure.
  */
  have_mng_structure=MagickFalse;
  mng_info=(MngInfo *) AcquireQuantumMemory(1,sizeof(MngInfo));
  if (mng_info == (MngInfo *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  /*
    Initialize members of the MngInfo structure.
  */
  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
  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");
      return((Image *) NULL);
    }
  (void) CloseBlob(image);
  if ((image->columns == 0) || (image->rows == 0))
    {
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "exit ReadPNGImage() with error.");
      ThrowReaderException(CorruptImageError,"CorruptImage");
    }
  if (LocaleCompare(image_info->magick,"PNG8") == 0)
    {
      (void) SetImageType(image,PaletteType);
      if (image->matte != MagickFalse)
        {
          /* To do: Reduce to binary transparency */
        }
    }
  if (LocaleCompare(image_info->magick,"PNG24") == 0)
    {
      (void) SetImageType(image,TrueColorType);
      image->matte=MagickFalse;
    }
  if (LocaleCompare(image_info->magick,"PNG32") == 0)
    (void) SetImageType(image,TrueColorMatteType);
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
  return(image);
}



#if defined(JNG_SUPPORTED)
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d O n e J N G I m a g e                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
%  (minus the 8-byte signature)  and returns it.  It allocates the memory
%  necessary for the new Image structure and returns a pointer to the new
%  image.
%
%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
%
%  The format of the ReadOneJNGImage method is:
%
%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
%         ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o mng_info: Specifies a pointer to a MngInfo structure.
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadOneJNGImage(MngInfo *mng_info,
    const ImageInfo *image_info, ExceptionInfo *exception)
{
  Image
    *alpha_image,
    *color_image,
    *image,
    *jng_image;

  ImageInfo
    *alpha_image_info,
    *color_image_info;

  ssize_t
    y;

  MagickBooleanType
    status;

  png_uint_32
    jng_height,
    jng_width;

  png_byte
    jng_color_type,
    jng_image_sample_depth,
    jng_image_compression_method,
    jng_image_interlace_method,
    jng_alpha_sample_depth,
    jng_alpha_compression_method,
    jng_alpha_filter_method,
    jng_alpha_interlace_method;

  register const PixelPacket
    *s;

  register ssize_t
    i,
    x;

  register PixelPacket
    *q;

  register unsigned char
    *p;

  unsigned int
    logging,
    read_JSEP,
    reading_idat,
    skip_to_iend;

  size_t
    length;

  jng_alpha_compression_method=0;
  jng_alpha_sample_depth=8;
  jng_color_type=0;
  jng_height=0;
  jng_width=0;
  alpha_image=(Image *) NULL;
  color_image=(Image *) NULL;
  alpha_image_info=(ImageInfo *) NULL;
  color_image_info=(ImageInfo *) NULL;

  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
    "  enter ReadOneJNGImage()");

  image=mng_info->image;
  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
    {
      /*
        Allocate next image structure.
      */
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "  AcquireNextImage()");
      AcquireNextImage(image_info,image);
      if (GetNextImageInList(image) == (Image *) NULL)
        return((Image *) NULL);
      image=SyncNextImageInList(image);
    }
  mng_info->image=image;

  /*
    Signature bytes have already been read.
  */

  read_JSEP=MagickFalse;
  reading_idat=MagickFalse;
  skip_to_iend=MagickFalse;
  for (;;)
  {
    char
      type[MaxTextExtent];

    unsigned char
      *chunk;

    unsigned int
      count;

    /*
      Read a new JNG chunk.
    */
    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
      2*GetBlobSize(image));
    if (status == MagickFalse)
      break;
    type[0]='\0';
    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
    length=ReadBlobMSBLong(image);
    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);

    if (logging != MagickFalse)
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
        type[0],type[1],type[2],type[3],(double) length);

    if (length > PNG_UINT_31_MAX || count == 0)
      ThrowReaderException(CorruptImageError,"CorruptImage");
    p=NULL;
    chunk=(unsigned char *) NULL;
    if (length)
      {
        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
        if (chunk == (unsigned char *) NULL)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        for (i=0; i < (ssize_t) length; i++)
          chunk[i]=(unsigned char) ReadBlobByte(image);
        p=chunk;
      }
    (void) ReadBlobMSBLong(image);  /* read crc word */

    if (skip_to_iend)
      {
        if (length)
          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_JHDR,4) == 0)
      {
        if (length == 16)
          {
            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
                (p[2] << 8) | p[3]);
            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
                (p[6] << 8) | p[7]);
            jng_color_type=p[8];
            jng_image_sample_depth=p[9];
            jng_image_compression_method=p[10];
            jng_image_interlace_method=p[11];
            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
              NoInterlace;
            jng_alpha_sample_depth=p[12];
            jng_alpha_compression_method=p[13];
            jng_alpha_filter_method=p[14];
            jng_alpha_interlace_method=p[15];
            if (logging != MagickFalse)
              {
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_width:      %16lu",(unsigned long) jng_width);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_width:      %16lu",(unsigned long) jng_height);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_color_type: %16d",jng_color_type);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_image_sample_depth:      %3d",
                  jng_image_sample_depth);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_image_compression_method:%3d",
                  jng_image_compression_method);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_image_interlace_method:  %3d",
                  jng_image_interlace_method);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_alpha_sample_depth:      %3d",
                  jng_alpha_sample_depth);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_alpha_compression_method:%3d",
                  jng_alpha_compression_method);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_alpha_filter_method:     %3d",
                  jng_alpha_filter_method);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    jng_alpha_interlace_method:  %3d",
                  jng_alpha_interlace_method);
              }
          }
        if (length)
          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }


    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
      {
        /*
           o create color_image
           o open color_blob, attached to color_image
           o if (color type has alpha)
               open alpha_blob, attached to alpha_image
        */

        color_image_info=(ImageInfo *)AcquireQuantumMemory(1,sizeof(ImageInfo));
        if (color_image_info == (ImageInfo *) NULL)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        GetImageInfo(color_image_info);
        color_image=AcquireImage(color_image_info);
        if (color_image == (Image *) NULL)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");

        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Creating color_blob.");
        (void) AcquireUniqueFilename(color_image->filename);
        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
          exception);
        if (status == MagickFalse)
          return((Image *) NULL);

        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
          {
            alpha_image_info=(ImageInfo *)
              AcquireQuantumMemory(1,sizeof(ImageInfo));
            if (alpha_image_info == (ImageInfo *) NULL)
              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
            GetImageInfo(alpha_image_info);
            alpha_image=AcquireImage(alpha_image_info);
            if (alpha_image == (Image *) NULL)
              {
                alpha_image=DestroyImage(alpha_image);
                ThrowReaderException(ResourceLimitError,
                  "MemoryAllocationFailed");
              }
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Creating alpha_blob.");
            (void) AcquireUniqueFilename(alpha_image->filename);
            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
              exception);
            if (status == MagickFalse)
              return((Image *) NULL);
            if (jng_alpha_compression_method == 0)
              {
                unsigned char
                  data[18];

                if (logging != MagickFalse)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "    Writing IHDR chunk to alpha_blob.");
                (void) WriteBlob(alpha_image,8,(const unsigned char *)
                  "\211PNG\r\n\032\n");
                (void) WriteBlobMSBULong(alpha_image,13L);
                PNGType(data,mng_IHDR);
                LogPNGChunk((int) logging,mng_IHDR,13L);
                PNGLong(data+4,jng_width);
                PNGLong(data+8,jng_height);
                data[12]=jng_alpha_sample_depth;
                data[13]=0; /* color_type gray */
                data[14]=0; /* compression method 0 */
                data[15]=0; /* filter_method 0 */
                data[16]=0; /* interlace_method 0 */
                (void) WriteBlob(alpha_image,17,data);
                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
              }
          }
        reading_idat=MagickTrue;
      }

    if (memcmp(type,mng_JDAT,4) == 0)
      {
        /*
           Copy chunk to color_image->blob
        */

        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Copying JDAT chunk data to color_blob.");

        (void) WriteBlob(color_image,length,chunk);
        if (length)
          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_IDAT,4) == 0)
      {
        png_byte
           data[5];

        /*
           Copy IDAT header and chunk data to alpha_image->blob
        */

        if (image_info->ping == MagickFalse)
          {
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Copying IDAT chunk data to alpha_blob.");

            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
            PNGType(data,mng_IDAT);
            LogPNGChunk((int) logging,mng_IDAT,length);
            (void) WriteBlob(alpha_image,4,data);
            (void) WriteBlob(alpha_image,length,chunk);
            (void) WriteBlobMSBULong(alpha_image,
              crc32(crc32(0,data,4),chunk,(uInt) length));
          }
        if (length)
          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
      {
        /*
           Copy chunk data to alpha_image->blob
        */

        if (image_info->ping == MagickFalse)
          {
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Copying JDAA chunk data to alpha_blob.");

            (void) WriteBlob(alpha_image,length,chunk);
          }
        if (length)
          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_JSEP,4) == 0)
      {
        read_JSEP=MagickTrue;
        if (length)
          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_bKGD,4) == 0)
      {
        if (length == 2)
          {
            image->background_color.red=ScaleCharToQuantum(p[1]);
            image->background_color.green=image->background_color.red;
            image->background_color.blue=image->background_color.red;
          }
        if (length == 6)
          {
            image->background_color.red=ScaleCharToQuantum(p[1]);
            image->background_color.green=ScaleCharToQuantum(p[3]);
            image->background_color.blue=ScaleCharToQuantum(p[5]);
          }
        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_gAMA,4) == 0)
      {
        if (length == 4)
          image->gamma=((float) mng_get_long(p))*0.00001;
        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_cHRM,4) == 0)
      {
        if (length == 32)
          {
            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
          }
        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_sRGB,4) == 0)
      {
        if (length == 1)
          {
            image->rendering_intent=
              PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
            image->gamma=0.45455f;
            image->chromaticity.red_primary.x=0.6400f;
            image->chromaticity.red_primary.y=0.3300f;
            image->chromaticity.green_primary.x=0.3000f;
            image->chromaticity.green_primary.y=0.6000f;
            image->chromaticity.blue_primary.x=0.1500f;
            image->chromaticity.blue_primary.y=0.0600f;
            image->chromaticity.white_point.x=0.3127f;
            image->chromaticity.white_point.y=0.3290f;
          }
        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_oFFs,4) == 0)
      {
        if (length > 8)
          {
            image->page.x=mng_get_long(p);
            image->page.y=mng_get_long(&p[4]);
            if ((int) p[8] != 0)
              {
                image->page.x/=10000;
                image->page.y/=10000;
              }
          }
        if (length)
          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

    if (memcmp(type,mng_pHYs,4) == 0)
      {
        if (length > 8)
          {
            image->x_resolution=(double) mng_get_long(p);
            image->y_resolution=(double) mng_get_long(&p[4]);
            if ((int) p[8] == PNG_RESOLUTION_METER)
              {
                image->units=PixelsPerCentimeterResolution;
                image->x_resolution=image->x_resolution/100.0f;
                image->y_resolution=image->y_resolution/100.0f;
              }
          }
        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }

#if 0
    if (memcmp(type,mng_iCCP,4) == 0)
      {
        /* To do. */
        if (length)
          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
        continue;
      }
#endif

    if (length)
      chunk=(unsigned char *) RelinquishMagickMemory(chunk);

    if (memcmp(type,mng_IEND,4))
      continue;
    break;
  }


  /* IEND found */

  /*
    Finish up reading image data:

       o read main image from color_blob.

       o close color_blob.

       o if (color_type has alpha)
            if alpha_encoding is PNG
               read secondary image from alpha_blob via ReadPNG
            if alpha_encoding is JPEG
               read secondary image from alpha_blob via ReadJPEG

       o close alpha_blob.

       o copy intensity of secondary image into
         opacity samples of main image.

       o destroy the secondary image.
  */

  (void) CloseBlob(color_image);
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "    Reading jng_image from color_blob.");
  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
    color_image->filename);
  color_image_info->ping=MagickFalse;   /* To do: avoid this */
  jng_image=ReadImage(color_image_info,exception);
  if (jng_image == (Image *) NULL)
    return((Image *) NULL);

  (void) RelinquishUniqueFileResource(color_image->filename);
  color_image=DestroyImage(color_image);
  color_image_info=DestroyImageInfo(color_image_info);

  if (jng_image == (Image *) NULL)
    return((Image *) NULL);

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "    Copying jng_image pixels to main image.");
  image->rows=jng_height;
  image->columns=jng_width;
  length=image->columns*sizeof(PixelPacket);
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    (void) CopyMagickMemory(q,s,length);
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
  }
  jng_image=DestroyImage(jng_image);
  if (image_info->ping == MagickFalse)
    {
     if (jng_color_type >= 12)
       {
         if (jng_alpha_compression_method == 0)
           {
             png_byte
               data[5];
             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
             PNGType(data,mng_IEND);
             LogPNGChunk((int) logging,mng_IEND,0L);
             (void) WriteBlob(alpha_image,4,data);
             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
           }
         (void) CloseBlob(alpha_image);
         if (logging != MagickFalse)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "    Reading opacity from alpha_blob.");

         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
           "%s",alpha_image->filename);

         jng_image=ReadImage(alpha_image_info,exception);
         if (jng_image != (Image *) NULL)
           for (y=0; y < (ssize_t) image->rows; y++)
           {
             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
                &image->exception);
             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
             if (image->matte != MagickFalse)
               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
                  q->opacity=(Quantum) QuantumRange-s->red;
             else
               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
               {
                  q->opacity=(Quantum) QuantumRange-s->red;
                  if (q->opacity != OpaqueOpacity)
                    image->matte=MagickTrue;
               }
             if (SyncAuthenticPixels(image,exception) == MagickFalse)
               break;
           }
         (void) RelinquishUniqueFileResource(alpha_image->filename);
         alpha_image=DestroyImage(alpha_image);
         alpha_image_info=DestroyImageInfo(alpha_image_info);
         if (jng_image != (Image *) NULL)
           jng_image=DestroyImage(jng_image);
       }
    }

  /*
    Read the JNG image.
  */
  if (mng_info->mng_type == 0)
    {
      mng_info->mng_width=jng_width;
      mng_info->mng_height=jng_height;
    }
  if (image->page.width == 0 && image->page.height == 0)
  {
    image->page.width=jng_width;
    image->page.height=jng_height;
  }
  if (image->page.x == 0 && image->page.y == 0)
  {
    image->page.x=mng_info->x_off[mng_info->object_id];
    image->page.y=mng_info->y_off[mng_info->object_id];
  }
  else
  {
    image->page.y=mng_info->y_off[mng_info->object_id];
  }
  mng_info->image_found++;
  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
    2*GetBlobSize(image));
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  exit ReadOneJNGImage()");
  return(image);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d J N G I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
%  (including the 8-byte signature)  and returns it.  It allocates the memory
%  necessary for the new Image structure and returns a pointer to the new
%  image.
%
%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
%
%  The format of the ReadJNGImage method is:
%
%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
%         *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/

static Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image,
    *previous;

  MagickBooleanType
    status;

  MngInfo
    *mng_info;

  char
    magic_number[MaxTextExtent];

  int
    have_mng_structure,
    logging;

  size_t
    count;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
  image=AcquireImage(image_info);
  mng_info=(MngInfo *) NULL;
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    return((Image *) NULL);
  if (LocaleCompare(image_info->magick,"JNG") != 0)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  /*
    Verify JNG signature.
  */
  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  /*
    Allocate a MngInfo structure.
  */
  have_mng_structure=MagickFalse;
  mng_info=(MngInfo *) AcquireQuantumMemory(1,sizeof(*mng_info));
  if (mng_info == (MngInfo *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  /*
    Initialize members of the MngInfo structure.
  */
  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
  have_mng_structure=MagickTrue;

  mng_info->image=image;
  previous=image;
  image=ReadOneJNGImage(mng_info,image_info,exception);
  MngInfoFreeStruct(mng_info,&have_mng_structure);
  if (image == (Image *) NULL)
    {
      if (IsImageObject(previous) != MagickFalse)
        {
          (void) CloseBlob(previous);
          (void) DestroyImageList(previous);
        }
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "exit ReadJNGImage() with error");
      return((Image *) NULL);
    }
  (void) CloseBlob(image);
  if (image->columns == 0 || image->rows == 0)
    {
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "exit ReadJNGImage() with error");
      ThrowReaderException(CorruptImageError,"CorruptImage");
    }
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
  return(image);
}
#endif

static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    page_geometry[MaxTextExtent];

  Image
    *image,
    *previous;

  int
    have_mng_structure;

  volatile int
    first_mng_object,
    logging,
    object_id,
    term_chunk_found,
    skip_to_iend;

  volatile ssize_t
    image_count=0;

  MagickBooleanType
    status;

  MagickOffsetType
    offset;

  MngInfo
    *mng_info;

  MngBox
    default_fb,
    fb,
    previous_fb;

#if defined(MNG_INSERT_LAYERS)
  PixelPacket
    mng_background_color;
#endif

  register unsigned char
    *p;

  register ssize_t
    i;

  size_t
    count;

  ssize_t
    loop_level;

  volatile short
    skipping_loop;

#if defined(MNG_INSERT_LAYERS)
  unsigned int
    mandatory_back=0;
#endif

  volatile unsigned int
#ifdef MNG_OBJECT_BUFFERS
    mng_background_object=0,
#endif
    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */

  size_t
    default_frame_timeout,
    frame_timeout,
#if defined(MNG_INSERT_LAYERS)
    image_height,
    image_width,
#endif
    length;

  /* These delays are all measured in image ticks_per_second,
   * not in MNG ticks_per_second
   */
  volatile size_t
    default_frame_delay,
    final_delay,
    final_image_delay,
    frame_delay,
#if defined(MNG_INSERT_LAYERS)
    insert_layers,
#endif
    mng_iterations=1,
    simplicity=0,
    subframe_height=0,
    subframe_width=0;

  previous_fb.top=0;
  previous_fb.bottom=0;
  previous_fb.left=0;
  previous_fb.right=0;
  default_fb.top=0;
  default_fb.bottom=0;
  default_fb.left=0;
  default_fb.right=0;

  /*
    Set image_info->type=OptimizeType (new in version 5.4.0) to get the
    following optimizations:

    o  16-bit depth is reduced to 8 if all pixels contain samples whose
       high byte and low byte are identical.
    o  Opaque matte channel is removed.
    o  If matte channel is present but only one transparent color is
       present, RGB+tRNS is written instead of RGBA
    o  Grayscale images are reduced to 1, 2, or 4 bit depth if
       this can be done without loss.
    o  Palette is sorted to remove unused entries and to put a
       transparent color first, if PNG_SORT_PALETTE is also defined.
   */

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
  image=AcquireImage(image_info);
  mng_info=(MngInfo *) NULL;
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    return((Image *) NULL);
  first_mng_object=MagickFalse;
  skipping_loop=(-1);
  have_mng_structure=MagickFalse;
  /*
    Allocate a MngInfo structure.
  */
  mng_info=(MngInfo *) AcquireQuantumMemory(1,sizeof(MngInfo));
  if (mng_info == (MngInfo *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  /*
    Initialize members of the MngInfo structure.
  */
  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
  mng_info->image=image;
  have_mng_structure=MagickTrue;
#if (MAGICKCORE_QUANTUM_DEPTH == 16)
    mng_info->optimize=image_info->type == OptimizeType;
#endif

  if (LocaleCompare(image_info->magick,"MNG") == 0)
    {
      char
        magic_number[MaxTextExtent];

      /*
        Verify MNG signature.
      */
      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
      /*
        Initialize some nonzero members of the MngInfo structure.
      */
      for (i=0; i < MNG_MAX_OBJECTS; i++)
      {
        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
      }
      mng_info->exists[0]=MagickTrue;
    }
  first_mng_object=MagickTrue;
  mng_type=0;
#if defined(MNG_INSERT_LAYERS)
  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
#endif
  default_frame_delay=0;
  default_frame_timeout=0;
  frame_delay=0;
  final_delay=1;
  mng_info->ticks_per_second=1UL*image->ticks_per_second;
  object_id=0;
  skip_to_iend=MagickFalse;
  term_chunk_found=MagickFalse;
  mng_info->framing_mode=1;
#if defined(MNG_INSERT_LAYERS)
  mandatory_back=MagickFalse;
#endif
#if defined(MNG_INSERT_LAYERS)
  mng_background_color=image->background_color;
#endif
  default_fb=mng_info->frame;
  previous_fb=mng_info->frame;
  do
  {
    char
      type[MaxTextExtent];

    if (LocaleCompare(image_info->magick,"MNG") == 0)
      {
        unsigned char
          *chunk;

        /*
          Read a new chunk.
        */
        type[0]='\0';
        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
        length=ReadBlobMSBLong(image);
        count=(size_t) ReadBlob(image,4,(unsigned char *) type);

        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
           type[0],type[1],type[2],type[3],(double) length);

        if (length > PNG_UINT_31_MAX)
          status=MagickFalse;
        if (count == 0)
          ThrowReaderException(CorruptImageError,"CorruptImage");
        p=NULL;
        chunk=(unsigned char *) NULL;
        if (length)
          {
            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
            if (chunk == (unsigned char *) NULL)
              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
            for (i=0; i < (ssize_t) length; i++)
              chunk[i]=(unsigned char) ReadBlobByte(image);
            p=chunk;
          }
        (void) ReadBlobMSBLong(image);  /* read crc word */

#if !defined(JNG_SUPPORTED)
        if (memcmp(type,mng_JHDR,4) == 0)
          {
            skip_to_iend=MagickTrue;
            if (mng_info->jhdr_warning == 0)
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
            mng_info->jhdr_warning++;
          }
#endif
        if (memcmp(type,mng_DHDR,4) == 0)
          {
            skip_to_iend=MagickTrue;
            if (mng_info->dhdr_warning == 0)
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
            mng_info->dhdr_warning++;
          }
        if (memcmp(type,mng_MEND,4) == 0)
          break;
        if (skip_to_iend)
          {
            if (memcmp(type,mng_IEND,4) == 0)
              skip_to_iend=MagickFalse;
            if (length)
              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "  Skip to IEND.");
            continue;
          }
        if (memcmp(type,mng_MHDR,4) == 0)
          {
            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
                (p[2] << 8) | p[3]);
            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
                (p[6] << 8) | p[7]);
            if (logging != MagickFalse)
              {
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "  MNG width: %.20g",(double) mng_info->mng_width);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "  MNG height: %.20g",(double) mng_info->mng_height);
              }
            p+=8;
            mng_info->ticks_per_second=(size_t) mng_get_long(p);
            if (mng_info->ticks_per_second == 0)
              default_frame_delay=0;
            else
              default_frame_delay=1UL*image->ticks_per_second/
                mng_info->ticks_per_second;
            frame_delay=default_frame_delay;
            simplicity=0;
            if (length > 16)
              {
                p+=16;
                simplicity=(size_t) mng_get_long(p);
              }
            mng_type=1;    /* Full MNG */
            if ((simplicity != 0) && ((simplicity | 11) == 11))
              mng_type=2; /* LC */
            if ((simplicity != 0) && ((simplicity | 9) == 9))
              mng_type=3; /* VLC */
#if defined(MNG_INSERT_LAYERS)
            if (mng_type != 3)
              insert_layers=MagickTrue;
#endif
            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
              {
                /*
                  Allocate next image structure.
                */
                AcquireNextImage(image_info,image);
                if (GetNextImageInList(image) == (Image *) NULL)
                  return((Image *) NULL);
                image=SyncNextImageInList(image);
                mng_info->image=image;
              }

            if ((mng_info->mng_width > 65535L) ||
                (mng_info->mng_height > 65535L))
              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
            (void) FormatMagickString(page_geometry,MaxTextExtent,
              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
              mng_info->mng_height);
            mng_info->frame.left=0;
            mng_info->frame.right=(ssize_t) mng_info->mng_width;
            mng_info->frame.top=0;
            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
            mng_info->clip=default_fb=previous_fb=mng_info->frame;
            for (i=0; i < MNG_MAX_OBJECTS; i++)
              mng_info->object_clip[i]=mng_info->frame;
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }

        if (memcmp(type,mng_TERM,4) == 0)
          {
            int
              repeat=0;


            if (length)
              repeat=p[0];
            if (repeat == 3)
              {
                final_delay=(png_uint_32) mng_get_long(&p[2]);
                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
                if (mng_iterations == PNG_UINT_31_MAX)
                  mng_iterations=0;
                image->iterations=mng_iterations;
                term_chunk_found=MagickTrue;
              }
            if (logging != MagickFalse)
              {
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    repeat=%d",repeat);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    final_delay=%.20g",(double) final_delay);
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    image->iterations=%.20g",(double) image->iterations);
              }
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_DEFI,4) == 0)
          {
            if (mng_type == 3)
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
                image->filename);
            object_id=(p[0] << 8) | p[1];
            if (mng_type == 2 && object_id != 0)
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
                image->filename);
            if (object_id > MNG_MAX_OBJECTS)
              {
                /*
                  Instead ofsuing a warning we should allocate a larger
                  MngInfo structure and continue.
                */
                (void) ThrowMagickException(&image->exception,GetMagickModule(),
                  CoderError,"object id too large","`%s'",image->filename);
                object_id=MNG_MAX_OBJECTS;
              }
            if (mng_info->exists[object_id])
              if (mng_info->frozen[object_id])
                {
                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
                  (void) ThrowMagickException(&image->exception,
                    GetMagickModule(),CoderError,
                    "DEFI cannot redefine a frozen MNG object","`%s'",
                    image->filename);
                  continue;
                }
            mng_info->exists[object_id]=MagickTrue;
            if (length > 2)
              mng_info->invisible[object_id]=p[2];
            /*
              Extract object offset info.
            */
            if (length > 11)
              {
                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) | (p[5] << 16) |
                (p[6] << 8) | p[7]);
                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) | (p[9] << 16) |
                (p[10] << 8) | p[11]);
                if (logging != MagickFalse)
                  {
                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                      "  x_off[%d]: %.20g",object_id,(double)
                      mng_info->x_off[object_id]);
                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                      "  y_off[%d]: %.20g",object_id,(double)
                      mng_info->y_off[object_id]);
                  }
              }
            /*
              Extract object clipping info.
            */
            if (length > 27)
              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
                &p[12]);
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_bKGD,4) == 0)
          {
            mng_info->have_global_bkgd=MagickFalse;
            if (length > 5)
              {
                mng_info->mng_global_bkgd.red=
                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
                mng_info->mng_global_bkgd.green=
                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
                mng_info->mng_global_bkgd.blue=
                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
                mng_info->have_global_bkgd=MagickTrue;
              }
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_BACK,4) == 0)
          {
#if defined(MNG_INSERT_LAYERS)
            if (length > 6)
              mandatory_back=p[6];
            else
              mandatory_back=0;
            if (mandatory_back && length > 5)
              {
                mng_background_color.red=
                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
                mng_background_color.green=
                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
                mng_background_color.blue=
                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
                mng_background_color.opacity=OpaqueOpacity;
              }
#ifdef MNG_OBJECT_BUFFERS
            if (length > 8)
              mng_background_object=(p[7] << 8) | p[8];
#endif
#endif
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_PLTE,4) == 0)
          {
            /*
              Read global PLTE.
            */
            if (length && (length < 769))
              {
                if (mng_info->global_plte == (png_colorp) NULL)
                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
                    sizeof(*mng_info->global_plte));
                for (i=0; i < (ssize_t) (length/3); i++)
                {
                  mng_info->global_plte[i].red=p[3*i];
                  mng_info->global_plte[i].green=p[3*i+1];
                  mng_info->global_plte[i].blue=p[3*i+2];
                }
                mng_info->global_plte_length=(unsigned int) (length/3);
              }
#ifdef MNG_LOOSE
            for ( ; i < 256; i++)
            {
              mng_info->global_plte[i].red=i;
              mng_info->global_plte[i].green=i;
              mng_info->global_plte[i].blue=i;
            }
            if (length)
              mng_info->global_plte_length=256;
#endif
            else
              mng_info->global_plte_length=0;
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_tRNS,4) == 0)
          {
            /* read global tRNS */

            if (length < 257)
              for (i=0; i < (ssize_t) length; i++)
                mng_info->global_trns[i]=p[i];

#ifdef MNG_LOOSE
            for ( ; i < 256; i++)
              mng_info->global_trns[i]=255;
#endif
            mng_info->global_trns_length=(unsigned int) length;
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_gAMA,4) == 0)
          {
            if (length == 4)
              {
                ssize_t
                  igamma;

                igamma=mng_get_long(p);
                mng_info->global_gamma=((float) igamma)*0.00001;
                mng_info->have_global_gama=MagickTrue;
              }
            else
              mng_info->have_global_gama=MagickFalse;
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }

        if (memcmp(type,mng_cHRM,4) == 0)
          {
            /*
              Read global cHRM
            */
            if (length == 32)
              {
                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
                mng_info->global_chrm.red_primary.y=0.00001*
                  mng_get_long(&p[12]);
                mng_info->global_chrm.green_primary.x=0.00001*
                  mng_get_long(&p[16]);
                mng_info->global_chrm.green_primary.y=0.00001*
                  mng_get_long(&p[20]);
                mng_info->global_chrm.blue_primary.x=0.00001*
                  mng_get_long(&p[24]);
                mng_info->global_chrm.blue_primary.y=0.00001*
                  mng_get_long(&p[28]);
                mng_info->have_global_chrm=MagickTrue;
              }
            else
              mng_info->have_global_chrm=MagickFalse;
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_sRGB,4) == 0)
          {
            /*
              Read global sRGB.
            */
            if (length)
              {
                mng_info->global_srgb_intent=
                  PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
                mng_info->have_global_srgb=MagickTrue;
              }
            else
              mng_info->have_global_srgb=MagickFalse;
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_iCCP,4) == 0)
          {
            /* To do. */

            /*
              Read global iCCP.
            */
            if (length)
              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_FRAM,4) == 0)
          {
            if (mng_type == 3)
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
                image->filename);
            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
              image->delay=frame_delay;
            frame_delay=default_frame_delay;
            frame_timeout=default_frame_timeout;
            fb=default_fb;
            if (length)
              if (p[0])
                mng_info->framing_mode=p[0];
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Framing_mode=%d",mng_info->framing_mode);
            if (length > 6)
              {
                /*
                  Note the delay and frame clipping boundaries.
                */
                p++; /* framing mode */
                while (*p && ((p-chunk) < (ssize_t) length))
                  p++;  /* frame name */
                p++;  /* frame name terminator */
                if ((p-chunk) < (ssize_t) (length-4))
                  {
                    int
                      change_delay,
                      change_timeout,
                      change_clipping;

                    change_delay=(*p++);
                    change_timeout=(*p++);
                    change_clipping=(*p++);
                    p++; /* change_sync */
                    if (change_delay)
                      {
                        frame_delay=1UL*image->ticks_per_second*
                          mng_get_long(p);
                        if (mng_info->ticks_per_second != 0)
                          frame_delay/=mng_info->ticks_per_second;
                        else
                          frame_delay=PNG_UINT_31_MAX;
                        if (change_delay == 2)
                          default_frame_delay=frame_delay;
                        p+=4;
                        if (logging != MagickFalse)
                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                            "    Framing_delay=%.20g",(double) frame_delay);
                      }
                    if (change_timeout)
                      {
                        frame_timeout=1UL*image->ticks_per_second*
                          mng_get_long(p);
                        if (mng_info->ticks_per_second != 0)
                          frame_timeout/=mng_info->ticks_per_second;
                        else
                          frame_timeout=PNG_UINT_31_MAX;
                        if (change_delay == 2)
                          default_frame_timeout=frame_timeout;
                        p+=4;
                        if (logging != MagickFalse)
                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                            "    Framing_timeout=%.20g",(double) frame_timeout);
                      }
                    if (change_clipping)
                      {
                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
                        p+=17;
                        previous_fb=fb;
                        if (logging != MagickFalse)
                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                            "    Frame_clipping: L=%.20g R=%.20g T=%.20g B=%.20g",
                            (double) fb.left,(double) fb.right,(double) fb.top,
                            (double) fb.bottom);
                        if (change_clipping == 2)
                          default_fb=fb;
                      }
                  }
              }
            mng_info->clip=fb;
            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
            subframe_width=(size_t) (mng_info->clip.right
               -mng_info->clip.left);
            subframe_height=(size_t) (mng_info->clip.bottom
               -mng_info->clip.top);
            /*
              Insert a background layer behind the frame if framing_mode is 4.
            */
#if defined(MNG_INSERT_LAYERS)
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "   subframe_width=%.20g, subframe_height=%.20g",(double)
                subframe_width,(double) subframe_height);
            if (insert_layers && (mng_info->framing_mode == 4) &&
                (subframe_width) && (subframe_height))
              {
                /*
                  Allocate next image structure.
                */
                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
                  {
                    AcquireNextImage(image_info,image);
                    if (GetNextImageInList(image) == (Image *) NULL)
                      {
                        image=DestroyImageList(image);
                        MngInfoFreeStruct(mng_info,&have_mng_structure);
                        return((Image *) NULL);
                      }
                    image=SyncNextImageInList(image);
                  }
                mng_info->image=image;
                if (term_chunk_found)
                  {
                    image->start_loop=MagickTrue;
                    image->iterations=mng_iterations;
                    term_chunk_found=MagickFalse;
                  }
                else
                    image->start_loop=MagickFalse;
                image->columns=subframe_width;
                image->rows=subframe_height;
                image->page.width=subframe_width;
                image->page.height=subframe_height;
                image->page.x=mng_info->clip.left;
                image->page.y=mng_info->clip.top;
                image->background_color=mng_background_color;
                image->matte=MagickFalse;
                image->delay=0;
                (void) SetImageBackgroundColor(image);
                if (logging != MagickFalse)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "  Inserted background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
                    (double) mng_info->clip.left,(double) mng_info->clip.right,
                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
              }
#endif
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_CLIP,4) == 0)
          {
            unsigned int
              first_object,
              last_object;

            /*
              Read CLIP.
            */
            first_object=(p[0] << 8) | p[1];
            last_object=(p[2] << 8) | p[3];
            for (i=(int) first_object; i <= (int) last_object; i++)
            {
              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]);
                }
            }
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_SAVE,4) == 0)
          {
            for (i=1; i < MNG_MAX_OBJECTS; i++)
              if (mng_info->exists[i])
                {
                 mng_info->frozen[i]=MagickTrue;
#ifdef MNG_OBJECT_BUFFERS
                 if (mng_info->ob[i] != (MngBuffer *) NULL)
                    mng_info->ob[i]->frozen=MagickTrue;
#endif
                }
            if (length)
              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }

        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
          {
            /*
              Read DISC or SEEK.
            */
            if ((length == 0) || !memcmp(type,mng_SEEK,4))
              {
                for (i=1; i < MNG_MAX_OBJECTS; i++)
                  MngInfoDiscardObject(mng_info,i);
              }
            else
              {
                register ssize_t
                  j;

                for (j=0; j < (ssize_t) length; j+=2)
                {
                  i=p[j] << 8 | p[j+1];
                  MngInfoDiscardObject(mng_info,i);
                }
              }
            if (length)
              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_MOVE,4) == 0)
          {
            size_t
              first_object,
              last_object;

            /*
              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 (mng_info->exists[i] && !mng_info->frozen[i])
                {
                  MngPair
                    new_pair;

                  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[4],&p[5]);
                  mng_info->x_off[i]=new_pair.a;
                  mng_info->y_off[i]=new_pair.b;
                }
            }
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }

        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 */
            /*
              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 (loop_iters == 0)
              skipping_loop=loop_level;
            else
              {
                mng_info->loop_jump[loop_level]=TellBlob(image);
                mng_info->loop_count[loop_level]=loop_iters;
              }
            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 (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)
                  {
                    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 iterations ",
                        (double) loop_level,(double)
                        mng_info->loop_count[loop_level]);
                    if (mng_info->loop_count[loop_level] != 0)
                      {
                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
                          SEEK_SET);
                        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;
                      }
                  }
              }
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_CLON,4) == 0)
          {
            if (mng_info->clon_warning == 0)
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                CoderError,"CLON is not implemented yet","`%s'",
                image->filename);
            mng_info->clon_warning++;
          }
        if (memcmp(type,mng_MAGN,4) == 0)
          {
            png_uint_16
              magn_first,
              magn_last,
              magn_mb,
              magn_ml,
              magn_mr,
              magn_mt,
              magn_mx,
              magn_my,
              magn_methx,
              magn_methy;

            if (length > 1)
              magn_first=(p[0] << 8) | p[1];
            else
              magn_first=0;
            if (length > 3)
              magn_last=(p[2] << 8) | p[3];
            else
              magn_last=magn_first;
#ifndef MNG_OBJECT_BUFFERS
            if (magn_first || magn_last)
              if (mng_info->magn_warning == 0)
                {
                  (void) ThrowMagickException(&image->exception,
                     GetMagickModule(),CoderError,
                     "MAGN is not implemented yet for nonzero objects",
                     "`%s'",image->filename);
                   mng_info->magn_warning++;
                }
#endif
            if (length > 4)
              magn_methx=p[4];
            else
              magn_methx=0;

            if (length > 6)
              magn_mx=(p[5] << 8) | p[6];
            else
              magn_mx=1;
            if (magn_mx == 0)
              magn_mx=1;

            if (length > 8)
              magn_my=(p[7] << 8) | p[8];
            else
              magn_my=magn_mx;
            if (magn_my == 0)
              magn_my=1;

            if (length > 10)
              magn_ml=(p[9] << 8) | p[10];
            else
              magn_ml=magn_mx;
            if (magn_ml == 0)
              magn_ml=1;

            if (length > 12)
              magn_mr=(p[11] << 8) | p[12];
            else
              magn_mr=magn_mx;
            if (magn_mr == 0)
              magn_mr=1;

            if (length > 14)
              magn_mt=(p[13] << 8) | p[14];
            else
              magn_mt=magn_my;
            if (magn_mt == 0)
              magn_mt=1;

            if (length > 16)
              magn_mb=(p[15] << 8) | p[16];
            else
              magn_mb=magn_my;
            if (magn_mb == 0)
              magn_mb=1;

            if (length > 17)
              magn_methy=p[17];
            else
              magn_methy=magn_methx;

            if (magn_methx > 5 || magn_methy > 5)
              if (mng_info->magn_warning == 0)
                {
                  (void) ThrowMagickException(&image->exception,
                     GetMagickModule(),CoderError,
                     "Unknown MAGN method in MNG datastream","`%s'",
                     image->filename);
                   mng_info->magn_warning++;
                }
#ifdef MNG_OBJECT_BUFFERS
          /* Magnify existing objects in the range magn_first to magn_last */
#endif
            if (magn_first == 0 || magn_last == 0)
              {
                /* Save the magnification factors for object 0 */
                mng_info->magn_mb=magn_mb;
                mng_info->magn_ml=magn_ml;
                mng_info->magn_mr=magn_mr;
                mng_info->magn_mt=magn_mt;
                mng_info->magn_mx=magn_mx;
                mng_info->magn_my=magn_my;
                mng_info->magn_methx=magn_methx;
                mng_info->magn_methy=magn_methy;
              }
          }
        if (memcmp(type,mng_PAST,4) == 0)
          {
            if (mng_info->past_warning == 0)
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                CoderError,"PAST is not implemented yet","`%s'",
                image->filename);
            mng_info->past_warning++;
          }
        if (memcmp(type,mng_SHOW,4) == 0)
          {
            if (mng_info->show_warning == 0)
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                CoderError,"SHOW is not implemented yet","`%s'",
                image->filename);
            mng_info->show_warning++;
          }
        if (memcmp(type,mng_sBIT,4) == 0)
          {
            if (length < 4)
              mng_info->have_global_sbit=MagickFalse;
            else
              {
                mng_info->global_sbit.gray=p[0];
                mng_info->global_sbit.red=p[0];
                mng_info->global_sbit.green=p[1];
                mng_info->global_sbit.blue=p[2];
                mng_info->global_sbit.alpha=p[3];
                mng_info->have_global_sbit=MagickTrue;
             }
          }
        if (memcmp(type,mng_pHYs,4) == 0)
          {
            if (length > 8)
              {
                mng_info->global_x_pixels_per_unit=
                    (size_t) mng_get_long(p);
                mng_info->global_y_pixels_per_unit=
                    (size_t) mng_get_long(&p[4]);
                mng_info->global_phys_unit_type=p[8];
                mng_info->have_global_phys=MagickTrue;
              }
            else
              mng_info->have_global_phys=MagickFalse;
          }
        if (memcmp(type,mng_pHYg,4) == 0)
          {
            if (mng_info->phyg_warning == 0)
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                CoderError,"pHYg is not implemented.","`%s'",image->filename);
            mng_info->phyg_warning++;
          }
        if (memcmp(type,mng_BASI,4) == 0)
          {
            skip_to_iend=MagickTrue;
            if (mng_info->basi_warning == 0)
              (void) ThrowMagickException(&image->exception,GetMagickModule(),
                CoderError,"BASI is not implemented yet","`%s'",
                image->filename);
            mng_info->basi_warning++;
#ifdef MNG_BASI_SUPPORTED
            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
               (p[2] << 8) | p[3]);
            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
               (p[6] << 8) | p[7]);
            basi_color_type=p[8];
            basi_compression_method=p[9];
            basi_filter_type=p[10];
            basi_interlace_method=p[11];
            if (length > 11)
              basi_red=(p[12] << 8) & p[13];
            else
              basi_red=0;
            if (length > 13)
              basi_green=(p[14] << 8) & p[15];
            else
              basi_green=0;
            if (length > 15)
              basi_blue=(p[16] << 8) & p[17];
            else
              basi_blue=0;
            if (length > 17)
              basi_alpha=(p[18] << 8) & p[19];
            else
              {
                if (basi_sample_depth == 16)
                  basi_alpha=65535L;
                else
                  basi_alpha=255;
              }
            if (length > 19)
              basi_viewable=p[20];
            else
              basi_viewable=0;
#endif
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
        if (memcmp(type,mng_IHDR,4)
#if defined(JNG_SUPPORTED)
            && memcmp(type,mng_JHDR,4)
#endif
            )
          {
            /* Not an IHDR or JHDR chunk */
            if (length)
              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
/* Process IHDR */
        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
        mng_info->exists[object_id]=MagickTrue;
        mng_info->viewable[object_id]=MagickTrue;
        if (mng_info->invisible[object_id])
          {
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "  Skipping invisible object");
            skip_to_iend=MagickTrue;
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
            continue;
          }
#if defined(MNG_INSERT_LAYERS)
        if (length < 8)
          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
        image_width=(size_t) mng_get_long(p);
        image_height=(size_t) mng_get_long(&p[4]);
#endif
        chunk=(unsigned char *) RelinquishMagickMemory(chunk);

        /*
          Insert a transparent background layer behind the entire animation
          if it is not full screen.
        */
#if defined(MNG_INSERT_LAYERS)
        if (insert_layers && mng_type && first_mng_object)
          {
            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
                (image_width < mng_info->mng_width) ||
                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
                (image_height < mng_info->mng_height) ||
                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
              {
                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
                  {
                    /*
                      Allocate next image structure.
                    */
                    AcquireNextImage(image_info,image);
                    if (GetNextImageInList(image) == (Image *) NULL)
                      {
                        image=DestroyImageList(image);
                        MngInfoFreeStruct(mng_info,&have_mng_structure);
                        return((Image *) NULL);
                      }
                    image=SyncNextImageInList(image);
                  }
                mng_info->image=image;
                if (term_chunk_found)
                  {
                    image->start_loop=MagickTrue;
                    image->iterations=mng_iterations;
                    term_chunk_found=MagickFalse;
                  }
                else
                    image->start_loop=MagickFalse;
                /*
                  Make a background rectangle.
                */
                image->delay=0;
                image->columns=mng_info->mng_width;
                image->rows=mng_info->mng_height;
                image->page.width=mng_info->mng_width;
                image->page.height=mng_info->mng_height;
                image->page.x=0;
                image->page.y=0;
                image->background_color=mng_background_color;
                (void) SetImageBackgroundColor(image);
                if (logging != MagickFalse)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
                    (double) mng_info->mng_width,(double) mng_info->mng_height);
              }
          }
        /*
          Insert a background layer behind the upcoming image if
          framing_mode is 3, and we haven't already inserted one.
        */
        if (insert_layers && (mng_info->framing_mode == 3) &&
                (subframe_width) && (subframe_height) && (simplicity == 0 ||
                (simplicity & 0x08)))
          {
            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
            {
              /*
                Allocate next image structure.
              */
              AcquireNextImage(image_info,image);
              if (GetNextImageInList(image) == (Image *) NULL)
                {
                  image=DestroyImageList(image);
                  MngInfoFreeStruct(mng_info,&have_mng_structure);
                  return((Image *) NULL);
                }
              image=SyncNextImageInList(image);
            }
            mng_info->image=image;
            if (term_chunk_found)
              {
                image->start_loop=MagickTrue;
                image->iterations=mng_iterations;
                term_chunk_found=MagickFalse;
              }
            else
                image->start_loop=MagickFalse;
            image->delay=0;
            image->columns=subframe_width;
            image->rows=subframe_height;
            image->page.width=subframe_width;
            image->page.height=subframe_height;
            image->page.x=mng_info->clip.left;
            image->page.y=mng_info->clip.top;
            image->background_color=mng_background_color;
            image->matte=MagickFalse;
            (void) SetImageBackgroundColor(image);
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "  Inserted background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
                (double) mng_info->clip.left,(double) mng_info->clip.right,
                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
          }
#endif /* MNG_INSERT_LAYERS */
        first_mng_object=MagickFalse;
        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
          {
            /*
              Allocate next image structure.
            */
            AcquireNextImage(image_info,image);
            if (GetNextImageInList(image) == (Image *) NULL)
              {
                image=DestroyImageList(image);
                MngInfoFreeStruct(mng_info,&have_mng_structure);
                return((Image *) NULL);
              }
            image=SyncNextImageInList(image);
          }
        mng_info->image=image;
        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
          GetBlobSize(image));
        if (status == MagickFalse)
          break;
        if (term_chunk_found)
          {
            image->start_loop=MagickTrue;
            term_chunk_found=MagickFalse;
          }
        else
            image->start_loop=MagickFalse;
        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
          {
            image->delay=frame_delay;
            frame_delay=default_frame_delay;
          }
        else
          image->delay=0;
        image->page.width=mng_info->mng_width;
        image->page.height=mng_info->mng_height;
        image->page.x=mng_info->x_off[object_id];
        image->page.y=mng_info->y_off[object_id];
        image->iterations=mng_iterations;
        /*
          Seek back to the beginning of the IHDR or JHDR chunk's length field.
        */
        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
            type[2],type[3]);
        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
        if (offset < 0)
          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
      }

    previous=image;
    mng_info->image=image;
    mng_info->mng_type=mng_type;
    mng_info->object_id=object_id;

    if (memcmp(type,mng_IHDR,4) == 0)
      image=ReadOnePNGImage(mng_info,image_info,exception);
#if defined(JNG_SUPPORTED)
    else
      image=ReadOneJNGImage(mng_info,image_info,exception);
#endif

    if (image == (Image *) NULL)
      {
        if (IsImageObject(previous) != MagickFalse)
          {
            (void) DestroyImageList(previous);
            (void) CloseBlob(previous);
          }
        MngInfoFreeStruct(mng_info,&have_mng_structure);
        return((Image *) NULL);
      }
    if (image->columns == 0 || image->rows == 0)
      {
        (void) CloseBlob(image);
        image=DestroyImageList(image);
        MngInfoFreeStruct(mng_info,&have_mng_structure);
        return((Image *) NULL);
      }
    mng_info->image=image;

    if (mng_type)
      {
        MngBox
          crop_box;

        if (mng_info->magn_methx || mng_info->magn_methy)
          {
            png_uint_32
               magnified_height,
               magnified_width;

            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "  Processing MNG MAGN chunk");

            if (mng_info->magn_methx == 1)
              {
                magnified_width=mng_info->magn_ml;
                if (image->columns > 1)
                   magnified_width += mng_info->magn_mr;
                if (image->columns > 2)
                   magnified_width += (png_uint_32) ((image->columns-2)*(mng_info->magn_mx));
              }
            else
              {
                magnified_width=(png_uint_32) image->columns;
                if (image->columns > 1)
                   magnified_width += mng_info->magn_ml-1;
                if (image->columns > 2)
                   magnified_width += mng_info->magn_mr-1;
                if (image->columns > 3)
                   magnified_width += (png_uint_32) ((image->columns-3)*(mng_info->magn_mx-1));
              }
            if (mng_info->magn_methy == 1)
              {
                magnified_height=mng_info->magn_mt;
                if (image->rows > 1)
                   magnified_height += mng_info->magn_mb;
                if (image->rows > 2)
                   magnified_height += (png_uint_32) ((image->rows-2)*(mng_info->magn_my));
              }
            else
              {
                magnified_height=(png_uint_32) image->rows;
                if (image->rows > 1)
                   magnified_height += mng_info->magn_mt-1;
                if (image->rows > 2)
                   magnified_height += mng_info->magn_mb-1;
                if (image->rows > 3)
                   magnified_height += (png_uint_32) ((image->rows-3)*(mng_info->magn_my-1));
              }
            if (magnified_height > image->rows ||
                magnified_width > image->columns)
              {
                Image
                  *large_image;

                int
                  yy;

                ssize_t
                  m,
                  y;

                register ssize_t
                  x;

                register PixelPacket
                  *n,
                  *q;

                PixelPacket
                  *next,
                  *prev;

                png_uint_16
                  magn_methx,
                  magn_methy;

                /*
                  Allocate next image structure.
                */
                if (logging != MagickFalse)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "    Allocate magnified image");
                AcquireNextImage(image_info,image);
                if (GetNextImageInList(image) == (Image *) NULL)
                  {
                    image=DestroyImageList(image);
                    MngInfoFreeStruct(mng_info,&have_mng_structure);
                    return((Image *) NULL);
                  }

                large_image=SyncNextImageInList(image);

                large_image->columns=magnified_width;
                large_image->rows=magnified_height;

                magn_methx=mng_info->magn_methx;
                magn_methy=mng_info->magn_methy;

#if (MAGICKCORE_QUANTUM_DEPTH == 32)
#define QM unsigned short
                if (magn_methx != 1 || magn_methy != 1)
                  {
                  /*
                     Scale pixels to unsigned shorts to prevent
                     overflow of intermediate values of interpolations
                  */
                     for (y=0; y < (ssize_t) image->rows; y++)
                     {
                       q=GetAuthenticPixels(image,0,y,image->columns,1,
                          exception);
                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
                       {
                          q->red=ScaleQuantumToShort(q->red);
                          q->green=ScaleQuantumToShort(q->green);
                          q->blue=ScaleQuantumToShort(q->blue);
                          q->opacity=ScaleQuantumToShort(q->opacity);
                          q++;
                       }
                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
                         break;
                     }
                  }
#else
#define QM Quantum
#endif

                if (image->matte != MagickFalse)
                   (void) SetImageBackgroundColor(large_image);
                else
                  {
                    large_image->background_color.opacity=OpaqueOpacity;
                    (void) SetImageBackgroundColor(large_image);
                    if (magn_methx == 4)
                      magn_methx=2;
                    if (magn_methx == 5)
                      magn_methx=3;
                    if (magn_methy == 4)
                      magn_methy=2;
                    if (magn_methy == 5)
                      magn_methy=3;
                  }

                /* magnify the rows into the right side of the large image */

                if (logging != MagickFalse)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "    Magnify the rows to %.20g",(double) large_image->rows);
                m=(ssize_t) mng_info->magn_mt;
                yy=0;
                length=(size_t) image->columns;
                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
                if ((prev == (PixelPacket *) NULL) ||
                    (next == (PixelPacket *) NULL))
                  {
                     image=DestroyImageList(image);
                     MngInfoFreeStruct(mng_info,&have_mng_structure);
                     ThrowReaderException(ResourceLimitError,
                       "MemoryAllocationFailed");
                  }
                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
                (void) CopyMagickMemory(next,n,length);
                for (y=0; y < (ssize_t) image->rows; y++)
                {
                  if (y == 0)
                    m=(ssize_t) mng_info->magn_mt;
                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
                    m=(ssize_t) mng_info->magn_mb;
                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
                    m=(ssize_t) mng_info->magn_mb;
                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
                    m=1;
                  else
                    m=(ssize_t) mng_info->magn_my;
                  n=prev;
                  prev=next;
                  next=n;
                  if (y < (ssize_t) image->rows-1)
                    {
                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
                          exception);
                      (void) CopyMagickMemory(next,n,length);
                    }
                  for (i=0; i < m; i++, yy++)
                  {
                    register PixelPacket
                      *pixels;

                    assert(yy < (ssize_t) large_image->rows);
                    pixels=prev;
                    n=next;
                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
                          1,exception);
                    q+=(large_image->columns-image->columns);
                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
                    {
                      /* TO DO: get color as function of indexes[x] */
                      /*
                      if (image->storage_class == PseudoClass)
                        {
                        }
                      */

                      if (magn_methy <= 1)
                        {
                          *q=(*pixels); /* replicate previous */
                        }
                      else if (magn_methy == 2 || magn_methy == 4)
                        {
                          if (i == 0)
                             *q=(*pixels);
                          else
                            {
                              /* Interpolate */
                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
                                 -(*pixels).red)+m))/((ssize_t) (m*2))
                                 +(*pixels).red);
                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
                                 -(*pixels).green)+m))/((ssize_t) (m*2))
                                 +(*pixels).green);
                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
                                 +(*pixels).blue);
                              if (image->matte != MagickFalse)
                                 (*q).opacity=(QM) (((ssize_t)
                                 (2*i*((*n).opacity
                                 -(*pixels).opacity)+m))
                                 /((ssize_t) (m*2))+(*pixels).opacity);
                            }
                          if (magn_methy == 4)
                            {
                              /* Replicate nearest */
                              if (i <= ((m+1) << 1))
                                 (*q).opacity=(*pixels).opacity+0;
                              else
                                 (*q).opacity=(*n).opacity+0;
                            }
                        }
                      else /* if (magn_methy == 3 || magn_methy == 5) */
                        {
                          /* Replicate nearest */
                          if (i <= ((m+1) << 1))
                             *q=(*pixels);
                          else
                             *q=(*n);
                          if (magn_methy == 5)
                            {
                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
                                 +(*pixels).opacity);
                            }
                        }
                      n++;
                      q++;
                      pixels++;
                    } /* x */
                    if (SyncAuthenticPixels(large_image,exception) == 0)
                      break;
                  } /* i */
                } /* y */
                prev=(PixelPacket *) RelinquishMagickMemory(prev);
                next=(PixelPacket *) RelinquishMagickMemory(next);

                length=image->columns;

                if (logging != MagickFalse)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "    Delete original image");

                DeleteImageFromList(&image);

                image=large_image;

                mng_info->image=image;

                /* magnify the columns */
                if (logging != MagickFalse)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "    Magnify the columns to %.20g",(double) image->columns);

                for (y=0; y < (ssize_t) image->rows; y++)
                {
                  register PixelPacket
                    *pixels;

                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
                  pixels=q+(image->columns-length);
                  n=pixels+1;
                  for (x=(ssize_t) (image->columns-length);
                    x < (ssize_t) image->columns; x++)
                  {
                    if (x == (ssize_t) (image->columns-length))
                      m=(ssize_t) mng_info->magn_ml;
                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
                      m=(ssize_t) mng_info->magn_mr;
                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
                      m=(ssize_t) mng_info->magn_mr;
                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
                      m=1;
                    else
                      m=(ssize_t) mng_info->magn_mx;
                    for (i=0; i < m; i++)
                    {
                      if (magn_methx <= 1)
                        {
                          /* replicate previous */
                          *q=(*pixels);
                        }
                      else if (magn_methx == 2 || magn_methx == 4)
                        {
                          if (i == 0)
                            *q=(*pixels);
                          else
                            {
                              /* Interpolate */
                              (*q).red=(QM) ((2*i*((*n).red
                                 -(*pixels).red)+m)
                                 /((ssize_t) (m*2))+(*pixels).red);
                              (*q).green=(QM) ((2*i*((*n).green
                                 -(*pixels).green)
                                 +m)/((ssize_t) (m*2))+(*pixels).green);
                              (*q).blue=(QM) ((2*i*((*n).blue
                                 -(*pixels).blue)+m)
                                 /((ssize_t) (m*2))+(*pixels).blue);
                              if (image->matte != MagickFalse)
                                 (*q).opacity=(QM) ((2*i*((*n).opacity
                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
                                   +(*pixels).opacity);
                            }
                          if (magn_methx == 4)
                            {
                              /* Replicate nearest */
                              if (i <= ((m+1) << 1))
                                 (*q).opacity=(*pixels).opacity+0;
                              else
                                 (*q).opacity=(*n).opacity+0;
                            }
                        }
                      else /* if (magn_methx == 3 || magn_methx == 5) */
                        {
                          /* Replicate nearest */
                          if (i <= ((m+1) << 1))
                             *q=(*pixels);
                          else
                             *q=(*n);
                          if (magn_methx == 5)
                            {
                              /* Interpolate */
                              (*q).opacity=(QM) ((2*i*((*n).opacity
                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
                                 +(*pixels).opacity);
                            }
                        }
                      q++;
                    }
                    n++;
                    p++;
                  }
                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
                    break;
                }
#if (MAGICKCORE_QUANTUM_DEPTH == 32)
              if (magn_methx != 1 || magn_methy != 1)
                {
                /*
                   Rescale pixels to Quantum
                */
                   for (y=0; y < (ssize_t) image->rows; y++)
                   {
                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
                     {
                        q->red=ScaleShortToQuantum(q->red);
                        q->green=ScaleShortToQuantum(q->green);
                        q->blue=ScaleShortToQuantum(q->blue);
                        q->opacity=ScaleShortToQuantum(q->opacity);
                        q++;
                     }
                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
                       break;
                   }
                }
#endif
                if (logging != MagickFalse)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "  Finished MAGN processing");
              }
          }

        /*
          Crop_box is with respect to the upper left corner of the MNG.
        */
        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
        crop_box=mng_minimum_box(crop_box,mng_info->clip);
        crop_box=mng_minimum_box(crop_box,mng_info->frame);
        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
        if ((crop_box.left != (mng_info->image_box.left
            +mng_info->x_off[object_id])) ||
            (crop_box.right != (mng_info->image_box.right
            +mng_info->x_off[object_id])) ||
            (crop_box.top != (mng_info->image_box.top
            +mng_info->y_off[object_id])) ||
            (crop_box.bottom != (mng_info->image_box.bottom
            +mng_info->y_off[object_id])))
          {
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "  Crop the PNG image");
            if ((crop_box.left < crop_box.right) &&
                (crop_box.top < crop_box.bottom))
              {
                Image
                  *im;

                RectangleInfo
                  crop_info;

                /*
                  Crop_info is with respect to the upper left corner of
                  the image.
                */
                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
                crop_info.width=(size_t) (crop_box.right-crop_box.left);
                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
                image->page.width=image->columns;
                image->page.height=image->rows;
                image->page.x=0;
                image->page.y=0;
                im=CropImage(image,&crop_info,exception);
                if (im != (Image *) NULL)
                  {
                    image->columns=im->columns;
                    image->rows=im->rows;
                    im=DestroyImage(im);
                    image->page.width=image->columns;
                    image->page.height=image->rows;
                    image->page.x=crop_box.left;
                    image->page.y=crop_box.top;
                  }
              }
            else
              {
                /*
                  No pixels in crop area.  The MNG spec still requires
                  a layer, though, so make a single transparent pixel in
                  the top left corner.
                */
                image->columns=1;
                image->rows=1;
                image->colors=2;
                (void) SetImageBackgroundColor(image);
                image->page.width=1;
                image->page.height=1;
                image->page.x=0;
                image->page.y=0;
              }
          }
#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
        image=mng_info->image;
#endif
      }

#if (MAGICKCORE_QUANTUM_DEPTH == 16)  /* TO DO: treat Q:32 */
    /* Determine if bit depth can be reduced from 16 to 8.
     * Note that the method GetImageDepth doesn't check background
     * and doesn't handle PseudoClass specially.  Also it uses
     * multiplication and division by 257 instead of shifting, so
     * might be slower.
     */
    if (mng_info->optimize && image->depth == 16)
      {
        int
          ok_to_reduce;

        const PixelPacket
          *p;

        ok_to_reduce=(((((size_t) image->background_color.red >> 8) &
                     0xff)
          == ((size_t) image->background_color.red & 0xff)) &&
           ((((size_t) image->background_color.green >> 8) & 0xff)
          == ((size_t) image->background_color.green & 0xff)) &&
           ((((size_t) image->background_color.blue >> 8) & 0xff)
          == ((size_t) image->background_color.blue & 0xff)));
        if (ok_to_reduce && image->storage_class == PseudoClass)
          {
            int indx;

            for (indx=0; indx < (ssize_t) image->colors; indx++)
              {
                ok_to_reduce=(((((size_t) image->colormap[indx].red >>
                    8) & 0xff)
                  == ((size_t) image->colormap[indx].red & 0xff)) &&
                  ((((size_t) image->colormap[indx].green >> 8) & 0xff)
                  == ((size_t) image->colormap[indx].green & 0xff)) &&
                  ((((size_t) image->colormap[indx].blue >> 8) & 0xff)
                  == ((size_t) image->colormap[indx].blue & 0xff)));
                if (ok_to_reduce == MagickFalse)
                  break;
              }
          }
        if ((ok_to_reduce != MagickFalse) &&
            (image->storage_class != PseudoClass))
          {
            ssize_t
              y;

            register ssize_t
              x;

            for (y=0; y < (ssize_t) image->rows; y++)
            {
              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
              if (p == (const PixelPacket *) NULL)
                break;
              for (x=(ssize_t) image->columns-1; x >= 0; x--)
              {
                ok_to_reduce=((
                  (((size_t) p->red >> 8) & 0xff) ==
                  ((size_t) p->red & 0xff)) &&
                  ((((size_t) p->green >> 8) & 0xff) ==
                  ((size_t) p->green & 0xff)) &&
                  ((((size_t) p->blue >> 8) & 0xff) ==
                  ((size_t) p->blue & 0xff)) &&
                  (((!image->matte ||
                  (((size_t) p->opacity >> 8) & 0xff) ==
                  ((size_t) p->opacity & 0xff)))));
                if (ok_to_reduce == 0)
                  break;
                p++;
              }
              if (x != 0)
                break;
            }
          }
        if (ok_to_reduce)
          {
            image->depth=8;
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "  Reducing PNG bit depth to 8 without loss of info");
          }
      }
#endif
      GetImageException(image,exception);
      if (image_info->number_scenes != 0)
        {
          if (mng_info->scenes_found >
             (ssize_t) (image_info->first_scene+image_info->number_scenes))
            break;
        }
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "  Finished reading image datastream.");
  } while (LocaleCompare(image_info->magick,"MNG") == 0);
  (void) CloseBlob(image);
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Finished reading all image datastreams.");
#if defined(MNG_INSERT_LAYERS)
  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
       (mng_info->mng_height))
    {
      /*
        Insert a background layer if nothing else was found.
      */
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "  No images found.  Inserting a background layer.");
      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
        {
          /*
            Allocate next image structure.
          */
          AcquireNextImage(image_info,image);
          if (GetNextImageInList(image) == (Image *) NULL)
            {
              image=DestroyImageList(image);
              MngInfoFreeStruct(mng_info,&have_mng_structure);
              if (logging != MagickFalse)
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "  Allocation failed, returning NULL.");
              return((Image *) NULL);
            }
          image=SyncNextImageInList(image);
        }
      image->columns=mng_info->mng_width;
      image->rows=mng_info->mng_height;
      image->page.width=mng_info->mng_width;
      image->page.height=mng_info->mng_height;
      image->page.x=0;
      image->page.y=0;
      image->background_color=mng_background_color;
      image->matte=MagickFalse;
      if (image_info->ping == MagickFalse)
        (void) SetImageBackgroundColor(image);
      mng_info->image_found++;
    }
#endif
  image->iterations=mng_iterations;
  if (mng_iterations == 1)
    image->start_loop=MagickTrue;
  while (GetPreviousImageInList(image) != (Image *) NULL)
  {
    image_count++;
    if (image_count > 10*mng_info->image_found)
      {
        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
        (void) ThrowMagickException(&image->exception,GetMagickModule(),
          CoderError,"Linked list is corrupted, beginning of list not found",
          "`%s'",image_info->filename);
        return((Image *) NULL);
      }
    image=GetPreviousImageInList(image);
    if (GetNextImageInList(image) == (Image *) NULL)
      {
        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
        (void) ThrowMagickException(&image->exception,GetMagickModule(),
          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
          image_info->filename);
      }
  }
  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
             GetNextImageInList(image) ==
     (Image *) NULL)
    {
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  First image null");
      (void) ThrowMagickException(&image->exception,GetMagickModule(),
        CoderError,"image->next for first image is NULL but shouldn't be.",
        "`%s'",image_info->filename);
    }
  if (mng_info->image_found == 0)
    {
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "  No visible images found.");
      (void) ThrowMagickException(&image->exception,GetMagickModule(),
        CoderError,"No visible images in file","`%s'",image_info->filename);
      if (image != (Image *) NULL)
        image=DestroyImageList(image);
      MngInfoFreeStruct(mng_info,&have_mng_structure);
      return((Image *) NULL);
    }

  if (mng_info->ticks_per_second)
    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
            final_delay/mng_info->ticks_per_second;
  else
    image->start_loop=MagickTrue;
  /* Find final nonzero image delay */
  final_image_delay=0;
  while (GetNextImageInList(image) != (Image *) NULL)
    {
      if (image->delay)
        final_image_delay=image->delay;
      image=GetNextImageInList(image);
    }
  if (final_delay < final_image_delay)
    final_delay=final_image_delay;
  image->delay=final_delay;
  if (logging != MagickFalse)
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
        (double) final_delay);
  if (logging != MagickFalse)
    {
      int
        scene;

      scene=0;
      image=GetFirstImageInList(image);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Before coalesce:");
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    scene 0 delay=%.20g",(double) image->delay);
      while (GetNextImageInList(image) != (Image *) NULL)
      {
        image=GetNextImageInList(image);
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
      }
    }

  image=GetFirstImageInList(image);
#ifdef MNG_COALESCE_LAYERS
  if (insert_layers)
    {
      Image
        *next_image,
        *next;

      size_t
        scene;

      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
      scene=image->scene;
      next_image=CoalesceImages(image,&image->exception);
      if (next_image == (Image *) NULL)
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
      image=DestroyImageList(image);
      image=next_image;
      for (next=image; next != (Image *) NULL; next=next_image)
      {
         next->page.width=mng_info->mng_width;
         next->page.height=mng_info->mng_height;
         next->page.x=0;
         next->page.y=0;
         next->scene=scene++;
         next_image=GetNextImageInList(next);
         if (next_image == (Image *) NULL)
           break;
         if (next->delay == 0)
           {
             scene--;
             next_image->previous=GetPreviousImageInList(next);
             if (GetPreviousImageInList(next) == (Image *) NULL)
               image=next_image;
             else
               next->previous->next=next_image;
             next=DestroyImage(next);
           }
      }
    }
#endif

  while (GetNextImageInList(image) != (Image *) NULL)
      image=GetNextImageInList(image);
  image->dispose=BackgroundDispose;

  if (logging != MagickFalse)
    {
      int
        scene;

      scene=0;
      image=GetFirstImageInList(image);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  After coalesce:");
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
        (double) image->dispose);
      while (GetNextImageInList(image) != (Image *) NULL)
      {
        image=GetNextImageInList(image);
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
          (double) image->delay,(double) image->dispose);
      }
   }
  image=GetFirstImageInList(image);
  MngInfoFreeStruct(mng_info,&have_mng_structure);
  have_mng_structure=MagickFalse;
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
  return(GetFirstImageInList(image));
}
#else /* PNG_LIBPNG_VER > 10011 */
static Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  printf("Your PNG library is too old: You have libpng-%s\n",
     PNG_LIBPNG_VER_STRING);
  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
    "PNG library is too old","`%s'",image_info->filename);
  return(Image *) NULL;
}
static Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  return(ReadPNGImage(image_info,exception));
}
#endif /* PNG_LIBPNG_VER > 10011 */
#endif

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e g i s t e r P N G I m a g e                                           %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RegisterPNGImage() adds properties for the PNG image format to
%  the list of supported formats.  The properties include the image format
%  tag, a method to read and/or write the format, whether the format
%  supports the saving of more than one frame to the same file or blob,
%  whether the format supports native in-memory I/O, and a brief
%  description of the format.
%
%  The format of the RegisterPNGImage method is:
%
%      size_t RegisterPNGImage(void)
%
*/
ModuleExport size_t RegisterPNGImage(void)
{
  char
    version[MaxTextExtent];

  MagickInfo
    *entry;

  static const char
    *PNGNote=
    {
      "See http://www.libpng.org/ for details about the PNG format."
    },
    *JNGNote=
    {
      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
      "format."
    },
    *MNGNote=
    {
      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
      "format."
    };

  *version='\0';
#if defined(PNG_LIBPNG_VER_STRING)
  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
    {
      (void) ConcatenateMagickString(version,",",MaxTextExtent);
      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
            MaxTextExtent);
    }
#endif
  entry=SetMagickInfo("MNG");
  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
#if defined(MAGICKCORE_PNG_DELEGATE)
  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
#endif
  entry->magick=(IsImageFormatHandler *) IsMNG;
  entry->description=ConstantString("Multiple-image Network Graphics");
  if (*version != '\0')
    entry->version=ConstantString(version);
  entry->module=ConstantString("PNG");
  entry->note=ConstantString(MNGNote);
  (void) RegisterMagickInfo(entry);

  entry=SetMagickInfo("PNG");
#if defined(MAGICKCORE_PNG_DELEGATE)
  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
  entry->encoder=(EncodeImageHandler *) WritePNGImage;
#endif
  entry->magick=(IsImageFormatHandler *) IsPNG;
  entry->adjoin=MagickFalse;
  entry->description=ConstantString("Portable Network Graphics");
  entry->module=ConstantString("PNG");
  if (*version != '\0')
    entry->version=ConstantString(version);
  entry->note=ConstantString(PNGNote);
  (void) RegisterMagickInfo(entry);

  entry=SetMagickInfo("PNG8");
#if defined(MAGICKCORE_PNG_DELEGATE)
  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
  entry->encoder=(EncodeImageHandler *) WritePNGImage;
#endif
  entry->magick=(IsImageFormatHandler *) IsPNG;
  entry->adjoin=MagickFalse;
  entry->description=ConstantString(
            "8-bit indexed with optional binary transparency");
  entry->module=ConstantString("PNG");
  (void) RegisterMagickInfo(entry);

  entry=SetMagickInfo("PNG24");
  *version='\0';
#if defined(ZLIB_VERSION)
  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
    {
      (void) ConcatenateMagickString(version,",",MaxTextExtent);
      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
    }
#endif
  if (*version != '\0')
    entry->version=ConstantString(version);
#if defined(MAGICKCORE_PNG_DELEGATE)
  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
  entry->encoder=(EncodeImageHandler *) WritePNGImage;
#endif
  entry->magick=(IsImageFormatHandler *) IsPNG;
  entry->adjoin=MagickFalse;
  entry->description=ConstantString("opaque 24-bit RGB");
  entry->module=ConstantString("PNG");
  (void) RegisterMagickInfo(entry);

  entry=SetMagickInfo("PNG32");
#if defined(MAGICKCORE_PNG_DELEGATE)
  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
  entry->encoder=(EncodeImageHandler *) WritePNGImage;
#endif
  entry->magick=(IsImageFormatHandler *) IsPNG;
  entry->adjoin=MagickFalse;
  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
  entry->module=ConstantString("PNG");
  (void) RegisterMagickInfo(entry);

  entry=SetMagickInfo("JNG");
#if defined(JNG_SUPPORTED)
#if defined(MAGICKCORE_PNG_DELEGATE)
  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
#endif
#endif
  entry->magick=(IsImageFormatHandler *) IsJNG;
  entry->adjoin=MagickFalse;
  entry->description=ConstantString("JPEG Network Graphics");
  entry->module=ConstantString("PNG");
  entry->note=ConstantString(JNGNote);
  (void) RegisterMagickInfo(entry);
#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
  png_semaphore=AllocateSemaphoreInfo();
#endif
  return(MagickImageCoderSignature);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   U n r e g i s t e r P N G I m a g e                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  UnregisterPNGImage() removes format registrations made by the
%  PNG module from the list of supported formats.
%
%  The format of the UnregisterPNGImage method is:
%
%      UnregisterPNGImage(void)
%
*/
ModuleExport void UnregisterPNGImage(void)
{
  (void) UnregisterMagickInfo("MNG");
  (void) UnregisterMagickInfo("PNG");
  (void) UnregisterMagickInfo("PNG8");
  (void) UnregisterMagickInfo("PNG24");
  (void) UnregisterMagickInfo("PNG32");
  (void) UnregisterMagickInfo("JNG");
#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
  if (png_semaphore != (SemaphoreInfo *) NULL)
    DestroySemaphoreInfo(&png_semaphore);
#endif
}

#if defined(MAGICKCORE_PNG_DELEGATE)
#if PNG_LIBPNG_VER > 10011
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e M N G I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteMNGImage() writes an image in the Portable Network Graphics
%  Group's "Multiple-image Network Graphics" encoded image format.
%
%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
%
%  The format of the WriteMNGImage method is:
%
%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
%
%  A description of each parameter follows.
%
%    o image_info: the image info.
%
%    o image:  The image.
%
%
%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
%    "To do" under ReadPNGImage):
%
%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
%    some GIF animations don't convert properly)
%
%    Preserve all unknown and not-yet-handled known chunks found in input
%    PNG file and copy them  into output PNG files according to the PNG
%    copying rules.
%
%    Write the iCCP chunk at MNG level when (icc profile length > 0)
%
%    Improve selection of color type (use indexed-colour or indexed-colour
%    with tRNS when 256 or fewer unique RGBA values are present).
%
%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
%    This will be complicated if we limit ourselves to generating MNG-LC
%    files.  For now we ignore disposal method 3 and simply overlay the next
%    image on it.
%
%    Check for identical PLTE's or PLTE/tRNS combinations and use a
%    global MNG PLTE or PLTE/tRNS combination when appropriate.
%    [mostly done 15 June 1999 but still need to take care of tRNS]
%
%    Check for identical sRGB and replace with a global sRGB (and remove
%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
%    local gAMA/cHRM with local sRGB if appropriate).
%
%    Check for identical sBIT chunks and write global ones.
%
%    Provide option to skip writing the signature tEXt chunks.
%
%    Use signatures to detect identical objects and reuse the first
%    instance of such objects instead of writing duplicate objects.
%
%    Use a smaller-than-32k value of compression window size when
%    appropriate.
%
%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
%    ancillary text chunks and save profiles.
%
%    Provide an option to force LC files (to ensure exact framing rate)
%    instead of VLC.
%
%    Provide an option to force VLC files instead of LC, even when offsets
%    are present.  This will involve expanding the embedded images with a
%    transparent region at the top and/or left.
*/

static void
png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
   png_info *ping_info, unsigned char *profile_type, unsigned char
   *profile_description, unsigned char *profile_data, png_uint_32 length)
{
   png_textp
     text;

   register ssize_t
     i;

   unsigned char
     *sp;

   png_charp
     dp;

   png_uint_32
     allocated_length,
     description_length;

   unsigned char
     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
      return;

   if (image_info->verbose)
     {
     (void) printf("writing raw profile: type=%s, length=%.20g\n",
       (char *) profile_type, (double) length);
     }
   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
   description_length=(png_uint_32) strlen((const char *) profile_description);
   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
      + description_length);
   text[0].text=(png_charp) png_malloc(ping,allocated_length);
   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
   text[0].key[0]='\0';
   (void) ConcatenateMagickString(text[0].key,
      "Raw profile type ",MaxTextExtent);
   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
   sp=profile_data;
   dp=text[0].text;
   *dp++='\n';
   (void) CopyMagickString(dp,(const char *) profile_description,
     allocated_length);
   dp+=description_length;
   *dp++='\n';
   (void) FormatMagickString(dp,allocated_length-
     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
   dp+=8;
   for (i=0; i < (ssize_t) length; i++)
   {
     if (i%36 == 0)
       *dp++='\n';
     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
   }
   *dp++='\n';
   *dp='\0';
   text[0].text_length=(png_size_t) (dp-text[0].text);
   text[0].compression=image_info->compression == NoCompression ||
     (image_info->compression == UndefinedCompression &&
     text[0].text_length < 128) ? -1 : 0;
   if (text[0].text_length <= allocated_length)
     png_set_text(ping,ping_info,text,1);
   png_free(ping,text[0].text);
   png_free(ping,text[0].key);
   png_free(ping,text);
}

static MagickBooleanType png_write_chunk_from_profile(Image *image,
   const char *string, int logging)
{
  char
    *name;

  const StringInfo
    *profile;

  unsigned char
    *data;

  png_uint_32 length;

  ResetImageProfileIterator(image);
  for (name=GetNextImageProfile(image); name != (const char *) NULL; ){
    profile=GetImageProfile(image,name);
    if (profile != (const StringInfo *) NULL)
      {
        StringInfo
          *png_profile;

        if (LocaleNCompare(name,string,11) == 0) {
          if (logging != MagickFalse)
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "  Found %s profile",name);

       png_profile=CloneStringInfo(profile);
       data=GetStringInfoDatum(png_profile),
       length=(png_uint_32) GetStringInfoLength(png_profile);
       data[4]=data[3];
       data[3]=data[2];
       data[2]=data[1];
       data[1]=data[0];
       (void) WriteBlobMSBULong(image,length-5);  /* data length */
       (void) WriteBlob(image,length-1,data+1);
       (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
       png_profile=DestroyStringInfo(png_profile);
        }
      }
      name=GetNextImageProfile(image);
   }
   return(MagickTrue);
}

static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
   const ImageInfo *image_info,Image *image)
{
/* Write one PNG image */
  char
    s[2];

  const char
    *name,
    *property,
    *value;

  const StringInfo
    *profile;


  int
    image_matte,
    num_passes,
    pass;

  png_byte
     ping_trans_alpha[256];

  png_colorp
     palette;

  png_color_16
    ping_background,
    ping_trans_color;

  png_info
    *ping_info;

  png_struct
    *ping;

  png_uint_32
    ping_height,
    ping_width;

  ssize_t
    y;

  MagickBooleanType
    status;

  QuantumInfo
    *quantum_info;

  register IndexPacket
    *indexes;

  register ssize_t
    i,
    x;

  unsigned char
    *png_pixels;

  unsigned int
    logging,
    matte;

  volatile int
    ping_bit_depth, 
    ping_color_type,
    ping_interlace_method,
    ping_compression_method,
    ping_filter_method,
    ping_num_trans;

  volatile size_t
    image_colors,
    image_depth,
    old_bit_depth;

  size_t
    quality,
    rowbytes,
    save_image_depth;

  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
    "  enter WriteOnePNGImage()");

#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
  LockSemaphoreInfo(png_semaphore);
#endif

  /* Initialize some stuff */
  ping_bit_depth=0, 
  ping_color_type=0,
  ping_interlace_method=0,
  ping_compression_method=0,
  ping_filter_method=0,
  ping_num_trans = 0;

  ping_background.red = 0;
  ping_background.green = 0;
  ping_background.blue = 0;
  ping_background.gray = 0;
  ping_background.index = 0;

  ping_trans_color.red=0;
  ping_trans_color.green=0;
  ping_trans_color.blue=0;
  ping_trans_color.gray=0;

  quantum_info = (QuantumInfo *) NULL;
  image_colors=image->colors;
  image_depth=image->depth;
  image_matte=image->matte;

  if (image->colorspace != RGBColorspace)
    (void) TransformImageColorspace(image,RGBColorspace);
  mng_info->IsPalette=image->storage_class == PseudoClass && 
    image_colors <= 256 && !IsOpaqueImage(image,&image->exception);
  mng_info->optimize=image_info->type == OptimizeType;

  /*
    Allocate the PNG structures
  */
#ifdef PNG_USER_MEM_SUPPORTED
  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
#else
  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
    PNGErrorHandler,PNGWarningHandler);
#endif
  if (ping == (png_struct *) NULL)
    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
  ping_info=png_create_info_struct(ping);
  if (ping_info == (png_info *) NULL)
    {
      png_destroy_write_struct(&ping,(png_info **) NULL);
      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    }
  png_set_write_fn(ping,image,png_put_data,png_flush_data);
  png_pixels=(unsigned char *) NULL;

  if (setjmp(png_jmpbuf(ping)))
    {
      /*
        PNG write failed.
      */
#ifdef PNG_DEBUG
     if (image_info->verbose)
        (void) printf("PNG write has failed.\n");
#endif
      png_destroy_write_struct(&ping,&ping_info);
#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
      UnlockSemaphoreInfo(png_semaphore);
#endif
      return(MagickFalse);
    }
  /*
    Prepare PNG for writing.
  */
#if defined(PNG_MNG_FEATURES_SUPPORTED)
  if (mng_info->write_mng)
     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
#else
# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
  if (mng_info->write_mng)
     png_permit_empty_plte(ping,MagickTrue);
# endif
#endif
  x=0;
  ping_width=(png_uint_32) image->columns;
  ping_height=(png_uint_32) image->rows;
  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
     image_depth=8;
  if (mng_info->write_png_depth != 0)
     image_depth=mng_info->write_png_depth;
  /* Adjust requested depth to next higher valid depth if necessary */
  if (image_depth > 8)
     image_depth=16;
  if ((image_depth > 4) && (image_depth < 8))
     image_depth=8;
  if (image_depth == 3)
     image_depth=4;
  if (logging != MagickFalse)
    {
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    width=%.20g",(double) ping_width);
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    height=%.20g",(double) ping_height);
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    image_matte=%.20g",(double) image->matte);
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    image_depth=%.20g",(double) image->depth);
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    requested PNG image_depth=%.20g",(double) image->depth);
    }
  save_image_depth=image_depth;
  ping_bit_depth=(png_byte) save_image_depth;
#if defined(PNG_pHYs_SUPPORTED)
  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
      (!mng_info->write_mng || !mng_info->equal_physs))
    {
      int
        unit_type;

      png_uint_32
        x_resolution,
        y_resolution;

      if (image->units == PixelsPerInchResolution)
        {
          unit_type=PNG_RESOLUTION_METER;
          x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
          y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
        }
      else if (image->units == PixelsPerCentimeterResolution)
        {
          unit_type=PNG_RESOLUTION_METER;
          x_resolution=(png_uint_32) (100.0*image->x_resolution);
          y_resolution=(png_uint_32) (100.0*image->y_resolution);
        }
      else
        {
          unit_type=PNG_RESOLUTION_UNKNOWN;
          x_resolution=(png_uint_32) image->x_resolution;
          y_resolution=(png_uint_32) image->y_resolution;
        }
       png_set_pHYs(ping,ping_info,x_resolution,y_resolution,unit_type);
       if (logging != MagickFalse)
         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "    Setting up pHYs chunk");
    }
#endif
#if defined(PNG_oFFs_SUPPORTED)
  if (image->page.x || image->page.y)
    {
       png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
          (png_int_32) image->page.y, 0);
       if (logging != MagickFalse)
         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "    Setting up oFFs chunk");
    }
#endif
  if (image_matte && (!mng_info->adjoin || !mng_info->equal_backgrounds))
    {
      png_color_16
        background;

      if (image_depth < MAGICKCORE_QUANTUM_DEPTH)
        {
          size_t
             maxval;

          maxval=(1UL << image_depth)-1;
          background.red=(png_uint_16)
            (QuantumScale*(maxval*image->background_color.red));
          background.green=(png_uint_16)
            (QuantumScale*(maxval*image->background_color.green));
          background.blue=(png_uint_16)
            (QuantumScale*(maxval*image->background_color.blue));
          background.gray=(png_uint_16)
            (QuantumScale*(maxval*PixelIntensity(&image->background_color)));
        }
      else
        {
          background.red=image->background_color.red;
          background.green=image->background_color.green;
          background.blue=image->background_color.blue;
          background.gray=
            (png_uint_16) PixelIntensity(&image->background_color);
        }
      background.index=(png_byte) background.gray;
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Setting up bKGd chunk");
      png_set_bKGD(ping,ping_info,&background);
    }
  /*
    Select the color type.
  */
  matte=image_matte;
  old_bit_depth=0;
  if ((mng_info->write_png_colortype-1) == PNG_COLOR_TYPE_PALETTE)
    mng_info->write_png8=MagickTrue;
  if (mng_info->write_png8)
    {
      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
      ping_bit_depth=8;
      image_depth=ping_bit_depth;
        {
          /* TO DO: make this a function cause it's used twice, except
             for reducing the sample depth from 8. */

          QuantizeInfo
            quantize_info;

          size_t
             number_colors,
             save_number_colors;

          number_colors=image_colors;
          if ((image->storage_class == DirectClass) || (number_colors > 256))
            {
              GetQuantizeInfo(&quantize_info);
              quantize_info.dither=IsPaletteImage(image,&image->exception) ==
                MagickFalse ? MagickTrue : MagickFalse;
              quantize_info.number_colors= (matte != MagickFalse ? 255UL :
                256UL);
              (void) QuantizeImage(&quantize_info,image);
              number_colors=image_colors;
              (void) SyncImage(image);
              if (logging != MagickFalse)
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    Colors quantized to %.20g",(double) number_colors);
            }
          if (matte)
            png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
          /*
            Set image palette.
          */
          ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
#if defined(PNG_SORT_PALETTE)
          save_number_colors=image_colors;
          if (CompressColormapTransFirst(image) == MagickFalse)
            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
          number_colors=image->colors;
          image_colors=save_number_colors;
#endif
          palette=(png_color *) AcquireQuantumMemory(257,
            sizeof(*palette));
          if (palette == (png_color *) NULL)
            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "  Setting up PLTE chunk with %d colors",
                (int) number_colors);
          for (i=0; i < (ssize_t) number_colors; i++)
          {
            palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
            palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
            palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
            if (logging != MagickFalse)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
#if MAGICKCORE_QUANTUM_DEPTH == 8
                "    %3ld (%3d,%3d,%3d)",
#else
                "    %5ld (%5d,%5d,%5d)",
#endif
                (long) i,palette[i].red,palette[i].green,palette[i].blue);

          }
          if (matte)
            {
              number_colors++;
              palette[i].red=ScaleQuantumToChar((Quantum) QuantumRange);
              palette[i].green=ScaleQuantumToChar((Quantum) QuantumRange);
              palette[i].blue=ScaleQuantumToChar((Quantum) QuantumRange);
            }
          png_set_PLTE(ping,ping_info,palette,(int) number_colors);
          palette=(png_colorp) RelinquishMagickMemory(palette);
            image_depth=ping_bit_depth;
            ping_num_trans=0;
            if (matte)
            {
              ExceptionInfo
                *exception;

              int
                trans_alpha[256];

              /*
                Identify which colormap entry is transparent.
              */
              assert(number_colors <= 256);
              for (i=0; i < (ssize_t) number_colors; i++)
                 trans_alpha[i]=255;
              exception=(&image->exception);
              for (y=0; y < (ssize_t) image->rows; y++)
              {
                register const PixelPacket
                  *p;

                p=GetAuthenticPixels(image,0,y,image->columns,1,exception);
                if (p == (PixelPacket *) NULL)
                  break;
                indexes=GetAuthenticIndexQueue(image);
                for (x=0; x < (ssize_t) image->columns; x++)
                {
                  if (p->opacity != OpaqueOpacity)
                    {
                      indexes[x]=(IndexPacket) (number_colors-1);
                      trans_alpha[(ssize_t) indexes[x]]=(png_byte) (255-
                        ScaleQuantumToChar(GetOpacityPixelComponent(p)));
                    }
                  p++;
                }
                if (SyncAuthenticPixels(image,exception) == MagickFalse)
                  break;
              }
              for (i=0; i < (ssize_t) number_colors; i++)
                if (trans_alpha[i] != 255)
                  ping_num_trans=(unsigned short) (i+1);

              if (ping_num_trans == 0)
                 png_set_invalid(ping, ping_info, PNG_INFO_tRNS);
              if (!png_get_valid(ping, ping_info, PNG_INFO_tRNS))
                ping_num_trans=0;
              if (ping_num_trans != 0)
                {
                  for (i=0; i<256; i++)
                     ping_trans_alpha[i]=(png_byte) trans_alpha[i];
                }

              (void) png_set_tRNS(ping, ping_info,
                                  ping_trans_alpha,
                                  ping_num_trans,
                                  &ping_trans_color);
            }
          /*
            Identify which colormap entry is the background color.
          */
          for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
            if (IsPNGColorEqual(ping_background,image->colormap[i]))
              break;
          ping_background.index=(png_byte) i;
        }
      if (image_matte != MagickFalse)
        {
          /* TO DO: reduce to binary transparency */
        }
    } /* end of write_png8 */
  else if (mng_info->write_png24)
    {
      image_matte=MagickFalse;
      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
    }
  else if (mng_info->write_png32)
    {
      image_matte=MagickTrue;
      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
    }
  else
    {
      image_depth=ping_bit_depth;
      if (mng_info->write_png_colortype)
        {
          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
          image_matte=MagickFalse;
          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
            image_matte=MagickTrue;
        }
      else
        {
          if (logging != MagickFalse)
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "Selecting PNG colortype");
          ping_color_type=(png_byte) ((matte == MagickTrue)?
          PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
          if(image_info->type == TrueColorType)
            {
              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
              image_matte=MagickFalse;
            }
          if(image_info->type == TrueColorMatteType)
            {
              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
              image_matte=MagickTrue;
            }
          if ((image_info->type == UndefinedType || 
             image_info->type == OptimizeType || 
             image_info->type == GrayscaleType) &&
             image_matte == MagickFalse && ImageIsGray(image))
            {
              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
              image_matte=MagickFalse;
            }
          if ((image_info->type == UndefinedType ||
             image_info->type == OptimizeType || 
              image_info->type == GrayscaleMatteType) &&
              image_matte == MagickTrue && ImageIsGray(image))
            {
              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
              image_matte=MagickTrue;
            } 
        }
      if (logging != MagickFalse)
         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
         "Selected PNG colortype=%d",ping_color_type);

      if (ping_bit_depth < 8)
       {
         if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
             ping_color_type == PNG_COLOR_TYPE_RGB ||
             ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
           ping_bit_depth=8;
       }

      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
        {
          if (image->matte == MagickFalse && image->colors < 256)
            {
              if (ImageIsMonochrome(image))
                {
                  ping_bit_depth=1;
                  if (ping_bit_depth < (int)mng_info->write_png_depth)
                    ping_bit_depth = mng_info->write_png_depth;
                }
            }
        }
      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
        {
           size_t one = 1;
           ping_bit_depth=1;

           if (image->colors == 0)
           {
              /* DO SOMETHING */       
              (void) ThrowMagickException(&image->exception,
                 GetMagickModule(),CoderError,
                "image has 0 colors", "`%s'","");
           }

              if (logging != MagickFalse)
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "  SyncImage.2.");
           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
             ping_bit_depth <<= 1;

           if (logging != MagickFalse)
             {
               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Number of colors: %.20g",(double) image_colors);
               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Tentative PNG bit depth: %d",ping_bit_depth);
             }
           if (mng_info->write_png_depth)
             {
               old_bit_depth=ping_bit_depth;
               if (ping_bit_depth < (int)mng_info->write_png_depth)
                 {
                   ping_bit_depth = mng_info->write_png_depth;
                   if (ping_bit_depth > 8)
                      ping_bit_depth = 8;
                   if (ping_bit_depth != (int) old_bit_depth)
                     {
                       if (logging != MagickFalse)
                         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                           "    Colors increased to %.20g",(double)
                           image_colors);
                     }
                 }
             }
        }
    }
  image_depth=ping_bit_depth;
  if (logging != MagickFalse)
    {
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    Tentative PNG color type: %.20g",(double) ping_color_type);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    image_info->type: %.20g",(double) image_info->type);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    image_depth: %.20g",(double) image_depth);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
    }

  if (matte && (mng_info->optimize || mng_info->IsPalette))
    {
      register const PixelPacket
        *p;

      p=GetVirtualPixels(image,0,0,image->columns,1,&image->exception);
      ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
        if (p == (const PixelPacket *) NULL)
          break;
        for (x=(ssize_t) image->columns-1; x >= 0; x--)
        {
          if (IsGray(p) == MagickFalse)
            {
              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
              break;
            }
          p++;
        }
      }
      /*
        Determine if there is any transparent color.
      */
      for (y=0; y < (ssize_t) image->rows; y++)
      {
        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
        if (p == (const PixelPacket *) NULL)
          break;
        for (x=(ssize_t) image->columns-1; x >= 0; x--)
        {
          if (p->opacity != OpaqueOpacity)
            break;
          p++;
        }
        if (x != 0)
          break;
      }
      if ((y == (ssize_t) image->rows) && (x == (ssize_t) image->columns))
        {
          /*
            No transparent pixels are present.  Change 4 or 6 to 0 or 2.
          */
          image_matte=MagickFalse;
          ping_color_type&=0x03;
        }
      else
        {
          unsigned int
            mask;

          mask=0xffff;
          if (ping_bit_depth == 8)
             mask=0x00ff;
          if (ping_bit_depth == 4)
             mask=0x000f;
          if (ping_bit_depth == 2)
             mask=0x0003;
          if (ping_bit_depth == 1)
             mask=0x0001;
          ping_trans_color.red=(png_uint_16)
            (ScaleQuantumToShort(GetRedPixelComponent(p)) & mask);
          ping_trans_color.green=(png_uint_16)
            (ScaleQuantumToShort(GetGreenPixelComponent(p)) & mask);
          ping_trans_color.blue=(png_uint_16)
            (ScaleQuantumToShort(GetBluePixelComponent(p)) & mask);
          ping_trans_color.gray=(png_uint_16)
            (ScaleQuantumToShort(PixelIntensityToQuantum(p)) & mask);
          ping_trans_color.index=(png_byte)
            (ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p))));
          (void) png_set_tRNS(ping, ping_info, NULL, 0,
             &ping_trans_color);
        }
      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
        {
          /*
            Determine if there is one and only one transparent color
            and if so if it is fully transparent.
          */
          for (y=0; y < (ssize_t) image->rows; y++)
          {
            p=GetVirtualPixels(image,0,y,image->columns,1,
               &image->exception);
            x=0;
            if (p == (const PixelPacket *) NULL)
              break;
            for (x=(ssize_t) image->columns-1; x >= 0; x--)
            {
              if (p->opacity != OpaqueOpacity)
                {
                  if (IsPNGColorEqual(ping_trans_color,*p) == 0)
                  {
                     break;  /* Can't use RGB + tRNS for multiple
                                transparent colors.  */
                  }
                  if (p->opacity != (Quantum) TransparentOpacity)
                  {
                     break;  /* Can't use RGB + tRNS for
                                semitransparency. */
                  }
                }
               else
                {
                  if (IsPNGColorEqual(ping_trans_color,*p))
                      break; /* Can't use RGB + tRNS when another pixel
                                having the same RGB samples is
                                transparent. */
                }
            p++;
            }
            if (x >= 0)
               break;
          }
          if (x >= 0)
            png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
        }
      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
        {
          ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
          if (image_depth == 8)
            {
              ping_trans_color.red&=0xff;
              ping_trans_color.green&=0xff;
              ping_trans_color.blue&=0xff;
              ping_trans_color.gray&=0xff;
            }
        }
    }
    matte=image_matte;
    if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
      image_matte=MagickFalse;
    if ((mng_info->optimize || mng_info->IsPalette) &&
        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
        ImageIsGray(image) && (!image_matte || image_depth >= 8))
      {
        size_t one=1;
        if (image_matte != MagickFalse)
          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
        else
          {
            ping_color_type=PNG_COLOR_TYPE_GRAY;
            if (save_image_depth == 16 && image_depth == 8)
              ping_trans_color.gray*=0x0101;
          }
        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
          image_depth=MAGICKCORE_QUANTUM_DEPTH;
        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
          image_colors=one << image_depth;
        if (image_depth > 8)
          ping_bit_depth=16;
        else
          {
            ping_bit_depth=8;
            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
              {
                if(!mng_info->write_png_depth)
                  {
                    ping_bit_depth=1;
                    while ((int) (one << ping_bit_depth)
                        < (ssize_t) image_colors)
                      ping_bit_depth <<= 1;
                  }
              }
            else if (mng_info->optimize && ping_color_type ==
                PNG_COLOR_TYPE_GRAY && image_colors < 17 && 
                mng_info->IsPalette)
              {

              /* Check if grayscale is reducible */
                int
                  depth_4_ok=MagickTrue,
                  depth_2_ok=MagickTrue,
                  depth_1_ok=MagickTrue;

                for (i=0; i < (ssize_t) image_colors; i++)
                {
                   unsigned char
                     intensity;

                   intensity=ScaleQuantumToChar(image->colormap[i].red);

                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
                     depth_2_ok=depth_1_ok=MagickFalse;
                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
                     depth_1_ok=MagickFalse;
                }
                if (depth_1_ok && mng_info->write_png_depth <= 1)
                  ping_bit_depth=1;
                else if (depth_2_ok && mng_info->write_png_depth <= 2)
                  ping_bit_depth=2;
                else if (depth_4_ok && mng_info->write_png_depth <= 4)
                  ping_bit_depth=4;
              }
          }
          image_depth=ping_bit_depth;
      }
    else
      if (mng_info->IsPalette)
      {
        size_t
           number_colors;

        number_colors=image_colors;

        if (image_depth <= 8)
          {
            /*
              Set image palette.
            */
            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
            if (mng_info->have_write_global_plte && !matte)
              {
                png_set_PLTE(ping,ping_info,NULL,0);
                if (logging)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "  Setting up empty PLTE chunk");
              }
            else
              {
#if defined(PNG_SORT_PALETTE)
                size_t
                   save_number_colors;

                if (mng_info->optimize)
                  {
                    save_number_colors=image_colors;
                    if (CompressColormapTransFirst(image) == MagickFalse)
                       ThrowWriterException(ResourceLimitError,
                                            "MemoryAllocationFailed");
                    number_colors=image->colors;
                    image_colors=save_number_colors;
                  }
#endif
                palette=(png_color *) AcquireQuantumMemory(257,
                  sizeof(*palette));
                if (palette == (png_color *) NULL)
                  ThrowWriterException(ResourceLimitError,
                     "MemoryAllocationFailed");
                for (i=0; i < (ssize_t) number_colors; i++)
                {
                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
                }
                if (logging)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "  Setting up PLTE chunk with %d colors",
                    (int) number_colors);
                png_set_PLTE(ping,ping_info,palette,(int) number_colors);
                palette=(png_colorp) RelinquishMagickMemory(palette);
              }
            /* color_type is PNG_COLOR_TYPE_PALETTE */
            if (!mng_info->write_png_depth)
              {
                size_t
                  one;

                ping_bit_depth=1;
                one=1;
                while ((one << ping_bit_depth) < number_colors)
                  ping_bit_depth <<= 1;
              }
            ping_num_trans=0;
            if (matte)
            {
              ExceptionInfo
                *exception;

              register const PixelPacket
                *p;

              int
                trans[256];

              register const IndexPacket
                *packet_indexes;

              /*
                Identify which colormap entry is transparent.
              */
              assert(number_colors <= 256);
              for (i=0; i < (ssize_t) number_colors; i++)
                trans[i]=256;
              exception=(&image->exception);
              for (y=0; y < (ssize_t) image->rows; y++)
              {
                p=GetVirtualPixels(image,0,y,image->columns,1,exception);
                if (p == (const PixelPacket *) NULL)
                  break;
                packet_indexes=GetVirtualIndexQueue(image);
                for (x=0; x < (ssize_t) image->columns; x++)
                {
                  if (p->opacity != OpaqueOpacity)
                    {
                      IndexPacket
                        packet_index;

                      packet_index=packet_indexes[x];
                      assert((size_t) packet_index < number_colors);
                      if (trans[(ssize_t) packet_index] != 256)
                        {
                          if (trans[(ssize_t) packet_index] != (png_byte) (255-
                             ScaleQuantumToChar(GetOpacityPixelComponent(p))))
                            {
                              ping_color_type=(png_byte)
                                PNG_COLOR_TYPE_RGB_ALPHA;
                              break;
                            }
                        }
                      trans[(ssize_t) packet_index]=(png_byte) (255-
                        ScaleQuantumToChar(GetOpacityPixelComponent(p)));
                    }
                  p++;
                }
                if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
                {
                  ping_num_trans=0;
                  png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
                  png_set_invalid(ping,ping_info,PNG_INFO_PLTE);
                  mng_info->IsPalette=MagickFalse;
                  (void) SyncImage(image);
                  if (logging)
                    (void) LogMagickEvent(CoderEvent, GetMagickModule(),
                      "    Cannot write image as indexed PNG, writing RGBA.");
                  break;
                }
              }
              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
              {
                for (i=0; i < (ssize_t) number_colors; i++)
                {
                  if (trans[i] == 256)
                    trans[i]=255;
                  if (trans[i] != 255)
                    ping_num_trans=(unsigned short) (i+1);
                }
              }
              if (ping_num_trans == 0)
                png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
                ping_num_trans=0;
              if (ping_num_trans != 0)
                {
                  for (i=0; i < (ssize_t) number_colors; i++)
                      ping_trans_alpha[i]=(png_byte) trans[i];
                }
            }

          }
      }
    else
      {
        if (image_depth < 8)
          image_depth=8;
        if ((save_image_depth == 16) && (image_depth == 8))
          {
            ping_trans_color.red*=0x0101;
            ping_trans_color.green*=0x0101;
            ping_trans_color.blue*=0x0101;
            ping_trans_color.gray*=0x0101;
          }
      }

    /*
      Adjust background and transparency samples in sub-8-bit grayscale files.
    */
    if (ping_bit_depth < 8 && ping_color_type ==
        PNG_COLOR_TYPE_GRAY)
      {
         png_uint_16
           maxval;

         png_color_16
           background;

         size_t
           one=1;

         maxval=(png_uint_16) ((one << ping_bit_depth)-1);


         background.gray=(png_uint_16)
           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));

         if (logging != MagickFalse)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "  Setting up bKGD chunk");
         png_set_bKGD(ping,ping_info,&background);

         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
           ping_trans_color.gray));
      }

    if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
      {
        /*
           Identify which colormap entry is the background color.
        */

        size_t
           number_colors;

        number_colors=image_colors;

        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
          if (IsPNGColorEqual(ping_background,image->colormap[i]))
            break;

        ping_background.index=(png_byte) i;

        if (logging)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  Setting up bKGD chunk with index=%d",(int) i);

        png_set_bKGD(ping,ping_info,&ping_background);
      }

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "    PNG color type: %d",ping_color_type);
  /*
    Initialize compression level and filtering.
  */
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Setting up deflate compression");
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "    Compression buffer size: 32768");
  png_set_compression_buffer_size(ping,32768L);
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "    Compression mem level: 9");
  png_set_compression_mem_level(ping, 9);
  quality=image->quality == UndefinedCompressionQuality ? 75UL :
     image->quality;
  if (quality > 9)
    {
      int
        level;

      level=(int) MagickMin((ssize_t) quality/10,9);
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Compression level: %d",level);
      png_set_compression_level(ping,level);
    }
  else
    {
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Compression strategy: Z_HUFFMAN_ONLY");
      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
    }
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Setting up filtering");
#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)

  /* This became available in libpng-1.0.9.  Output must be a MNG. */
  if (mng_info->write_mng && ((quality % 10) == 7))
    {
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
    }
  else
    if (logging != MagickFalse)
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    Filter_type: 0");
#endif
  {
    int
      base_filter;

    if ((quality % 10) > 5)
      base_filter=PNG_ALL_FILTERS;
    else
      if ((quality % 10) != 5)
        base_filter=(int) quality % 10;
      else
        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
            (quality < 50))
          base_filter=PNG_NO_FILTERS;
        else
          base_filter=PNG_ALL_FILTERS;
    if (logging != MagickFalse)
      {
        if (base_filter == PNG_ALL_FILTERS)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Base filter method: ADAPTIVE");
        else
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Base filter method: NONE");
      }
    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
  }

  ResetImageProfileIterator(image);
  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
  {
    profile=GetImageProfile(image,name);
    if (profile != (StringInfo *) NULL)
      {
#ifdef PNG_WRITE_iCCP_SUPPORTED
        if ((LocaleCompare(name,"ICC") == 0) ||
            (LocaleCompare(name,"ICM") == 0))
          png_set_iCCP(ping,ping_info,(const png_charp) name,0,(png_charp)
            GetStringInfoDatum(profile),
                     (png_uint_32) GetStringInfoLength(profile));
        else
#endif
          png_write_raw_profile(image_info,ping,ping_info,(unsigned char *)
            name,(unsigned char *) name,GetStringInfoDatum(profile),
            (png_uint_32) GetStringInfoLength(profile));
      }
    if (logging != MagickFalse)
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Setting up text chunk with %s profile",name);
    name=GetNextImageProfile(image);
  }

#if defined(PNG_WRITE_sRGB_SUPPORTED)
  if ((mng_info->have_write_global_srgb == 0) &&
      ((image->rendering_intent != UndefinedIntent) ||
      (image->colorspace == sRGBColorspace)))
    {
      /*
        Note image rendering intent.
      */
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  Setting up sRGB chunk");
      (void) png_set_sRGB(ping,ping_info,(
        PNG_RenderingIntent_from_Magick_RenderingIntent(
        image->rendering_intent)));
      png_set_gAMA(ping,ping_info,0.45455);
    }
  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
#endif
    {
      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
        {
          /*
            Note image gamma.
            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
          */
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "  Setting up gAMA chunk");
          png_set_gAMA(ping,ping_info,image->gamma);
        }
      if ((mng_info->have_write_global_chrm == 0) &&
          (image->chromaticity.red_primary.x != 0.0))
        {
          /*
            Note image chromaticity.
            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
          */
           PrimaryInfo
             bp,
             gp,
             rp,
             wp;

           wp=image->chromaticity.white_point;
           rp=image->chromaticity.red_primary;
           gp=image->chromaticity.green_primary;
           bp=image->chromaticity.blue_primary;

           if (logging != MagickFalse)
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
               "  Setting up cHRM chunk");
           png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
               bp.x,bp.y);
       }
    }
  ping_interlace_method=image_info->interlace != NoInterlace;

  if (mng_info->write_mng)
    png_set_sig_bytes(ping,8);

  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */

  if (mng_info->write_png_colortype)
    {
     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
       if (ImageIsGray(image) == MagickFalse)
         {
           ping_color_type = PNG_COLOR_TYPE_RGB;
           if (ping_bit_depth < 8)
             ping_bit_depth=8;
         }
         
     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
       if (ImageIsGray(image) == MagickFalse)
         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
    }

  if ((mng_info->write_png_depth &&
     (int) mng_info->write_png_depth != ping_bit_depth) ||
     (mng_info->write_png_colortype &&
     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
      mng_info->write_png_colortype != 7 &&
      !(mng_info->write_png_colortype == 5 && ping_color_type == 0))))
    {
      if (logging != MagickFalse)
        {
          if (mng_info->write_png_depth)
            {
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
                  mng_info->write_png_depth,
                  ping_bit_depth);
            }
          if (mng_info->write_png_colortype)
            {
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "  Defined PNG:color-type=%u, Computed color type=%u",
                  mng_info->write_png_colortype-1,
                  ping_color_type);
            }
        }
      png_warning(ping,
        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
    }

  if (image_matte && !image->matte)
    {
      /* Add an opaque matte channel */
      image->matte = MagickTrue;
      (void) SetImageOpacity(image,0);
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "  Added an opaque matte channel");
    }

  if (image->matte == MagickTrue && ping_color_type < 4)
    {
      if (ping_color_type == 3 && ping_num_trans == 0)
        {
          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "  Ignoring request to write tRNS chunk with num_trans==0");
        }
      else
        (void) png_set_tRNS(ping, ping_info,
                            ping_trans_alpha,
                            ping_num_trans,
                            &ping_trans_color);
    }

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Writing PNG header chunks");

  png_set_IHDR(ping,ping_info,ping_width,ping_height,
               ping_bit_depth,ping_color_type,
               ping_interlace_method,ping_compression_method,
               ping_filter_method);

  png_write_info_before_PLTE(ping, ping_info);
  /* write any png-chunk-b profiles */
  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",(int) logging);
  png_write_info(ping,ping_info);
  /* write any PNG-chunk-m profiles */
  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",(int) logging);

  if (image->page.width || image->page.height)
    {
      unsigned char
        chunk[14];

      (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
      PNGType(chunk,mng_vpAg);
      LogPNGChunk((int) logging,mng_vpAg,9L);
      PNGLong(chunk+4,(png_uint_32) image->page.width);
      PNGLong(chunk+8,(png_uint_32) image->page.height);
      chunk[12]=0;   /* unit = pixels */
      (void) WriteBlob(image,13,chunk);
      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
    }

#if (PNG_LIBPNG_VER == 10206)
    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
#define PNG_HAVE_IDAT               0x04
    ping->mode |= PNG_HAVE_IDAT;
#undef PNG_HAVE_IDAT
#endif

  png_set_packing(ping);
  /*
    Allocate memory.
  */
  rowbytes=image->columns;
  if (image_depth > 8)
    rowbytes*=2;
  switch (ping_color_type)
    {
      case PNG_COLOR_TYPE_RGB:
        rowbytes*=3;
        break;
      case PNG_COLOR_TYPE_GRAY_ALPHA:
        rowbytes*=2;
        break;
      case PNG_COLOR_TYPE_RGBA:
        rowbytes*=4;
        break;
      default:
        break;
    }
  if (logging)
    {
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Writing PNG image data");
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
    }
  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
    sizeof(*png_pixels));
  if (png_pixels == (unsigned char *) NULL)
    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
  /*
    Initialize image scanlines.
  */
  if (setjmp(png_jmpbuf(ping)))
    {
      /*
        PNG write failed.
      */
#ifdef PNG_DEBUG
     if (image_info->verbose)
        (void) printf("PNG write has failed.\n");
#endif
      png_destroy_write_struct(&ping,&ping_info);
      if (quantum_info != (QuantumInfo *) NULL)
        quantum_info=DestroyQuantumInfo(quantum_info);
      if (png_pixels != (unsigned char *) NULL)
        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
      UnlockSemaphoreInfo(png_semaphore);
#endif
      return(MagickFalse);
    }
  quantum_info=AcquireQuantumInfo(image_info,image);
  if (quantum_info == (QuantumInfo *) NULL)
    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
  quantum_info->format=UndefinedQuantumFormat;
  quantum_info->depth=image_depth;
  num_passes=png_set_interlace_handling(ping);
  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
                      !mng_info->write_png32) &&
      (mng_info->optimize || mng_info->IsPalette ||
       (image_info->type == BilevelType)) &&
      !image_matte && ImageIsMonochrome(image))
    {
      register const PixelPacket
        *p;

      quantum_info->depth=8;
      for (pass=0; pass < num_passes; pass++)
      {
        /*
          Convert PseudoClass image to a PNG monochrome image.
        */
        for (y=0; y < (ssize_t) image->rows; y++)
        {
          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
          if (p == (const PixelPacket *) NULL)
            break;
          if (mng_info->IsPalette)
            {
              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                quantum_info,GrayQuantum,png_pixels,&image->exception);
              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
                  mng_info->write_png_depth &&
                  mng_info->write_png_depth != old_bit_depth)
                {
                  /* Undo pixel scaling */
                  for (i=0; i < (ssize_t) image->columns; i++)
                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
                     >> (8-old_bit_depth));
                }
            }
          else
            {
              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                quantum_info,RedQuantum,png_pixels,&image->exception);
            }
          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
            for (i=0; i < (ssize_t) image->columns; i++)
               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
                      255 : 0);
          if (logging && y == 0)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Writing row of pixels (1)");
          png_write_row(ping,png_pixels);
        }
        if (image->previous == (Image *) NULL)
          {
            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
            if (status == MagickFalse)
              break;
          }
      }
    }
  else
    for (pass=0; pass < num_passes; pass++)
    {
      register const PixelPacket
        *p;

      if ((!mng_info->write_png8 && !mng_info->write_png24 && 
         !mng_info->write_png32) &&
         (image_matte ||
         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
         (mng_info->optimize || mng_info->IsPalette) && ImageIsGray(image))
      {
        for (y=0; y < (ssize_t) image->rows; y++)
        {
          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
          if (p == (const PixelPacket *) NULL)
            break;
          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
            {
              if (mng_info->IsPalette)
                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                  quantum_info,GrayQuantum,png_pixels,&image->exception);
              else
                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                  quantum_info,RedQuantum,png_pixels,&image->exception);
              if (logging && y == 0)
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                     "    Writing GRAY PNG pixels (2)");
            }
          else /* PNG_COLOR_TYPE_GRAY_ALPHA */
            {
              if (logging && y == 0)
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                       "    Writing GRAY_ALPHA PNG pixels (2)");
              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
            }
          if (logging && y == 0)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "    Writing row of pixels (2)");
          png_write_row(ping,png_pixels);
        }
        if (image->previous == (Image *) NULL)
          {
            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
            if (status == MagickFalse)
              break;
          }
      }
    else
      for (pass=0; pass < num_passes; pass++)
      {
        if ((image_depth > 8) || (mng_info->write_png24 ||
            mng_info->write_png32 ||
            (!mng_info->write_png8 && !mng_info->IsPalette)))
          for (y=0; y < (ssize_t) image->rows; y++)
          {
            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
            if (p == (const PixelPacket *) NULL)
              break;
            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
              {
                if (image->storage_class == DirectClass)
                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                    quantum_info,RedQuantum,png_pixels,&image->exception);
                else
                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                    quantum_info,GrayQuantum,png_pixels,&image->exception);
              }
            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
              {
                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
                if (logging && y == 0)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                       "    Writing GRAY_ALPHA PNG pixels (3)");
              }
            else if (image_matte != MagickFalse)
              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                quantum_info,RGBAQuantum,png_pixels,&image->exception);
            else
              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                quantum_info,RGBQuantum,png_pixels,&image->exception);
            if (logging && y == 0)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "    Writing row of pixels (3)");
            png_write_row(ping,png_pixels);
          }
      else
        /* not ((image_depth > 8) || (mng_info->write_png24 ||
            mng_info->write_png32 ||
            (!mng_info->write_png8 && !mng_info->IsPalette))) */
        {
          if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
              (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
            {
              if (logging)
                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
              quantum_info->depth=8;
              image_depth=8;
            }
          for (y=0; y < (ssize_t) image->rows; y++)
          {
            if (logging && y == 0)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
            if (p == (const PixelPacket *) NULL)
              break;
            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                quantum_info,GrayQuantum,png_pixels,&image->exception);
            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
              {
                if (logging && y == 0)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                       "  Writing GRAY_ALPHA PNG pixels (4)");
                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
              }
            else
              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
                quantum_info,IndexQuantum,png_pixels,&image->exception);
            if (logging && y == 0)
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                  "  Writing row of pixels (4)");
            png_write_row(ping,png_pixels);
          }
        }
        if (image->previous == (Image *) NULL)
          {
            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
            if (status == MagickFalse)
              break;
          }
     }
  }
  if (quantum_info != (QuantumInfo *) NULL)
    quantum_info=DestroyQuantumInfo(quantum_info);

  if (logging != MagickFalse)
    {
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Wrote PNG image data");
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    Width: %.20g",(double) ping_width);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    Height: %.20g",(double) ping_height);
      if (mng_info->write_png_depth)
        {
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
        }
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    PNG bit-depth written: %d",ping_bit_depth);
      if (mng_info->write_png_colortype)
        {
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
        }
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    PNG color-type written: %d",ping_color_type);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    PNG Interlace method: %d",ping_interlace_method);
    }
  /*
    Generate text chunks.
  */
  ResetImagePropertyIterator(image);
  property=GetNextImageProperty(image);
  while (property != (const char *) NULL)
  {
    png_textp
      text;

    value=GetImageProperty(image,property);
    if (value != (const char *) NULL)
      {
        text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
        text[0].key=(char *) property;
        text[0].text=(char *) value;
        text[0].text_length=strlen(value);
        text[0].compression=image_info->compression == NoCompression ||
          (image_info->compression == UndefinedCompression &&
          text[0].text_length < 128) ? -1 : 0;
        if (logging != MagickFalse)
          {
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "  Setting up text chunk");
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "    keyword: %s",text[0].key);
          }
        png_set_text(ping,ping_info,text,1);
        png_free(ping,text);
      }
    property=GetNextImageProperty(image);
  }

  /* write any PNG-chunk-e profiles */
  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",(int) logging);

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Writing PNG end info");
  png_write_end(ping,ping_info);
  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
    {
      if (mng_info->page.x || mng_info->page.y ||
          (ping_width != mng_info->page.width) ||
          (ping_height != mng_info->page.height))
        {
          unsigned char
            chunk[32];

          /*
            Write FRAM 4 with clipping boundaries followed by FRAM 1.
          */
          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
          PNGType(chunk,mng_FRAM);
          LogPNGChunk((int) logging,mng_FRAM,27L);
          chunk[4]=4;
          chunk[5]=0;  /* frame name separator (no name) */
          chunk[6]=1;  /* flag for changing delay, for next frame only */
          chunk[7]=0;  /* flag for changing frame timeout */
          chunk[8]=1;  /* flag for changing frame clipping for next frame */
          chunk[9]=0;  /* flag for changing frame sync_id */
          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
          chunk[14]=0; /* clipping boundaries delta type */
          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
          PNGLong(chunk+19,
             (png_uint_32) (mng_info->page.x + ping_width));
          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
          PNGLong(chunk+27,
             (png_uint_32) (mng_info->page.y + ping_height));
          (void) WriteBlob(image,31,chunk);
          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
          mng_info->old_framing_mode=4;
          mng_info->framing_mode=1;
        }
      else
        mng_info->framing_mode=3;
    }
  if (mng_info->write_mng && !mng_info->need_fram &&
      ((int) image->dispose == 3))
     (void) ThrowMagickException(&image->exception,GetMagickModule(),
       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
       "`%s'",image->filename);
  image_depth=save_image_depth;

  /* Save depth actually written */

  s[0]=(char) ping_bit_depth;
  s[1]='\0';

  (void) SetImageProperty(image,"png:bit-depth-written",s);

  /*
    Free PNG resources.
  */

  png_destroy_write_struct(&ping,&ping_info);

  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);

#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
  UnlockSemaphoreInfo(png_semaphore);
#endif

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  exit WriteOnePNGImage()");
  return(MagickTrue);
/*  End write one PNG image */
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e P N G I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WritePNGImage() writes a Portable Network Graphics (PNG) or
%  Multiple-image Network Graphics (MNG) image file.
%
%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
%
%  The format of the WritePNGImage method is:
%
%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o image:  The image.
%
%  Returns MagickTrue on success, MagickFalse on failure.
%
%  Communicating with the PNG encoder:
%
%  While the datastream written is always in PNG format and normally would
%  be given the "png" file extension, this method also writes the following
%  pseudo-formats which are subsets of PNG:
%
%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
%               is present, the tRNS chunk must only have values 0 and 255
%               (i.e., transparency is binary: fully opaque or fully
%               transparent).  The pixels contain 8-bit indices even if
%               they could be represented with 1, 2, or 4 bits. Note: grayscale
%               images will be written as indexed PNG files even though the
%               PNG grayscale type might be slightly more efficient.
%
%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
%               chunk can be present to convey binary transparency by naming
%               one of the colors as transparent.
%
%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
%               transparency is permitted, i.e., the alpha sample for
%               each pixel can have any value from 0 to 255. The alpha
%               channel is present even if the image is fully opaque. 
%
%    o -define: For more precise control of the PNG output, you can use the
%               Image options "png:bit-depth" and "png:color-type".  These
%               can be set from the commandline with "-define" and also
%               from the application programming interfaces.
%
%               png:color-type can be 0, 2, 3, 4, or 6.
%
%               When png:color-type is 0 (Grayscale), png:bit-depth can
%               be 1, 2, 4, 8, or 16.
%
%               When png:color-type is 2 (RGB), png:bit-depth can
%               be 8 or 16.
%
%               When png:color-type is 3 (Indexed), png:bit-depth can
%               be 1, 2, 4, or 8.  This refers to the number of bits
%               used to store the index.  The color samples always have
%               bit-depth 8 in indexed PNG files.
%
%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
%               png:bit-depth can be 8 or 16.
%
%  If the image cannot be written without loss in the requested PNG8, PNG24,
%  or PNG32 format or with the requested bit-depth and color-type without loss,
%  a PNG file will not be written, and the encoder will return MagickFalse.
%  Since image encoders should not be responsible for the "heavy lifting",
%  the user should make sure that ImageMagick has already reduced the
%  image depth and number of colors and limit transparency to binary
%  transparency prior to attempting to write the image in a format that
%  is subject to depth, color, or transparency limitations.
%
%  TODO: Enforce the previous paragraph.
%
%  TODO: Allow all other PNG subformats to be requested via new
%        "-define png:bit-depth -define png:color-type" options.
%
%  Note that another definition, "png:bit-depth-written" exists, but it
%  is not intended for external use.  It is only used internally by the
%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
%
%  It is possible to request that the PNG encoder write previously-formatted
%  ancillary chunks in the output PNG file, using the "-profile" commandline
%  option as shown below or by setting the profile via a programming
%  interface:
%
%     -profile PNG-chunk-x:<file>
%
%  where x is a location flag and <file> is a file containing the chunk
%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
%
%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
%  of the same type, then add a short unique string after the "x" to prevent
%  subsequent profiles from overwriting the preceding ones:
%
%     -profile PNG-chunk-x01:file01 -profile PNG-chunk-x02:file02
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
static MagickBooleanType WritePNGImage(const ImageInfo *image_info,
  Image *image)
{
  MagickBooleanType
    status;

  MngInfo
    *mng_info;

  const char
    *value;

  int
    have_mng_structure;

  unsigned int
    logging;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
  if (status == MagickFalse)
    return(MagickFalse);
  /*
    Allocate a MngInfo structure.
  */
  have_mng_structure=MagickFalse;
  mng_info=(MngInfo *) AcquireQuantumMemory(1,sizeof(MngInfo));
  if (mng_info == (MngInfo *) NULL)
    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
  /*
    Initialize members of the MngInfo structure.
  */
  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
  mng_info->image=image;
  have_mng_structure=MagickTrue;

  /* See if user has requested a specific PNG subformat */

  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;

  if (mng_info->write_png8)
    {
      mng_info->write_png_colortype = /* 3 */ 4;
      mng_info->write_png_depth = 8;
      image->depth = 8;
#if 0 /* this does not work */
      if (image->matte == MagickTrue)
        (void) SetImageType(image,PaletteMatteType);
      else
        (void) SetImageType(image,PaletteType);
      (void) SyncImage(image);
#endif
    }

  if (mng_info->write_png24)
    {
      mng_info->write_png_colortype = /* 2 */ 3;
      mng_info->write_png_depth = 8;
      image->depth = 8;
      if (image->matte == MagickTrue)
        (void) SetImageType(image,TrueColorMatteType);
      else
        (void) SetImageType(image,TrueColorType);
      (void) SyncImage(image);
    }

  if (mng_info->write_png32)
    {
      mng_info->write_png_colortype = /* 6 */  7;
      mng_info->write_png_depth = 8;
      image->depth = 8;
      if (image->matte == MagickTrue)
        (void) SetImageType(image,TrueColorMatteType);
      else
        (void) SetImageType(image,TrueColorType);
      (void) SyncImage(image);
    }

  value=GetImageOption(image_info,"png:bit-depth");
  if (value != (char *) NULL)
    {
      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;
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
    }
  value=GetImageOption(image_info,"png:color-type");
  if (value != (char *) NULL)
    {
      /* We must store colortype+1 because 0 is a valid colortype */
      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;
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
    }

  status=WriteOnePNGImage(mng_info,image_info,image);

  (void) CloseBlob(image);

  MngInfoFreeStruct(mng_info,&have_mng_structure);
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
  return(status);
}

#if defined(JNG_SUPPORTED)

/* Write one JNG image */
static MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
   const ImageInfo *image_info,Image *image)
{
  Image
    *jpeg_image;

  ImageInfo
    *jpeg_image_info;

  MagickBooleanType
    status;

  size_t
    length;

  unsigned char
    *blob,
    chunk[80],
    *p;

  unsigned int
    jng_alpha_compression_method,
    jng_alpha_sample_depth,
    jng_color_type,
    logging,
    transparent;

  size_t
    jng_quality;

  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
    "  enter WriteOneJNGImage()");

  blob=(unsigned char *) NULL;
  jpeg_image=(Image *) NULL;
  jpeg_image_info=(ImageInfo *) NULL;

  status=MagickTrue;
  transparent=image_info->type==GrayscaleMatteType ||
     image_info->type==TrueColorMatteType;
  jng_color_type=10;
  jng_alpha_sample_depth=0;
  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
  jng_alpha_compression_method=0;

  if (image->matte != MagickFalse)
    {
      /* if any pixels are transparent */
      transparent=MagickTrue;
      if (image_info->compression==JPEGCompression)
        jng_alpha_compression_method=8;
    }

  if (transparent)
    {
      jng_color_type=14;
      /* Create JPEG blob, image, and image_info */
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "  Creating jpeg_image_info for opacity.");
      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
      if (jpeg_image_info == (ImageInfo *) NULL)
        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
      if (logging != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "  Creating jpeg_image.");
      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
      if (jpeg_image == (Image *) NULL)
        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
      status=SeparateImageChannel(jpeg_image,OpacityChannel);
      status=NegateImage(jpeg_image,MagickFalse);
      jpeg_image->matte=MagickFalse;
      if (jng_quality >= 1000)
        jpeg_image_info->quality=jng_quality/1000;
      else
        jpeg_image_info->quality=jng_quality;
      jpeg_image_info->type=GrayscaleType;
      (void) SetImageType(jpeg_image,GrayscaleType);
      (void) AcquireUniqueFilename(jpeg_image->filename);
      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
        "%s",jpeg_image->filename);
    }

  /* To do: check bit depth of PNG alpha channel */

  /* Check if image is grayscale. */
  if (image_info->type != TrueColorMatteType && image_info->type !=
    TrueColorType && ImageIsGray(image))
    jng_color_type-=2;

  if (transparent)
    {
      if (jng_alpha_compression_method==0)
        {
          const char
            *value;

          /* Encode opacity as a grayscale PNG blob */
          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
            &image->exception);
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "  Creating PNG blob.");
          length=0;

          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
          jpeg_image_info->interlace=NoInterlace;

          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
            &image->exception);

          /* Retrieve sample depth used */
          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
          if (value != (char *) NULL)
            jng_alpha_sample_depth= (unsigned int) value[0];
        }
      else
        {
          /* Encode opacity as a grayscale JPEG blob */

          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
            &image->exception);

          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
          jpeg_image_info->interlace=NoInterlace;
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "  Creating blob.");
          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
           &image->exception);
          jng_alpha_sample_depth=8;
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "  Successfully read jpeg_image into a blob, length=%.20g.",
              (double) length);

        }
      /* Destroy JPEG image and image_info */
      jpeg_image=DestroyImage(jpeg_image);
      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
    }

  /* Write JHDR chunk */
  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
  PNGType(chunk,mng_JHDR);
  LogPNGChunk((int) logging,mng_JHDR,16L);
  PNGLong(chunk+4,(png_uint_32) image->columns);
  PNGLong(chunk+8,(png_uint_32) image->rows);
  chunk[12]=jng_color_type;
  chunk[13]=8;  /* sample depth */
  chunk[14]=8; /*jng_image_compression_method */
  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
  chunk[16]=jng_alpha_sample_depth;
  chunk[17]=jng_alpha_compression_method;
  chunk[18]=0; /*jng_alpha_filter_method */
  chunk[19]=0; /*jng_alpha_interlace_method */
  (void) WriteBlob(image,20,chunk);
  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
  if (logging != MagickFalse)
    {
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    JNG width:%15lu",(unsigned long) image->columns);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    JNG height:%14lu",(unsigned long) image->rows);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    JNG color type:%10d",jng_color_type);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    JNG sample depth:%8d",8);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    JNG compression:%9d",8);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    JNG interlace:%11d",0);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    JNG alpha compression:%3d",jng_alpha_compression_method);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    JNG alpha filter:%8d",0);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    JNG alpha interlace:%5d",0);
    }

  /* Write any JNG-chunk-b profiles */ 
  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",(int) logging);

  /*
     Write leading ancillary chunks
  */

  if (transparent)
  {
    /*
      Write JNG bKGD chunk
    */

    unsigned char
      blue,
      green,
      red;

    ssize_t
      num_bytes;

    if (jng_color_type == 8 || jng_color_type == 12)
      num_bytes=6L;
    else
      num_bytes=10L;
    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
    PNGType(chunk,mng_bKGD);
    LogPNGChunk((int) logging,mng_bKGD,(size_t) (num_bytes-4L));
    red=ScaleQuantumToChar(image->background_color.red);
    green=ScaleQuantumToChar(image->background_color.green);
    blue=ScaleQuantumToChar(image->background_color.blue);
    *(chunk+4)=0;
    *(chunk+5)=red;
    *(chunk+6)=0;
    *(chunk+7)=green;
    *(chunk+8)=0;
    *(chunk+9)=blue;
    (void) WriteBlob(image,(size_t) num_bytes,chunk);
    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
  }

  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
    {
      /*
        Write JNG sRGB chunk
      */
      (void) WriteBlobMSBULong(image,1L);
      PNGType(chunk,mng_sRGB);
      LogPNGChunk((int) logging,mng_sRGB,1L);
      if (image->rendering_intent != UndefinedIntent)
        chunk[4]=(unsigned char)
          PNG_RenderingIntent_from_Magick_RenderingIntent(
          (image->rendering_intent));
      else
        chunk[4]=(unsigned char)
          PNG_RenderingIntent_from_Magick_RenderingIntent(
          (PerceptualIntent));
      (void) WriteBlob(image,5,chunk);
      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
    }
  else
    {
      if (image->gamma != 0.0)
        {
          /*
             Write JNG gAMA chunk
          */
          (void) WriteBlobMSBULong(image,4L);
          PNGType(chunk,mng_gAMA);
          LogPNGChunk((int) logging,mng_gAMA,4L);
          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
          (void) WriteBlob(image,8,chunk);
          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
        }
      if ((mng_info->equal_chrms == MagickFalse) &&
          (image->chromaticity.red_primary.x != 0.0))
        {
          PrimaryInfo
            primary;

          /*
             Write JNG cHRM chunk
          */
          (void) WriteBlobMSBULong(image,32L);
          PNGType(chunk,mng_cHRM);
          LogPNGChunk((int) logging,mng_cHRM,32L);
          primary=image->chromaticity.white_point;
          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
          primary=image->chromaticity.red_primary;
          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
          primary=image->chromaticity.green_primary;
          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
          primary=image->chromaticity.blue_primary;
          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
          (void) WriteBlob(image,36,chunk);
          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
        }
    }
  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
    {
      /*
         Write JNG pHYs chunk
      */
      (void) WriteBlobMSBULong(image,9L);
      PNGType(chunk,mng_pHYs);
      LogPNGChunk((int) logging,mng_pHYs,9L);
      if (image->units == PixelsPerInchResolution)
        {
          PNGLong(chunk+4,(png_uint_32)
            (image->x_resolution*100.0/2.54+0.5));
          PNGLong(chunk+8,(png_uint_32)
            (image->y_resolution*100.0/2.54+0.5));
          chunk[12]=1;
        }
      else
        {
          if (image->units == PixelsPerCentimeterResolution)
            {
              PNGLong(chunk+4,(png_uint_32)
                (image->x_resolution*100.0+0.5));
              PNGLong(chunk+8,(png_uint_32)
                (image->y_resolution*100.0+0.5));
              chunk[12]=1;
            }
          else
            {
              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
              chunk[12]=0;
            }
        }
      (void) WriteBlob(image,13,chunk);
      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
    }

  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
    {
      /*
         Write JNG oFFs chunk
      */
      (void) WriteBlobMSBULong(image,9L);
      PNGType(chunk,mng_oFFs);
      LogPNGChunk((int) logging,mng_oFFs,9L);
      PNGsLong(chunk+4,(ssize_t) (image->page.x));
      PNGsLong(chunk+8,(ssize_t) (image->page.y));
      chunk[12]=0;
      (void) WriteBlob(image,13,chunk);
      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
    }
  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
    {
       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
       PNGType(chunk,mng_vpAg);
       LogPNGChunk((int) logging,mng_vpAg,9L);
       PNGLong(chunk+4,(png_uint_32) image->page.width);
       PNGLong(chunk+8,(png_uint_32) image->page.height);
       chunk[12]=0;   /* unit = pixels */
       (void) WriteBlob(image,13,chunk);
       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
    }


  if (transparent)
    {
      if (jng_alpha_compression_method==0)
        {
          register ssize_t
            i;

          ssize_t
            len;

          /* Write IDAT chunk header */
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "  Write IDAT chunks from blob, length=%.20g.",(double)
              length);

          /* Copy IDAT chunks */
          len=0;
          p=blob+8;
          for (i=8; i<(ssize_t) length; i+=len+12)
          {
            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
            p+=4;
            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
              {
                /* Found an IDAT chunk. */
                (void) WriteBlobMSBULong(image,(size_t) len);
                LogPNGChunk((int) logging,mng_IDAT,(size_t) len);
                (void) WriteBlob(image,(size_t) len+4,p);
                (void) WriteBlobMSBULong(image,
                    crc32(0,p,(uInt) len+4));
              }
            else
              {
                if (logging != MagickFalse)
                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                    "    Skipping %c%c%c%c chunk, length=%.20g.",
                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
              }
            p+=(8+len);
          }
        }
      else
        {
          /* Write JDAA chunk header */
          if (logging != MagickFalse)
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "  Write JDAA chunk, length=%.20g.",(double) length);
          (void) WriteBlobMSBULong(image,(size_t) length);
          PNGType(chunk,mng_JDAA);
          LogPNGChunk((int) logging,mng_JDAA,length);
          /* Write JDAT chunk(s) data */
          (void) WriteBlob(image,4,chunk);
          (void) WriteBlob(image,length,blob);
          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
             (uInt) length));
        }
      blob=(unsigned char *) RelinquishMagickMemory(blob);
    }

  /* Encode image as a JPEG blob */
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Creating jpeg_image_info.");
  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
  if (jpeg_image_info == (ImageInfo *) NULL)
    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Creating jpeg_image.");

  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
  if (jpeg_image == (Image *) NULL)
    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);

  (void) AcquireUniqueFilename(jpeg_image->filename);
  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
    jpeg_image->filename);

  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
    &image->exception);

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
      (double) jpeg_image->rows);

  if (jng_color_type == 8 || jng_color_type == 12)
    jpeg_image_info->type=GrayscaleType;
  jpeg_image_info->quality=jng_quality % 1000;
  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Creating blob.");
  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
  if (logging != MagickFalse)
    {
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Successfully read jpeg_image into a blob, length=%.20g.",
        (double) length);

      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Write JDAT chunk, length=%.20g.",(double) length);
    }
  /* Write JDAT chunk(s) */
  (void) WriteBlobMSBULong(image,(size_t) length);
  PNGType(chunk,mng_JDAT);
  LogPNGChunk((int) logging,mng_JDAT,length);
  (void) WriteBlob(image,4,chunk);
  (void) WriteBlob(image,length,blob);
  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));

  jpeg_image=DestroyImage(jpeg_image);
  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
  blob=(unsigned char *) RelinquishMagickMemory(blob);

  /* Write any JNG-chunk-e profiles */
  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",(int) logging);

  /* Write IEND chunk */
  (void) WriteBlobMSBULong(image,0L);
  PNGType(chunk,mng_IEND);
  LogPNGChunk((int) logging,mng_IEND,0);
  (void) WriteBlob(image,4,chunk);
  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));

  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  exit WriteOneJNGImage()");
  return(status);
}


/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e J N G I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
%
%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
%
%  The format of the WriteJNGImage method is:
%
%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o image:  The image.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
static MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
{
  MagickBooleanType
    status;

  MngInfo
    *mng_info;

  int
    have_mng_structure;

  unsigned int
    logging;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
  if (status == MagickFalse)
    return(status);

  /*
    Allocate a MngInfo structure.
  */
  have_mng_structure=MagickFalse;
  mng_info=(MngInfo *) AcquireQuantumMemory(1,sizeof(MngInfo));
  if (mng_info == (MngInfo *) NULL)
    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
  /*
    Initialize members of the MngInfo structure.
  */
  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
  mng_info->image=image;
  have_mng_structure=MagickTrue;

  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");

  status=WriteOneJNGImage(mng_info,image_info,image);
  (void) CloseBlob(image);

  (void) CatchImageException(image);
  MngInfoFreeStruct(mng_info,&have_mng_structure);
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
  return(status);
}
#endif



static MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
{
  const char
    *option;

  Image
    *next_image;

  MagickBooleanType
    status;

  MngInfo
    *mng_info;

  int
    have_mng_structure,
    image_count,
    need_iterations,
    need_matte;

  volatile int
#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
    defined(PNG_MNG_FEATURES_SUPPORTED)
    need_local_plte,
#endif
    all_images_are_gray,
    logging,
    need_defi,
    optimize,
    use_global_plte;

  register ssize_t
    i;

  unsigned char
    chunk[800];

  volatile unsigned int
    write_jng,
    write_mng;

  volatile size_t
    scene;

  size_t
    final_delay=0,
    initial_delay;

#if (PNG_LIBPNG_VER < 10200)
    if (image_info->verbose)
      printf("Your PNG library (libpng-%s) is rather old.\n",
         PNG_LIBPNG_VER_STRING);
#endif

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
  if (status == MagickFalse)
    return(status);

  /*
    Allocate a MngInfo structure.
  */
  have_mng_structure=MagickFalse;
  mng_info=(MngInfo *) AcquireQuantumMemory(1,sizeof(MngInfo));
  if (mng_info == (MngInfo *) NULL)
    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
  /*
    Initialize members of the MngInfo structure.
  */
  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
  mng_info->image=image;
  have_mng_structure=MagickTrue;
  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;

  /*
   * See if user has requested a specific PNG subformat to be used
   * for all of the PNGs in the MNG being written, e.g.,
   *
   *    convert *.png png8:animation.mng
   *
   * To do: check -define png:bit_depth and png:color_type as well,
   * or perhaps use mng:bit_depth and mng:color_type instead for
   * global settings.
   */

  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;

  write_jng=MagickFalse;
  if (image_info->compression == JPEGCompression)
    write_jng=MagickTrue;

  mng_info->adjoin=image_info->adjoin &&
    (GetNextImageInList(image) != (Image *) NULL) && write_mng;

  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
    optimize=MagickFalse;
  else
    optimize=(image_info->type == OptimizeType || image_info->type ==
      UndefinedType);

  if (logging != MagickFalse)
    {
      /* Log some info about the input */
      Image
        *p;

      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Checking input image(s)");
      if (optimize)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Optimize: TRUE");
      else
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Optimize: FALSE");
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    Image_info depth: %.20g",(double) image_info->depth);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "    Type: %d",image_info->type);

      scene=0;
      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
      {
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "    Scene: %.20g",(double) scene++);
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "      Image depth: %.20g",(double) p->depth);
        if (p->matte)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "      Matte: True");
        else
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "      Matte: False");
        if (p->storage_class == PseudoClass)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "      Storage class: PseudoClass");
        else
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "      Storage class: DirectClass");
        if (p->colors)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "      Number of colors: %.20g",(double) p->colors);
        else
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "      Number of colors: unspecified");
        if (mng_info->adjoin == MagickFalse)
          break;
      }
    }

  /*
    Sometimes we get PseudoClass images whose RGB values don't match
    the colors in the colormap.  This code syncs the RGB values.
  */
  {
    Image
      *p;

    for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
    {
      if (p->taint && p->storage_class == PseudoClass)
         (void) SyncImage(p);
      if (mng_info->adjoin == MagickFalse)
        break;
    }
  }

#ifdef PNG_BUILD_PALETTE
  if (optimize)
    {
      /*
        Sometimes we get DirectClass images that have 256 colors or fewer.
        This code will convert them to PseudoClass and build a colormap.
      */
      Image
        *p;

      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
      {
        if (p->storage_class != PseudoClass)
          {
            p->colors=GetNumberColors(p,(FILE *) NULL,&p->exception);
            if (p->colors <= 256)
              {
                p->colors=0;
                if (p->matte != MagickFalse)
                  (void) SetImageType(p,PaletteMatteType);
                else
                  (void) SetImageType(p,PaletteType);
              }
          }
        if (mng_info->adjoin == MagickFalse)
          break;
      }
    }
#endif

  use_global_plte=MagickFalse;
  all_images_are_gray=MagickFalse;
#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
  need_local_plte=MagickTrue;
#endif
  need_defi=MagickFalse;
  need_matte=MagickFalse;
  mng_info->framing_mode=1;
  mng_info->old_framing_mode=1;

  if (write_mng)
      if (image_info->page != (char *) NULL)
        {
          /*
            Determine image bounding box.
          */
          SetGeometry(image,&mng_info->page);
          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
        }
  if (write_mng)
    {
      unsigned int
        need_geom;

      unsigned short
        red,
        green,
        blue;

      mng_info->page=image->page;
      need_geom=MagickTrue;
      if (mng_info->page.width || mng_info->page.height)
         need_geom=MagickFalse;
      /*
        Check all the scenes.
      */
      initial_delay=image->delay;
      need_iterations=MagickFalse;
      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
      mng_info->equal_physs=MagickTrue,
      mng_info->equal_gammas=MagickTrue;
      mng_info->equal_srgbs=MagickTrue;
      mng_info->equal_backgrounds=MagickTrue;
      image_count=0;
#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
    defined(PNG_MNG_FEATURES_SUPPORTED)
      all_images_are_gray=MagickTrue;
      mng_info->equal_palettes=MagickFalse;
      need_local_plte=MagickFalse;
#endif
      for (next_image=image; next_image != (Image *) NULL; )
      {
        if (need_geom)
          {
            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
              mng_info->page.width=next_image->columns+next_image->page.x;
            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
              mng_info->page.height=next_image->rows+next_image->page.y;
          }
        if (next_image->page.x || next_image->page.y)
          need_defi=MagickTrue;
        if (next_image->matte)
          need_matte=MagickTrue;
        if ((int) next_image->dispose >= BackgroundDispose)
          if (next_image->matte || next_image->page.x || next_image->page.y ||
              ((next_image->columns < mng_info->page.width) &&
               (next_image->rows < mng_info->page.height)))
            mng_info->need_fram=MagickTrue;
        if (next_image->iterations)
          need_iterations=MagickTrue;
        final_delay=next_image->delay;
        if (final_delay != initial_delay || final_delay > 1UL*
           next_image->ticks_per_second)
          mng_info->need_fram=1;
#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
    defined(PNG_MNG_FEATURES_SUPPORTED)
        /*
          check for global palette possibility.
        */
        if (image->matte != MagickFalse)
           need_local_plte=MagickTrue;
        if (need_local_plte == 0)
          {
            if (ImageIsGray(image) == MagickFalse)
              all_images_are_gray=MagickFalse;
            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
            if (use_global_plte == 0)
              use_global_plte=mng_info->equal_palettes;
            need_local_plte=!mng_info->equal_palettes;
          }
#endif
        if (GetNextImageInList(next_image) != (Image *) NULL)
          {
            if (next_image->background_color.red !=
                next_image->next->background_color.red ||
                next_image->background_color.green !=
                next_image->next->background_color.green ||
                next_image->background_color.blue !=
                next_image->next->background_color.blue)
              mng_info->equal_backgrounds=MagickFalse;
            if (next_image->gamma != next_image->next->gamma)
              mng_info->equal_gammas=MagickFalse;
            if (next_image->rendering_intent !=
                next_image->next->rendering_intent)
              mng_info->equal_srgbs=MagickFalse;
            if ((next_image->units != next_image->next->units) ||
                (next_image->x_resolution != next_image->next->x_resolution) ||
                (next_image->y_resolution != next_image->next->y_resolution))
              mng_info->equal_physs=MagickFalse;
            if (mng_info->equal_chrms)
              {
                if (next_image->chromaticity.red_primary.x !=
                    next_image->next->chromaticity.red_primary.x ||
                    next_image->chromaticity.red_primary.y !=
                    next_image->next->chromaticity.red_primary.y ||
                    next_image->chromaticity.green_primary.x !=
                    next_image->next->chromaticity.green_primary.x ||
                    next_image->chromaticity.green_primary.y !=
                    next_image->next->chromaticity.green_primary.y ||
                    next_image->chromaticity.blue_primary.x !=
                    next_image->next->chromaticity.blue_primary.x ||
                    next_image->chromaticity.blue_primary.y !=
                    next_image->next->chromaticity.blue_primary.y ||
                    next_image->chromaticity.white_point.x !=
                    next_image->next->chromaticity.white_point.x ||
                    next_image->chromaticity.white_point.y !=
                    next_image->next->chromaticity.white_point.y)
                  mng_info->equal_chrms=MagickFalse;
              }
          }
        image_count++;
        next_image=GetNextImageInList(next_image);
      }
      if (image_count < 2)
        {
          mng_info->equal_backgrounds=MagickFalse;
          mng_info->equal_chrms=MagickFalse;
          mng_info->equal_gammas=MagickFalse;
          mng_info->equal_srgbs=MagickFalse;
          mng_info->equal_physs=MagickFalse;
          use_global_plte=MagickFalse;
#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
          need_local_plte=MagickTrue;
#endif
          need_iterations=MagickFalse;
        }
     if (mng_info->need_fram == MagickFalse)
       {
         /*
           Only certain framing rates 100/n are exactly representable without
           the FRAM chunk but we'll allow some slop in VLC files
         */
         if (final_delay == 0)
           {
             if (need_iterations != MagickFalse)
               {
                 /*
                   It's probably a GIF with loop; don't run it *too* fast.
                 */
                 if (mng_info->adjoin)
                   {
                     final_delay=10;
                     (void) ThrowMagickException(&image->exception,
                        GetMagickModule(),CoderWarning,
                       "input has zero delay between all frames; assuming",
                       " 10 cs `%s'","");
                   }
               }
             else
               mng_info->ticks_per_second=0;
           }
         if (final_delay != 0)
           mng_info->ticks_per_second=(png_uint_32) (image->ticks_per_second/final_delay);
         if (final_delay > 50)
           mng_info->ticks_per_second=2;
         if (final_delay > 75)
           mng_info->ticks_per_second=1;
         if (final_delay > 125)
           mng_info->need_fram=MagickTrue;
         if (need_defi && final_delay > 2 && (final_delay != 4) &&
            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
            (final_delay != 25) && (final_delay != 50) && (final_delay !=
               1UL*image->ticks_per_second))
           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
       }
     if (mng_info->need_fram != MagickFalse)
        mng_info->ticks_per_second=1UL*image->ticks_per_second;
     /*
        If pseudocolor, we should also check to see if all the
        palettes are identical and write a global PLTE if they are.
        ../glennrp Feb 99.
     */
     /*
        Write the MNG version 1.0 signature and MHDR chunk.
     */
     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
     PNGType(chunk,mng_MHDR);
     LogPNGChunk((int) logging,mng_MHDR,28L);
     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
     PNGLong(chunk+12,mng_info->ticks_per_second);
     PNGLong(chunk+16,0L);  /* layer count=unknown */
     PNGLong(chunk+20,0L);  /* frame count=unknown */
     PNGLong(chunk+24,0L);  /* play time=unknown   */
     if (write_jng)
       {
         if (need_matte)
           {
             if (need_defi || mng_info->need_fram || use_global_plte)
               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
             else
               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
           }
         else
           {
             if (need_defi || mng_info->need_fram || use_global_plte)
               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
             else
               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
           }
       }
     else
       {
         if (need_matte)
           {
             if (need_defi || mng_info->need_fram || use_global_plte)
               PNGLong(chunk+28,11L);    /* simplicity=LC */
             else
               PNGLong(chunk+28,9L);    /* simplicity=VLC */
           }
         else
           {
             if (need_defi || mng_info->need_fram || use_global_plte)
               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
             else
               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
           }
       }
     (void) WriteBlob(image,32,chunk);
     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
     option=GetImageOption(image_info,"mng:need-cacheoff");
     if (option != (const char *) NULL)
       {
         size_t
           length;

         /*
           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
         */
         PNGType(chunk,mng_nEED);
         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
         (void) WriteBlobMSBULong(image,(size_t) length);
         LogPNGChunk((int) logging,mng_nEED,(size_t) length);
         length+=4;
         (void) WriteBlob(image,length,chunk);
         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
       }
     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
         (GetNextImageInList(image) != (Image *) NULL) &&
         (image->iterations != 1))
       {
         /*
           Write MNG TERM chunk
         */
         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
         PNGType(chunk,mng_TERM);
         LogPNGChunk((int) logging,mng_TERM,10L);
         chunk[4]=3;  /* repeat animation */
         chunk[5]=0;  /* show last frame when done */
         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
            final_delay/MagickMax(image->ticks_per_second,1)));
         if (image->iterations == 0)
           PNGLong(chunk+10,PNG_UINT_31_MAX);
         else
           PNGLong(chunk+10,(png_uint_32) image->iterations);
         if (logging != MagickFalse)
           {
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
              final_delay/MagickMax(image->ticks_per_second,1)));
             if (image->iterations == 0)
               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
             else
               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                 "     Image iterations: %.20g",(double) image->iterations);
           }
         (void) WriteBlob(image,14,chunk);
         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
       }
     /*
       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
     */
     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
          mng_info->equal_srgbs)
       {
         /*
           Write MNG sRGB chunk
         */
         (void) WriteBlobMSBULong(image,1L);
         PNGType(chunk,mng_sRGB);
         LogPNGChunk((int) logging,mng_sRGB,1L);
         if (image->rendering_intent != UndefinedIntent)
           chunk[4]=(unsigned char)
             PNG_RenderingIntent_from_Magick_RenderingIntent(
             (image->rendering_intent));
         else
           chunk[4]=(unsigned char)
             PNG_RenderingIntent_from_Magick_RenderingIntent(
             (PerceptualIntent));
         (void) WriteBlob(image,5,chunk);
         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
         mng_info->have_write_global_srgb=MagickTrue;
       }
     else
       {
         if (image->gamma && mng_info->equal_gammas)
           {
             /*
                Write MNG gAMA chunk
             */
             (void) WriteBlobMSBULong(image,4L);
             PNGType(chunk,mng_gAMA);
             LogPNGChunk((int) logging,mng_gAMA,4L);
             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
             (void) WriteBlob(image,8,chunk);
             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
             mng_info->have_write_global_gama=MagickTrue;
           }
         if (mng_info->equal_chrms)
           {
             PrimaryInfo
               primary;

             /*
                Write MNG cHRM chunk
             */
             (void) WriteBlobMSBULong(image,32L);
             PNGType(chunk,mng_cHRM);
             LogPNGChunk((int) logging,mng_cHRM,32L);
             primary=image->chromaticity.white_point;
             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
             primary=image->chromaticity.red_primary;
             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
             primary=image->chromaticity.green_primary;
             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
             primary=image->chromaticity.blue_primary;
             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
             (void) WriteBlob(image,36,chunk);
             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
             mng_info->have_write_global_chrm=MagickTrue;
           }
       }
     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
       {
         /*
            Write MNG pHYs chunk
         */
         (void) WriteBlobMSBULong(image,9L);
         PNGType(chunk,mng_pHYs);
         LogPNGChunk((int) logging,mng_pHYs,9L);
         if (image->units == PixelsPerInchResolution)
           {
             PNGLong(chunk+4,(png_uint_32)
               (image->x_resolution*100.0/2.54+0.5));
             PNGLong(chunk+8,(png_uint_32)
               (image->y_resolution*100.0/2.54+0.5));
             chunk[12]=1;
           }
         else
           {
             if (image->units == PixelsPerCentimeterResolution)
               {
                 PNGLong(chunk+4,(png_uint_32)
                   (image->x_resolution*100.0+0.5));
                 PNGLong(chunk+8,(png_uint_32)
                   (image->y_resolution*100.0+0.5));
                 chunk[12]=1;
               }
             else
               {
                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
                 chunk[12]=0;
               }
           }
         (void) WriteBlob(image,13,chunk);
         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
       }
     /*
       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
       or does not cover the entire frame.
     */
     if (write_mng && (image->matte || image->page.x > 0 ||
         image->page.y > 0 || (image->page.width &&
         (image->page.width+image->page.x < mng_info->page.width))
         || (image->page.height && (image->page.height+image->page.y
         < mng_info->page.height))))
       {
         (void) WriteBlobMSBULong(image,6L);
         PNGType(chunk,mng_BACK);
         LogPNGChunk((int) logging,mng_BACK,6L);
         red=ScaleQuantumToShort(image->background_color.red);
         green=ScaleQuantumToShort(image->background_color.green);
         blue=ScaleQuantumToShort(image->background_color.blue);
         PNGShort(chunk+4,red);
         PNGShort(chunk+6,green);
         PNGShort(chunk+8,blue);
         (void) WriteBlob(image,10,chunk);
         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
         if (mng_info->equal_backgrounds)
           {
             (void) WriteBlobMSBULong(image,6L);
             PNGType(chunk,mng_bKGD);
             LogPNGChunk((int) logging,mng_bKGD,6L);
             (void) WriteBlob(image,10,chunk);
             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
           }
       }

#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
     if ((need_local_plte == MagickFalse) &&
         (image->storage_class == PseudoClass) &&
         (all_images_are_gray == MagickFalse))
       {
         size_t
           data_length;

         /*
           Write MNG PLTE chunk
         */
         data_length=3*image->colors;
         (void) WriteBlobMSBULong(image,data_length);
         PNGType(chunk,mng_PLTE);
         LogPNGChunk((int) logging,mng_PLTE,data_length);
         for (i=0; i < (ssize_t) image->colors; i++)
         {
           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
         }
         (void) WriteBlob(image,data_length+4,chunk);
         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
         mng_info->have_write_global_plte=MagickTrue;
       }
#endif
    }
  scene=0;
  mng_info->delay=0;
#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
    defined(PNG_MNG_FEATURES_SUPPORTED)
  mng_info->equal_palettes=MagickFalse;
#endif
  do
  {
    if (mng_info->adjoin)
    {
#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
    defined(PNG_MNG_FEATURES_SUPPORTED)
    /*
      If we aren't using a global palette for the entire MNG, check to
      see if we can use one for two or more consecutive images.
    */
    if (need_local_plte && use_global_plte && !all_images_are_gray)
      {
        if (mng_info->IsPalette)
          {
            /*
              When equal_palettes is true, this image has the same palette
              as the previous PseudoClass image
            */
            mng_info->have_write_global_plte=mng_info->equal_palettes;
            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
              {
                /*
                  Write MNG PLTE chunk
                */
                size_t
                  data_length;

                data_length=3*image->colors;
                (void) WriteBlobMSBULong(image,data_length);
                PNGType(chunk,mng_PLTE);
                LogPNGChunk((int) logging,mng_PLTE,data_length);
                for (i=0; i < (ssize_t) image->colors; i++)
                {
                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
                }
                (void) WriteBlob(image,data_length+4,chunk);
                (void) WriteBlobMSBULong(image,crc32(0,chunk,
                   (uInt) (data_length+4)));
                mng_info->have_write_global_plte=MagickTrue;
              }
          }
        else
          mng_info->have_write_global_plte=MagickFalse;
      }
#endif
    if (need_defi)
      {
        ssize_t
          previous_x,
          previous_y;

        if (scene)
          {
            previous_x=mng_info->page.x;
            previous_y=mng_info->page.y;
          }
        else
          {
            previous_x=0;
            previous_y=0;
          }
        mng_info->page=image->page;
        if ((mng_info->page.x !=  previous_x) ||
            (mng_info->page.y != previous_y))
          {
             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
             PNGType(chunk,mng_DEFI);
             LogPNGChunk((int) logging,mng_DEFI,12L);
             chunk[4]=0; /* object 0 MSB */
             chunk[5]=0; /* object 0 LSB */
             chunk[6]=0; /* visible  */
             chunk[7]=0; /* abstract */
             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
             (void) WriteBlob(image,16,chunk);
             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
          }
      }
    }

   mng_info->write_mng=write_mng;

   if ((int) image->dispose >= 3)
     mng_info->framing_mode=3;

   if (mng_info->need_fram && mng_info->adjoin &&
       ((image->delay != mng_info->delay) ||
        (mng_info->framing_mode != mng_info->old_framing_mode)))
     {
       if (image->delay == mng_info->delay)
         {
           /*
             Write a MNG FRAM chunk with the new framing mode.
           */
           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
           PNGType(chunk,mng_FRAM);
           LogPNGChunk((int) logging,mng_FRAM,1L);
           chunk[4]=(unsigned char) mng_info->framing_mode;
           (void) WriteBlob(image,5,chunk);
           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
         }
       else
         {
           /*
             Write a MNG FRAM chunk with the delay.
           */
           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
           PNGType(chunk,mng_FRAM);
           LogPNGChunk((int) logging,mng_FRAM,10L);
           chunk[4]=(unsigned char) mng_info->framing_mode;
           chunk[5]=0;  /* frame name separator (no name) */
           chunk[6]=2;  /* flag for changing default delay */
           chunk[7]=0;  /* flag for changing frame timeout */
           chunk[8]=0;  /* flag for changing frame clipping */
           chunk[9]=0;  /* flag for changing frame sync_id */
           PNGLong(chunk+10,(png_uint_32)
             ((mng_info->ticks_per_second*
             image->delay)/MagickMax(image->ticks_per_second,1)));
           (void) WriteBlob(image,14,chunk);
           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
           mng_info->delay=(png_uint_32) image->delay;
         }
       mng_info->old_framing_mode=mng_info->framing_mode;
     }

#if defined(JNG_SUPPORTED)
   if (image_info->compression == JPEGCompression)
     {
       ImageInfo
         *write_info;

       if (logging != MagickFalse)
         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "  Writing JNG object.");
       /* To do: specify the desired alpha compression method. */
       write_info=CloneImageInfo(image_info);
       write_info->compression=UndefinedCompression;
       status=WriteOneJNGImage(mng_info,write_info,image);
       write_info=DestroyImageInfo(write_info);
     }
   else
#endif
     {
       if (logging != MagickFalse)
         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "  Writing PNG object.");
       status=WriteOnePNGImage(mng_info,image_info,image);
     }

    if (status == MagickFalse)
      {
        MngInfoFreeStruct(mng_info,&have_mng_structure);
        (void) CloseBlob(image);
        return(MagickFalse);
      }
    (void) CatchImageException(image);
    if (GetNextImageInList(image) == (Image *) NULL)
      break;
    image=SyncNextImageInList(image);
    status=SetImageProgress(image,SaveImagesTag,scene++,
      GetImageListLength(image));
    if (status == MagickFalse)
      break;
  } while (mng_info->adjoin);
  if (write_mng)
    {
      while (GetPreviousImageInList(image) != (Image *) NULL)
        image=GetPreviousImageInList(image);
      /*
        Write the MEND chunk.
      */
      (void) WriteBlobMSBULong(image,0x00000000L);
      PNGType(chunk,mng_MEND);
      LogPNGChunk((int) logging,mng_MEND,0L);
      (void) WriteBlob(image,4,chunk);
      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
    }
  /*
    Relinquish resources.
  */
  (void) CloseBlob(image);
  MngInfoFreeStruct(mng_info,&have_mng_structure);
  if (logging != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
  return(MagickTrue);
}
#else /* PNG_LIBPNG_VER > 10011 */
static MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
{
  image=image;
  printf("Your PNG library is too old: You have libpng-%s\n",
     PNG_LIBPNG_VER_STRING);
  ThrowBinaryException(CoderError,"PNG library is too old",
     image_info->filename);
}
static MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
{
  return(WritePNGImage(image_info,image));
}
#endif /* PNG_LIBPNG_VER > 10011 */
#endif
