png.c revision ed5525230af20461366cdc5b8bbe0f7f9b166c44
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            PPPP   N   N   GGGG                              %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P   P  NN  N  G                                  %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            PPPP   N N N  G  GG                              %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P      N  NN  G   G                              %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P      N   N   GGG                               %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%              Read/Write Portable Network Graphics Image Format              %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                John Cristy                                  %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                           Glenn Randers-Pehrson                             %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                               November 1997                                 %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/studio.h"
455a2ca481ab4ff6751bba842263739966e53441aacristy#include "magick/attribute.h"
463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob.h"
473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob-private.h"
483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/cache.h"
493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color.h"
503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color-private.h"
513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/colorspace.h"
523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/constitute.h"
533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/enhance.h"
543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception.h"
553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception-private.h"
563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/geometry.h"
57f2e1166e90de2dfe2e6a2aed7cd5f73640f34a7acristy#include "magick/histogram.h"
583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image.h"
593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image-private.h"
603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/layer.h"
613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/list.h"
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/log.h"
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/magick.h"
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/memory_.h"
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/module.h"
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor.h"
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor-private.h"
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/option.h"
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/profile.h"
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/property.h"
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantize.h"
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/resource_.h"
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/semaphore.h"
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/static.h"
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/statistic.h"
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/string_.h"
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/transform.h"
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/utility.h"
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "png.h"
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* ImageMagick differences */
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define first_scene scene
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if PNG_LIBPNG_VER < 10400
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define trans_color  trans_values   /* Changed at libpng-1.4.0beta35 */
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define trans_alpha  trans          /* Changed at libpng-1.4.0beta74 */
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if PNG_LIBPNG_VER > 95
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Optional declarations. Define or undefine them as you like.
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Features under construction.  Define these to work on them.
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_OBJECT_BUFFERS
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_BASI_SUPPORTED
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_BUILD_PALETTE   /* This works as of 5.4.3. */
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SORT_PALETTE    /* This works as of 5.4.0. */
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (((color).red == (target).red) && \
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).green == (target).green) && \
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).blue == (target).blue))
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *png_semaphore = (SemaphoreInfo *) NULL;
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10009)  /* work around libpng-1.0.9 bug */
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  undef PNG_READ_EMPTY_PLTE_SUPPORTED
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  undef PNG_WRITE_EMPTY_PLTE_SUPPORTED
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Maximum valid unsigned long in PNG/MNG chunks is (2^31)-1
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile long
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline long MagickMax(const long x,const long y)
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline long MagickMin(const long x,const long y)
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if PNG_LIBPNG_VER > 95
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   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                       %
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CompressColormapTransFirst compresses an image colormap removing
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  any duplicate and unused color entries and putting the transparent colors
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  first.  Returns MagickTrue on success, MagickFalse on error.
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the CompressColormapTransFirst method is:
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      unsigned int CompressColormapTransFirst(Image *image)
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the address of a structure of type Image.
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType CompressColormapTransFirst(Image *image)
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    remap_needed,
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    k;
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    j,
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors,
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_colors,
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *colormap;
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const IndexPacket
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *indices;
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IndexPacket
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top_used;
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IndexPacket
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *map,
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *opacity;
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *marker,
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_transparency;
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Determine if colormap can be compressed.
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class != PseudoClass || image->colors > 256 ||
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors < 2)
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  marker=(unsigned char *) AcquireQuantumMemory(image->colors,sizeof(*marker));
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (marker == (unsigned char *) NULL)
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  opacity=(IndexPacket *) AcquireQuantumMemory(image->colors,sizeof(*opacity));
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (opacity == (IndexPacket *) NULL)
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Mark colors that are present.
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  number_colors=(long) image->colors;
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    marker[i]=MagickFalse;
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    opacity[i]=OpaqueOpacity;
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  top_used=0;
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (y=0; y < (long) image->rows; y++)
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    indices=GetVirtualIndexQueue(image);
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->matte != MagickFalse)
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (x=0; x < (long) image->columns; x++)
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        marker[(int) indices[x]]=MagickTrue;
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        opacity[(int) indices[x]]=p->opacity;
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (indices[x] > top_used)
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           top_used=indices[x];
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p++;
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (x=0; x < (long) image->columns; x++)
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        marker[(int) indices[x]]=MagickTrue;
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (indices[x] > top_used)
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           top_used=indices[x];
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Mark background color, topmost occurrence if more than one.
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (i=number_colors-1; i; i--)
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsColorEqual(image->colormap+i,&image->background_color))
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          marker[i]=MagickTrue;
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Unmark duplicates.
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors-1; i++)
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=i+1; j < number_colors; j++)
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((opacity[i] == opacity[j]) &&
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (IsColorEqual(image->colormap+i,image->colormap+j)))
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            marker[j]=MagickFalse;
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Count colors that still remain.
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_transparency=MagickFalse;
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  new_number_colors=0;
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        new_number_colors++;
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (opacity[i] != OpaqueOpacity)
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          have_transparency=MagickTrue;
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!have_transparency || (marker[0] &&
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (opacity[0] == (Quantum) TransparentOpacity)))
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      && (new_number_colors == number_colors))
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        No duplicate or unused entries, and transparency-swap not needed.
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  remap_needed=MagickFalse;
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((long) top_used >= new_number_colors)
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     remap_needed=MagickTrue;
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Compress colormap.
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  colormap=(PixelPacket *) AcquireQuantumMemory(image->colors,
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*colormap));
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (colormap == (PixelPacket *) NULL)
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Eliminate unused colormap entries.
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  map=(IndexPacket *) AcquireQuantumMemory((size_t) number_colors,
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*map));
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (map == (IndexPacket *) NULL)
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  k=0;
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    map[i]=(IndexPacket) k;
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=i+1; j < number_colors; j++)
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((opacity[i] == opacity[j]) &&
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (IsColorEqual(image->colormap+i,image->colormap+j)))
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               map[j]=(IndexPacket) k;
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               marker[j]=MagickFalse;
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        k++;
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  j=0;
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        colormap[j]=image->colormap[i];
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        j++;
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (have_transparency && (opacity[0] != (Quantum) TransparentOpacity))
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Move the first transparent color to palette entry 0.
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < number_colors; i++)
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (marker[i] && opacity[i] == (Quantum) TransparentOpacity)
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PixelPacket
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              temp_colormap;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            temp_colormap=colormap[0];
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            colormap[0]=colormap[(int) map[i]];
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            colormap[(long) map[i]]=temp_colormap;
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (j=0; j < number_colors; j++)
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (map[j] == 0)
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                map[j]=map[i];
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else if (map[j] == map[i])
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                map[j]=0;
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            remap_needed=MagickTrue;
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  marker=(unsigned char *) RelinquishMagickMemory(marker);
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (remap_needed)
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ExceptionInfo
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *exception;
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register IndexPacket
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *pixels;
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register PixelPacket
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *q;
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Remap pixels.
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception=(&image->exception);
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=GetAuthenticIndexQueue(image);
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (x=0; x < (long) image->columns; x++)
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          j=(int) pixels[x];
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          pixels[x]=map[j];
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < new_number_colors; i++)
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i]=colormap[i];
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->colors=(unsigned long) new_number_colors;
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  map=(IndexPacket *) RelinquishMagickMemory(map);
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I m a g e I s G r a y                                                     %
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType ImageIsGray(Image *image)
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x,
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < (long) image->colors; i++)
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsGray(image->colormap+i) == MagickFalse)
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (y=0; y < (long) image->rows; y++)
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (x=(long) image->columns-1; x >= 0; x--)
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (IsGray(p) == MagickFalse)
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       p++;
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I m a g e I s M o n o c h r o m e                                         %
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   and is more accurate.                                                     %
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType ImageIsMonochrome(Image *image)
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x,
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < (long) image->colors; i++)
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((IsGray(image->colormap+i) == MagickFalse) ||
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ((image->colormap[i].red != 0) &&
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (image->colormap[i].red != (Quantum) QuantumRange)))
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (y=0; y < (long) image->rows; y++)
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (x=(long) image->columns-1; x >= 0; x--)
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsGray(p) == MagickFalse)
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->opacity != OpaqueOpacity) &&
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (p->opacity != (Quantum) TransparentOpacity))
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* PNG_LIBPNG_VER > 95 */
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 95)
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic size_t WriteBlobMSBULong(Image *image,const unsigned long value)
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void LogPNGChunk(int logging, png_bytep type, size_t length)
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing %c%c%c%c chunk, length: %lu",
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[0],type[1],type[2],type[3],(unsigned long) length);
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* PNG_LIBPNG_VER > 95 */
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if PNG_LIBPNG_VER > 95
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "Expected %lu bytes; found %lu bytes",(unsigned long) length,
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (unsigned long) check);
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) WriteBlob(image,(unsigned long) length,data);
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < (long) a->colors; i++)
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].right=(long) PNG_UINT_31_MAX;
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].bottom=(long) PNG_UINT_31_MAX;
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register long
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box.left=(long) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box.right=(long) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box.top=(long) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box.bottom=(long) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read two longs from CLON, MOVE or PAST chunk
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic long mng_get_long(unsigned char *p)
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGErrorHandler(png_struct *ping,png_const_charp message)
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGWarningHandler(png_struct *ping,png_const_charp message)
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      message);
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_read_raw_profile(Image *image, const ImageInfo *image_info,
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=(png_uint_32) atol(sp);
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < (long) nibbles; i++)
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->page.width=(unsigned long) ((chunk->data[0] << 24) |
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->page.height=(unsigned long) ((chunk->data[4] << 24) |
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pass;
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent_color;
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *indices;
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOnePNGImage()");
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  AcquireSemaphoreInfo(&png_semaphore);
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10007)
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1715ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   PNGErrorHandler,PNGWarningHandler, NULL,
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (setjmp(ping->jmpbuf))
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RelinquishSemaphoreInfo(png_semaphore);
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->exception.severity > exception->severity)
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            InheritException(exception,&image->exception);
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->columns=0;
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->bit_depth < 8)
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE))
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_packing(ping);
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=ping_info->bit_depth;
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->interlace=ping_info->interlace_type != 0 ? PNGInterlace : NoInterlace;
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG width: %lu, height: %lu",
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->width, ping_info->height);
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->color_type, ping_info->bit_depth);
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->compression_type);
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->interlace_type,ping_info->filter_type);
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10008) && defined(PNG_READ_iCCP_SUPPORTED)
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_iCCP)
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        info,
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rendering_intent=(RenderingIntent)
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->global_srgb_intent+1);
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->rendering_intent=(RenderingIntent) (intent+1);
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Reading PNG sRGB chunk: rendering_intent: %d",intent+1);
18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->have_global_gama)
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       image->gamma=mng_info->global_gamma;
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_chrm != MagickFalse)
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->chromaticity=mng_info->global_chrm;
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_cHRM)
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->rendering_intent)
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->gamma=0.45455f;
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.red_primary.x=0.6400f;
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.red_primary.y=0.3300f;
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.green_primary.x=0.3000f;
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.green_primary.y=0.6000f;
19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.blue_primary.x=0.1500f;
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.blue_primary.y=0.0600f;
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.white_point.x=0.3127f;
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.white_point.y=0.3290f;
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_global_gama != MagickFalse) || image->rendering_intent)
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ping_info->valid|=PNG_INFO_gAMA;
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_global_chrm != MagickFalse) || image->rendering_intent)
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ping_info->valid|=PNG_INFO_cHRM;
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_oFFs)
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=png_get_x_offset_pixels(ping, ping_info);
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=png_get_y_offset_pixels(ping, ping_info);
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Reading PNG oFFs chunk: x: %ld, y: %ld.",image->page.x,
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y);
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_pHYs)
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          &unit_type);
19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->x_resolution=(float) x_resolution;
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->y_resolution=(float) y_resolution;
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG pHYs chunk: xres: %lu, yres: %lu, units: %d.",
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution, y_resolution, unit_type);
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->have_global_phys)
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(float) mng_info->global_x_pixels_per_unit;
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(float) mng_info->global_y_pixels_per_unit;
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_phys_unit_type == PNG_RESOLUTION_METER)
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->units=PixelsPerCentimeterResolution;
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->x_resolution=(double)
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit/100.0;
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->y_resolution=(double)
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit/100.0;
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->valid|=PNG_INFO_pHYs;
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_PLTE)
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE))
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if ((ping_info->valid & PNG_INFO_tRNS) == 0)
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   ping_info->valid & PNG_INFO_bKGD)
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=ping_info->background.index;
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_bkgd && !(ping_info->valid & PNG_INFO_bKGD))
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_bKGD)
20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->bit_depth <= MAGICKCORE_QUANTUM_DEPTH)
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=ping_info->background.red;
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=ping_info->background.green;
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=ping_info->background.blue;
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ScaleShortToQuantum(ping_info->background.red);
20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ScaleShortToQuantum(ping_info->background.green);
20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ScaleShortToQuantum(ping_info->background.blue);
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.red=0;
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.green=0;
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.blue=0;
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.opacity=0;
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_tRNS)
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      max_sample = (1 << ping_info->bit_depth) - 1;
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((ping_info->color_type == PNG_COLOR_TYPE_GRAY &&
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (int)ping_info->trans_color.gray > max_sample) ||
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (ping_info->color_type == PNG_COLOR_TYPE_RGB &&
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ((int)ping_info->trans_color.red > max_sample ||
21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (int)ping_info->trans_color.green > max_sample ||
21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (int)ping_info->trans_color.blue > max_sample)))
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
21113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10007)
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_alpha=(unsigned char *) RelinquishMagickMemory(
21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->trans_alpha);
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->valid&=(~PNG_INFO_tRNS);
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transparent_color.red= (Quantum)(ping_info->trans_color.red);
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transparent_color.green= (Quantum) (ping_info->trans_color.green);
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transparent_color.blue= (Quantum) (ping_info->trans_color.blue);
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transparent_color.opacity= (Quantum) (ping_info->trans_color.gray);
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->bit_depth < 8)
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  transparent_color.opacity=(Quantum) (((
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ping_info->trans_color.gray)*255)/max_sample);
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
21373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (!(ping_info->valid & PNG_INFO_sBIT))
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
21523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.right=(long) ping_info->width;
21533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.bottom=(long) ping_info->height;
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=ping_info->width;
21583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=ping_info->height;
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
21603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
21613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
21633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=ping_info->width;
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=ping_info->height;
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE) ||
21703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
21713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY))
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=1UL << ping_info->bit_depth;
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colors=(unsigned long) number_colors;
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=0; i < (long) image->colors; i++)
22153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned long
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          scale=(QuantumRange/((1UL << ping_info->bit_depth)-1));
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=0; i < (long) image->colors; i++)
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_info->number_scenes != 0) && (mng_info->scenes_found > (long)
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image_info->first_scene+image_info->number_scenes)))
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Skipping PNG image data for scene %ld",
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RelinquishSemaphoreInfo(png_semaphore);
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->rowbytes*sizeof(*png_pixels));
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(ping_info->rowbytes,
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sizeof(*png_pixels));
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (setjmp(ping->jmpbuf))
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RelinquishSemaphoreInfo(png_semaphore);
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->exception.severity > exception->severity)
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            InheritException(exception,&image->exception);
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->columns=0;
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2299ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
2300ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2301ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert image to DirectClass pixel packets.
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        depth;
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      depth=(long) ping_info->bit_depth;
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=(((int) ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (ping_info->valid & PNG_INFO_tRNS)) ? MagickTrue : MagickFalse;
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=ping_info->rowbytes*y;
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
2325abc8f408bb48da2d73cb760d61f16063695081d2cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (depth == 16)
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register Quantum
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *p,
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r;
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            r=png_pixels+row_offset;
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=r;
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
23393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=(long) image->columns-1; x >= 0; x--)
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if ((ping_info->valid & PNG_INFO_tRNS) &&
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (((*(p-2) << 8)|*(p-1)) == transparent_color.opacity))
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
23493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
23503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_RGB)
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->valid & PNG_INFO_tRNS)
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=(long) image->columns-1; x >= 0; x--)
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if ((((*(p-6) << 8)|*(p-5)) == transparent_color.red) &&
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-4) << 8)|*(p-3)) == transparent_color.green) &&
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-2) << 8)|*(p-1)) == transparent_color.blue))
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=(long) image->columns-1; x >= 0; x--)
23763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=OpaqueOpacity;
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=(long) (4*image->columns); x != 0; x--)
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=(long) (2*image->columns); x != 0; x--)
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
23983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (depth == 8 && ping_info->color_type == PNG_COLOR_TYPE_GRAY)
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset);
24023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ping_info->color_type == PNG_COLOR_TYPE_GRAY ||
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GrayAlphaQuantum,png_pixels+row_offset);
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if (depth == 8 && ping_info->color_type == PNG_COLOR_TYPE_RGB)
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             RGBQuantum,png_pixels+row_offset);
24123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if (ping_info->color_type == PNG_COLOR_TYPE_RGB ||
24133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RGBAQuantum,png_pixels+row_offset);
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if (ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
24203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              IndexQuantum,png_pixels+row_offset);
24223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
24233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY)
24243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset,exception);
24263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if ((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayAlphaQuantum,png_pixels+row_offset,exception);
24293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if ((int) ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBAQuantum,png_pixels+row_offset,exception);
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexQuantum,png_pixels+row_offset,exception);
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBQuantum,png_pixels+row_offset,exception);
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->previous == (Image *) NULL)
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=ping_info->rowbytes*y;
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        indices=GetAuthenticIndexQueue(image);
24783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=png_pixels+row_offset;
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
24803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        switch (ping_info->bit_depth)
24813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
24833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
24843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register long
24853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (x=(long) image->columns-7; x > 0; x-=8)
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
24913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (bit=7; bit >= (long) (8-(image->columns % 8)); bit--)
24963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
24983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
24993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
25013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (x=(long) image->columns-3; x > 0; x-=4)
25033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
25053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
25063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
25073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
25103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=3; i >= (long) (4-(image->columns % 4)); i--)
25123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
25133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
25173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (x=(long) image->columns-1; x > 0; x-=2)
25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
25223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ping_info->color_type == 4)
25303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=(long) image->columns-1; x >= 0; x--)
25313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
25423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=(long) image->columns-1; x >= 0; x--)
25433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
25473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (x=(long) image->columns-1; x >= 0; x--)
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              unsigned long
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
25553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
25573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
25583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
25623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->color_type == 4)
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              unsigned long
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
25773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
25823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->color_type == 4)
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity*=65537L;
25863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-q->opacity);
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->color_type == 4)
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
26053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (x=0; x < (long) image->columns; x++)
26123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          indices[x]=(*r++);
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->previous == (Image *) NULL)
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2624b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2625b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SyncImage(image);
26283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
26293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (long) image_info->first_scene && image->delay != 0)
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RelinquishSemaphoreInfo(png_semaphore);
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_tRNS)
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->storage_class=storage_class;
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        indices=GetAuthenticIndexQueue(image);
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (storage_class == PseudoClass)
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexPacket
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexpacket;
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
26693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) image->columns; x++)
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                indexpacket=indices[x];
26723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (indexpacket < ping_info->num_trans)
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=ScaleCharToQuantum((unsigned char)
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (255-ping_info->trans_alpha[(long) indexpacket]));
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=OpaqueOpacity;
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) image->columns; x++)
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                indexpacket=indices[x];
26833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->red=image->colormap[(long) indexpacket].red;
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->green=q->red;
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->blue=q->red;
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (q->red == transparent_color.opacity)
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) TransparentOpacity;
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=OpaqueOpacity;
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (x=(long) image->columns-1; x >= 0; x--)
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ScaleQuantumToChar(q->red) == transparent_color.red &&
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ScaleQuantumToChar(q->green) == transparent_color.green &&
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ScaleQuantumToChar(q->blue) == transparent_color.blue)
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               q->opacity=(Quantum) TransparentOpacity;
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q->opacity=OpaqueOpacity;
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q++;
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->depth > 8)
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->depth=8;
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (i=0; i < (long) num_text; i++)
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_read_raw_profile(image,image_info,text,(int) i);
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
27353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
27513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireMagickMemory(sizeof(MngBuffer));
27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
27743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
27763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_uint_32
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            width,
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            height;
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            bit_depth,
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            color_type,
27873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            interlace_method,
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            compression_method,
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            filter_method;
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
27923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
27933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
27943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
27953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
27963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
27973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
27983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
27993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
28003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
28023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_get_IHDR(ping,ping_info,&width,&height,&bit_depth,&color_type,
28033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &interlace_method,&compression_method,&filter_method);
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (width > 250000L || height > 250000L)
28053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
28063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->width=width;
28073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->height=height;
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->color_type=color_type;
28093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->sample_depth=bit_depth;
28103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->interlace_method=interlace_method;
28113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->compression_method=compression_method;
28123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->filter_method=filter_method;
28133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->valid & PNG_INFO_PLTE)
28143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
28153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
28163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
28173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
28203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
28223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
28233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
28243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
28253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
28263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
28273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
28293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
28333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
28383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
28403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
28423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
28433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RelinquishSemaphoreInfo(png_semaphore);
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
28473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
28573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
28583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
28593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
28643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
28653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
28673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
28683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
28703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
28713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
28723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
28743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
28753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
28783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
28793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
28803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
28823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
28833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
28843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
28853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
28863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
28883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
28913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
28953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
28973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
28983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
29003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
29043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
29273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
29463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
29513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOneJNGImage()");
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
30753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
30823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
30833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
30853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
30903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
30983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Reading JNG chunk type %c%c%c%c, length: %lu",
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0],type[1],type[2],type[3],length);
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (i=0; i < (long) length; i++)
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_width=(unsigned long) ((p[0] << 24) | (p[1] << 16) |
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_height=(unsigned long) ((p[4] << 24) | (p[5] << 16) |
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_width:      %16lu",jng_width);
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_width:      %16lu",jng_height);
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireMagickMemory(sizeof(ImageInfo));
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_IHDR,13L);
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk to color_image->blob
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy IDAT header and chunk data to alpha_image->blob
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,(unsigned long) length);
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            LogPNGChunk((int) logging,mng_IDAT,length);
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk data to alpha_image->blob
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->gamma=((float) mng_get_long(p))*0.00001;
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rendering_intent=(RenderingIntent) (p[0]+1);
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_get_long(p);
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_get_long(&p[4]);
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->x_resolution=(double) mng_get_long(p);
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->y_resolution=(double) mng_get_long(&p[4]);
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* To do. */
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (y=0; y < (long) image->rows; y++)
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_IEND,0L);
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           for (y=0; y < (long) image->rows; y++)
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               for (x=(long) image->columns; x != 0; x--,q++,s++)
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               for (x=(long) image->columns; x != 0; x--,q++,s++)
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
35463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read the JNG image.
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.width=jng_width;
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.height=jng_height;
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.x=mng_info->x_off[mng_info->object_id];
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify JNG signature.
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile long
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned long
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Set image_info->type=OptimizeType (new in version 5.4.0) to get the
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    following optimizations:
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  16-bit depth is reduced to 8 if all pixels contain samples whose
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       high byte and low byte are identical.
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Opaque matte channel is removed.
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  If matte channel is present but only one transparent color is
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       present, RGB+tRNS is written instead of RGBA
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Grayscale images are reduced to 1, 2, or 4 bit depth if
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       this can be done without loss.
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Palette is sorted to remove unused entries and to put a
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       transparent color first, if PNG_SORT_PALETTE is also defined.
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->optimize=image_info->type == OptimizeType;
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Verify MNG signature.
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize some nonzero members of the MngInfo structure.
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->object_clip[i].right=(long) PNG_UINT_31_MAX;
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->object_clip[i].bottom=(long) PNG_UINT_31_MAX;
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Reading MNG chunk type %c%c%c%c, length: %lu",
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           type[0],type[1],type[2],type[3],length);
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < (long) length; i++)
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->mng_width=(unsigned long) ((p[0] << 24) | (p[1] << 16) |
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->mng_height=(unsigned long) ((p[4] << 24) | (p[5] << 16) |
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  MNG width: %lu",mng_info->mng_width);
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  MNG height: %lu",mng_info->mng_height);
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ticks_per_second=(unsigned long) mng_get_long(p);
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                simplicity=(unsigned long) mng_get_long(p);
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu+0+0",
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->mng_width,mng_info->mng_height);
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.right=(long) mng_info->mng_width;
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.bottom=(long) mng_info->mng_height;
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    final_delay=%ld",final_delay);
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    image->iterations=%ld",image->iterations);
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->x_off[object_id]=(long) ((p[4] << 24) | (p[5] << 16) |
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->y_off[object_id]=(long) ((p[8] << 24) | (p[9] << 16) |
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[10] << 8) | p[11]);
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "  x_off[%d]: %lu",object_id,mng_info->x_off[object_id]);
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "  y_off[%d]: %lu",object_id,mng_info->y_off[object_id]);
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global PLTE.
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) (length/3); i++)
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_plte_length=length/3;
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < (long) length; i++)
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->global_trns_length=length;
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                long
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                igamma=mng_get_long(p);
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global cHRM
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_get_long(&p[12]);
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_get_long(&p[16]);
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_get_long(&p[20]);
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_get_long(&p[24]);
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_get_long(&p[28]);
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_srgb_intent=(RenderingIntent) (p[0]+1);
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* To do. */
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Note the delay and frame clipping boundaries.
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                while (*p && ((p-chunk) < (long) length))
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((p-chunk) < (long) (length-4))
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        frame_delay=(1UL*image->ticks_per_second*
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            (mng_get_long(p))/mng_info->ticks_per_second);
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "    Framing_delay=%ld",frame_delay);
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        frame_timeout=(1UL*image->ticks_per_second*
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            (mng_get_long(p))/mng_info->ticks_per_second);
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "    Framing_timeout=%ld",frame_timeout);
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "    Frame_clipping: L=%ld R=%ld T=%ld B=%ld",
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              fb.left, fb.right,fb.top,fb.bottom);
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            subframe_width=(unsigned long) (mng_info->clip.right
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            subframe_height=(unsigned long) (mng_info->clip.bottom
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "   subframe_width=%lu, subframe_height=%lu",
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                subframe_width, subframe_height);
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Inserted background layer, L=%ld, R=%ld, T=%ld, B=%ld",
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->clip.left,mng_info->clip.right,
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->clip.top,mng_info->clip.bottom);
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read DISC or SEEK.
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register long
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (j=0; j < (long) length; j+=2)
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned long
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              read MOVE
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(long) first_object; i <= (long) last_object; i++)
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            long loop_iters=1;
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Record starting point.
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_iters=mng_get_long(&chunk[1]);
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  LOOP level %ld  has %ld iterations ",loop_level,loop_iters);
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "  ENDL: LOOP level %ld  has %ld remaining iterations ",
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level,mng_info->loop_count[loop_level]);
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (unsigned long) mng_get_long(p);
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (unsigned long) mng_get_long(&p[4]);
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_width=(unsigned long) ((p[0] << 24) | (p[1] << 16) |
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_height=(unsigned long) ((p[4] << 24) | (p[5] << 16) |
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_width=(unsigned  long) mng_get_long(p);
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_height=(unsigned  long) mng_get_long(&p[4]);
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->clip.right < (long) mng_info->mng_width) ||
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->clip.bottom < (long) mng_info->mng_height))
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Make a background rectangle.
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Inserted transparent background layer, W=%lud, H=%lud",
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->mng_width,mng_info->mng_height);
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Inserted background layer, L=%ld, R=%ld, T=%ld, B=%ld",
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->clip.left,mng_info->clip.right,
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->clip.top,mng_info->clip.bottom);
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        offset=SeekBlob(image,-((long) length+12),SEEK_CUR);
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += (image->columns-2)*(mng_info->magn_mx);
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=image->columns;
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += (image->columns-3)*(mng_info->magn_mx-1);
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += (image->rows-2)*(mng_info->magn_my);
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=image->rows;
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += (image->rows-3)*(mng_info->magn_my-1);
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                long
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register long
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     for (y=0; y < (long) image->rows; y++)
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       for (x=(long) image->columns-1; x >= 0; x--)
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Magnify the rows to %lu",large_image->rows);
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                m=(long) mng_info->magn_mt;
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (y=0; y < (long) image->rows; y++)
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=(long) mng_info->magn_mt;
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else if (magn_methy > 1 && y == (long) image->rows-2)
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=(long) mng_info->magn_mb;
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else if (magn_methy <= 1 && y == (long) image->rows-1)
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=(long) mng_info->magn_mb;
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else if (magn_methy > 1 && y == (long) image->rows-1)
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=(long) mng_info->magn_my;
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y < (long) image->rows-1)
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    assert(yy < (long) large_image->rows);
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (x=(long) image->columns-1; x >= 0; x--)
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /* TO DO: get color as function of indices[x] */
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) (((long) (2*i*((*n).red
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m))/((long) (m*2))
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) (((long) (2*i*((*n).green
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)+m))/((long) (m*2))
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) (((long) (2*i*((*n).blue
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m))/((long) (m*2))
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) (((long)
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 /((long) (m*2))+(*pixels).opacity);
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) (((long) (2*i*((*n).opacity
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))/((long) (m*2))
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Magnify the columns to %lu",image->columns);
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (y=0; y < (long) image->rows; y++)
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (x=(long) (image->columns-length);
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    x < (long) image->columns; x++)
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (x == (long) (image->columns-length))
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=(long) mng_info->magn_ml;
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else if (magn_methx > 1 && x == (long) image->columns-2)
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=(long) mng_info->magn_mr;
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else if (magn_methx <= 1 && x == (long) image->columns-1)
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=(long) mng_info->magn_mr;
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else if (magn_methx > 1 && x == (long) image->columns-1)
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=(long) mng_info->magn_mx;
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 /((long) (m*2))+(*pixels).red);
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +m)/((long) (m*2))+(*pixels).green);
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 /((long) (m*2))+(*pixels).blue);
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   -(*pixels).opacity)+m)/((long) (m*2))
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m) /((long) (m*2))
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   for (y=0; y < (long) image->rows; y++)
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     for (x=(long) image->columns-1; x >= 0; x--)
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.width=(unsigned long) (crop_box.right-crop_box.left);
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.height=(unsigned long) (crop_box.bottom-crop_box.top);
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)  /* TO DO: treat Q:32 */
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* Determine if bit depth can be reduced from 16 to 8.
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * Note that the method GetImageDepth doesn't check background
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * and doesn't handle PseudoClass specially.  Also it uses
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * multiplication and division by 257 instead of shifting, so
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * might be slower.
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->optimize && image->depth == 16)
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        int
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ok_to_reduce;
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        const PixelPacket
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *p;
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ok_to_reduce=(((((unsigned long) image->background_color.red >> 8) &
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     0xff)
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          == ((unsigned long) image->background_color.red & 0xff)) &&
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ((((unsigned long) image->background_color.green >> 8) & 0xff)
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          == ((unsigned long) image->background_color.green & 0xff)) &&
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ((((unsigned long) image->background_color.blue >> 8) & 0xff)
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          == ((unsigned long) image->background_color.blue & 0xff)));
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce && image->storage_class == PseudoClass)
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int indx;
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (indx=0; indx < (long) image->colors; indx++)
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ok_to_reduce=(((((unsigned long) image->colormap[indx].red >>
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    8) & 0xff)
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  == ((unsigned long) image->colormap[indx].red & 0xff)) &&
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((((unsigned long) image->colormap[indx].green >> 8) & 0xff)
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  == ((unsigned long) image->colormap[indx].green & 0xff)) &&
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((((unsigned long) image->colormap[indx].blue >> 8) & 0xff)
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  == ((unsigned long) image->colormap[indx].blue & 0xff)));
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == MagickFalse)
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((ok_to_reduce != MagickFalse) &&
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->storage_class != PseudoClass))
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            long
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              y;
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register long
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              x;
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=0; y < (long) image->rows; y++)
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p == (const PixelPacket *) NULL)
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=(long) image->columns-1; x >= 0; x--)
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ok_to_reduce=((
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (((unsigned long) p->red >> 8) & 0xff) ==
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((unsigned long) p->red & 0xff)) &&
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((((unsigned long) p->green >> 8) & 0xff) ==
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((unsigned long) p->green & 0xff)) &&
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((((unsigned long) p->blue >> 8) & 0xff) ==
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((unsigned long) p->blue & 0xff)) &&
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (((!image->matte ||
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (((unsigned long) p->opacity >> 8) & 0xff) ==
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((unsigned long) p->opacity & 0xff)))));
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == 0)
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (x != 0)
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce)
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->depth=8;
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Reducing PNG bit depth to 8 without loss of info");
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (long) (image_info->first_scene+image_info->number_scenes))
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  image->delay=%lu, final_delay=%lu",image->delay,final_delay);
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    scene 0 delay=%lu",image->delay);
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    scene %d delay=%lu",++scene,image->delay);
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned long
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    scene 0 delay=%lu dispose=%d",image->delay,(int) image->dispose);
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=GetNextImageInList(image);
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    scene %d delay=%lu dispose=%d",++scene,
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay,(int) image->dispose);
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* PNG_LIBPNG_VER > 95 */
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* PNG_LIBPNG_VER > 95 */
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      unsigned long RegisterPNGImage(void)
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport unsigned long RegisterPNGImage(void)
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10005)
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  AcquireSemaphoreInfo(&png_semaphore);
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RelinquishSemaphoreInfo(png_semaphore);
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  DestroySemaphoreInfo(&png_semaphore);
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if PNG_LIBPNG_VER > 95
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    some GIF animations don't convert properly)
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 99 && PNG_LIBPNG_VER < 10007)
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* This function became available in libpng version 1.0.6g. */
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_ptr->zbuf)
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_free(png_ptr, png_ptr->zbuf); png_ptr->zbuf=NULL;
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_ptr->zbuf_size=(png_size_t) size;
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_ptr->zbuf=(png_bytep) png_malloc(png_ptr, size);
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_ptr->zbuf == 0)
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_error(png_ptr,"Unable to allocate zbuf");
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10005)
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   register long
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER <= 10005)
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) printf("Not ");
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   image_info=image_info;
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   ping=ping;
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   ping_info=ping_info;
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   profile_type=profile_type;
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   profile_description=profile_description;
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   profile_data=profile_data;
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   length=length;
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) printf("writing raw profile: type=%s, length=%lu\n",
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (char *) profile_type, length);
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10005)
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (png_size_t) (dp-text[0].text),"%8lu ",length);
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   for (i=0; i < (long) length; i++)
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType png_write_chunk_from_profile(Image *image,
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const char *string, int logging)
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; ){
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png_profile;
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (LocaleNCompare(name,string,11) == 0) {
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Found %s profile",name);
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=CloneStringInfo(profile);
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data=GetStringInfoDatum(png_profile),
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       length=(png_uint_32) GetStringInfoLength(png_profile);
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[4]=data[3];
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[3]=data[2];
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[2]=data[1];
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[1]=data[0];
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,length-5);  /* data length */
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,length-1,data+1);
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=DestroyStringInfo(png_profile);
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one PNG image */
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_matte,
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pass;
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     palette;
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *indices;
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte;
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned long
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_colors,
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_depth;
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_bit_depth,
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOnePNGImage()");
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  AcquireSemaphoreInfo(&png_semaphore);
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6279ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_colors=image->colors;
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=image->depth;
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_matte=image->matte;
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->IsPalette=image->storage_class == PseudoClass &&
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_colors <= 256;
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->optimize=image_info->type == OptimizeType;
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (setjmp(ping->jmpbuf))
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RelinquishSemaphoreInfo(png_semaphore);
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info->width=image->columns;
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info->height=image->rows;
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    width=%lu",ping_info->width);
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    height=%lu",ping_info->height);
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_matte=%u",image->matte);
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_depth=%lu",image->depth);
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    requested PNG image_depth=%lu",image->depth);
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info->bit_depth=(png_byte) save_image_depth;
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution);
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution);
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_UNKNOWN;
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) image->x_resolution;
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) image->y_resolution;
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_pHYs(ping,ping_info,x_resolution,y_resolution,unit_type);
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up pHYs chunk");
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x || image->page.y)
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (png_int_32) image->page.y, 0);
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up oFFs chunk");
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && (!mng_info->adjoin || !mng_info->equal_backgrounds))
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_color_16
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        background;
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_depth < MAGICKCORE_QUANTUM_DEPTH)
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned long
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             maxval;
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          maxval=(1UL << image_depth)-1;
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.red=(png_uint_16)
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.red));
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.green=(png_uint_16)
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.green));
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.blue=(png_uint_16)
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.blue));
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.gray=(png_uint_16)
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*PixelIntensity(&image->background_color)));
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.red=image->background_color.red;
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.green=image->background_color.green;
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.blue=image->background_color.blue;
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.gray=
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_16) PixelIntensity(&image->background_color);
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      background.index=(png_byte) background.gray;
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Setting up bKGd chunk");
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_bKGD(ping,ping_info,&background);
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->bit_depth=8;
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_depth=ping_info->bit_depth;
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: make this a function cause it's used twice, except
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             for reducing the sample depth from 8. */
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          QuantizeInfo
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantize_info;
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned long
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             number_colors,
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             save_number_colors;
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          number_colors=image_colors;
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image->storage_class == DirectClass) || (number_colors > 256))
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GetQuantizeInfo(&quantize_info);
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.dither=IsPaletteImage(image,&image->exception) ==
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MagickFalse ? MagickTrue : MagickFalse;
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.number_colors= (matte != MagickFalse ? 255UL :
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                256UL);
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) QuantizeImage(&quantize_info,image);
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors=image_colors;
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) SyncImage(image);
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    Colors quantized to %ld",number_colors);
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->valid|=PNG_INFO_tRNS;
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Set image palette.
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->valid|=PNG_INFO_PLTE;
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          save_number_colors=image_colors;
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (CompressColormapTransFirst(image) == MagickFalse)
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          number_colors=image_colors;
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_colors=save_number_colors;
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_color *) AcquireQuantumMemory(257,
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*palette));
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (palette == (png_color *) NULL)
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up PLTE chunk");
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=0; i < (long) number_colors; i++)
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %3ld (%3d,%3d,%3d)",
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %5ld (%5d,%5d,%5d)",
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                i,palette[i].red,palette[i].green,palette[i].blue);
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors++;
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].red=ScaleQuantumToChar((Quantum) QuantumRange);
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].green=ScaleQuantumToChar((Quantum) QuantumRange);
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].blue=ScaleQuantumToChar((Quantum) QuantumRange);
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_PLTE(ping,ping_info,palette,(int) number_colors);
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10008)
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_colorp) RelinquishMagickMemory(palette);
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_depth=ping_info->bit_depth;
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->num_trans=0;
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_alpha=(unsigned char *) AcquireQuantumMemory(
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors,sizeof(*ping_info->trans_alpha));
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->trans == (unsigned char *) NULL)
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowWriterException(ResourceLimitError,
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < (long) number_colors; i++)
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 ping_info->trans_alpha[i]=255;
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (y=0; y < (long) image->rows; y++)
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register const PixelPacket
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *p;
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetAuthenticPixels(image,0,y,image->columns,1,exception);
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (PixelPacket *) NULL)
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                indices=GetAuthenticIndexQueue(image);
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=0; x < (long) image->columns; x++)
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      indices[x]=(IndexPacket) (number_colors-1);
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ping_info->trans_alpha[(long) indices[x]]=(png_byte) (255-
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        ScaleQuantumToChar(p->opacity));
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (SyncAuthenticPixels(image,exception) == MagickFalse)
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < (long) number_colors; i++)
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ping_info->trans_alpha[i] != 255)
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->num_trans=(unsigned short) (i+1);
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->num_trans == 0)
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->valid&=(~PNG_INFO_tRNS);
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (!(ping_info->valid & PNG_INFO_tRNS))
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->num_trans=0;
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->num_trans == 0)
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->trans_alpha=(unsigned char *)
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  RelinquishMagickMemory(ping_info->trans_alpha);
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Identify which colormap entry is the background color.
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=0; i < (long) MagickMax(1L*number_colors-1L,1L); i++)
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (IsPNGColorEqual(ping_info->background,image->colormap[i]))
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->background.index=(png_byte) i;
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_matte != MagickFalse)
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: reduce to binary transparency */
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->color_type=(png_byte) PNG_COLOR_TYPE_RGB;
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_depth=ping_info->bit_depth;
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->color_type=(png_byte) mng_info->write_png_colortype-1;
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "Selecting PNG colortype");
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->color_type=(png_byte) ((matte == MagickTrue)?
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorType)
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type=(png_byte) PNG_COLOR_TYPE_RGB;
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorMatteType)
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == GrayscaleType) &&
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_matte == MagickFalse && ImageIsGray(image))
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_info->type == GrayscaleMatteType) &&
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte == MagickTrue && ImageIsGray(image))
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         "Selected PNG colortype=%d",ping_info->color_type);
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->bit_depth < 8)
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ping_info->color_type == PNG_COLOR_TYPE_RGB ||
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ping_info->color_type == PNG_COLOR_TYPE_RGBA)
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ping_info->bit_depth=8;
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->matte == MagickFalse && image->colors < 256)
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ImageIsMonochrome(image))
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->bit_depth=1;
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (ping_info->bit_depth < mng_info->write_png_depth)
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ping_info->bit_depth = mng_info->write_png_depth;
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ping_info->bit_depth=1;
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           while ((int) (1 << ping_info->bit_depth) < (long) image_colors)
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ping_info->bit_depth <<= 1;
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Number of colors: %lu",image_colors);
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Tentative PNG bit depth: %d",ping_info->bit_depth);
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (mng_info->write_png_depth)
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               old_bit_depth=ping_info->bit_depth;
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               if (ping_info->bit_depth < mng_info->write_png_depth)
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 {
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   ping_info->bit_depth = mng_info->write_png_depth;
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if (ping_info->bit_depth > 8)
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ping_info->bit_depth = 8;
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if (ping_info->bit_depth != old_bit_depth)
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (logging != MagickFalse)
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                           "    Colors increased to %ld",image_colors);
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 }
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=ping_info->bit_depth;
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Tentative PNG color type: %d",ping_info->color_type);
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_info->type: %d",image_info->type);
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_depth: %lu",image_depth);
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    ping_info->bit_depth: %d",ping_info->bit_depth);
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (matte && (mng_info->optimize || mng_info->IsPalette))
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=GetVirtualPixels(image,0,0,image->columns,1,&image->exception);
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (x=(long) image->columns-1; x >= 0; x--)
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (IsGray(p) == MagickFalse)
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Determine if there is any transparent color.
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (x=(long) image->columns-1; x >= 0; x--)
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p->opacity != OpaqueOpacity)
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (x != 0)
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((y == (long) image->rows) && (x == (long) image->columns))
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            No transparent pixels are present.  Change 4 or 6 to 0 or 2,
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            and do not set the PNG_INFO_tRNS flag in ping_info->valid.
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_matte=MagickFalse;
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->color_type&=0x03;
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned int
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mask;
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mask=0xffff;
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->bit_depth == 8)
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x00ff;
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->bit_depth == 4)
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x000f;
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->bit_depth == 2)
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0003;
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->bit_depth == 1)
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0001;
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->valid|=PNG_INFO_tRNS;
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_color.red=(png_uint_16)
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(p->red) & mask);
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_color.green=(png_uint_16)
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(p->green) & mask);
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_color.blue=(png_uint_16)
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(p->blue) & mask);
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_color.gray=(png_uint_16)
67873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(PixelIntensityToQuantum(p)) & mask);
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_color.index=(png_byte)
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToChar((Quantum) (QuantumRange-p->opacity)));
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->valid & PNG_INFO_tRNS)
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine if there is one and only one transparent color
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            and if so if it is fully transparent.
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (y=0; y < (long) image->rows; y++)
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               &image->exception);
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            x=0;
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (x=(long) image->columns-1; x >= 0; x--)
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p->opacity != OpaqueOpacity)
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (IsPNGColorEqual(ping_info->trans_color,*p) == 0)
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for multiple
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent colors.  */
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != (Quantum) TransparentOpacity)
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                semitransparency. */
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               else
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (IsPNGColorEqual(ping_info->trans_color,*p))
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break; /* Can't use RGB + tRNS when another pixel
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                having the same RGB samples is
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent. */
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (x != 0)
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
68303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (x != 0)
68323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->valid&=(~PNG_INFO_tRNS);
68333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->valid & PNG_INFO_tRNS)
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_color.red&=0xff;
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_color.green&=0xff;
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_color.blue&=0xff;
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_color.gray&=0xff;
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (ping_info->valid & PNG_INFO_tRNS)
68483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((mng_info->optimize || mng_info->IsPalette) &&
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageIsGray(image) && (!image_matte || image_depth >= 8))
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->color_type=PNG_COLOR_TYPE_GRAY;
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_color.gray*=0x0101;
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_colors=1 << image_depth;
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->bit_depth=16;
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->bit_depth=8;
68703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
68743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ping_info->bit_depth=1;
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    while ((int) (1 << ping_info->bit_depth)
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        < (long) image_colors)
68773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ping_info->bit_depth <<= 1;
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (mng_info->optimize && ping_info->color_type ==
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) image_colors; i++)
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   ping_info->bit_depth=1;
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
69083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   ping_info->bit_depth=2;
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   ping_info->bit_depth=4;
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=ping_info->bit_depth;
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned long
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               number_colors;
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors=image_colors;
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               ping_info->valid|=PNG_INFO_tRNS;
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
69273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
69293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->valid|=PNG_INFO_PLTE;
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->have_write_global_plte && !matte)
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 png_set_PLTE(ping,ping_info,NULL,0);
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (logging)
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "  Setting up empty PLTE chunk");
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned long
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   save_number_colors;
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->optimize)
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    save_number_colors=image_colors;
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (CompressColormapTransFirst(image) == MagickFalse)
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       ThrowWriterException(ResourceLimitError,
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                            "MemoryAllocationFailed");
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    number_colors=image_colors;
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image_colors=save_number_colors;
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_color *) AcquireQuantumMemory(257,
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  sizeof(*palette));
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (palette == (png_color *) NULL)
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ThrowWriterException(ResourceLimitError,
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MemoryAllocationFailed");
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) number_colors; i++)
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging)
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Setting up PLTE chunk");
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_set_PLTE(ping,ping_info,palette,(int) number_colors);
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10008)
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_colorp) RelinquishMagickMemory(palette);
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (!mng_info->write_png_depth)
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->bit_depth=1;
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                while ((1UL << ping_info->bit_depth) < number_colors)
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->bit_depth <<= 1;
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->num_trans=0;
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
69853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const PixelPacket
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *p;
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[256];
69913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const IndexPacket
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *packet_indices;
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < (long) number_colors; i++)
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[i]=256;
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (y=0; y < (long) image->rows; y++)
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetVirtualPixels(image,0,y,image->columns,1,exception);
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (const PixelPacket *) NULL)
70063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                packet_indices=GetVirtualIndexQueue(image);
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=0; x < (long) image->columns; x++)
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
70103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
70123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      IndexPacket
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        packet_index;
70143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      packet_index=packet_indices[x];
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      assert((unsigned long) packet_index < number_colors);
70173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (trans[(long) packet_index] != 256)
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (trans[(long) packet_index] != (png_byte) (255-
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             ScaleQuantumToChar(p->opacity)))
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              ping_info->color_type=(png_byte)
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                PNG_COLOR_TYPE_RGB_ALPHA;
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              break;
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      trans[(long) packet_index]=(png_byte) (255-
70283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        ScaleQuantumToChar(p->opacity));
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
70313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((int) ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->num_trans=0;
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->valid&=(~PNG_INFO_tRNS);
70363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->valid&=(~PNG_INFO_PLTE);
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->IsPalette=MagickFalse;
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) SyncImage(image);
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (logging)
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent, GetMagickModule(),
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "    Cannot write image as indexed PNG, writing RGBA.");
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if ((ping_info->valid & PNG_INFO_tRNS))
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) number_colors; i++)
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] == 256)
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    trans[i]=255;
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] != 255)
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ping_info->num_trans=(unsigned short) (i+1);
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->num_trans == 0)
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->valid&=(~PNG_INFO_tRNS);
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (!(ping_info->valid & PNG_INFO_tRNS))
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->num_trans=0;
70593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->num_trans != 0)
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->trans_alpha=(unsigned char *) AcquireQuantumMemory(
70623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  number_colors,sizeof(*ping_info->trans_alpha));
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ping_info->trans_alpha == (unsigned char *) NULL)
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ThrowWriterException(ResourceLimitError,
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MemoryAllocationFailed");
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) number_colors; i++)
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ping_info->trans_alpha[i]=(png_byte) trans[i];
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Identify which colormap entry is the background color.
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < (long) MagickMax(1L*number_colors-1L,1L); i++)
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (IsPNGColorEqual(ping_info->background,image->colormap[i]))
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->background.index=(png_byte) i;
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
70813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
70853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->trans_color.red*=0x0101;
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->trans_color.green*=0x0101;
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->trans_color.blue*=0x0101;
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->trans_color.gray*=0x0101;
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (ping_info->bit_depth < 8 && ping_info->color_type ==
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_color_16
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           background;
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         maxval=(png_uint_16) ((1 << ping_info->bit_depth)-1);
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         background.gray=(png_uint_16)
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Setting up bKGD chunk");
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_set_bKGD(ping,ping_info,&background);
71153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         ping_info->trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ping_info->trans_color.gray));
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    PNG color type: %d",ping_info->color_type);
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up deflate compression");
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 99)
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression buffer size: 32768");
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
71343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
71393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      level=(int) MagickMin((long) quality/10,9);
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
71653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->filter_type=PNG_INTRAPIXEL_DIFFERENCING;
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
71733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter=PNG_ALL_FILTERS;
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((quality % 10) != 5)
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY) ||
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE) ||
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_NO_FILTERS;
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
71913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_ALL_FILTERS;
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
71933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (StringInfo *) NULL)
72093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10008) && defined(PNG_WRITE_iCCP_SUPPORTED)
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((LocaleCompare(name,"ICC") == 0) ||
72123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (LocaleCompare(name,"ICM") == 0))
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_iCCP(ping,ping_info,(const png_charp) name,0,(png_charp)
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetStringInfoDatum(profile),
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (png_uint_32) GetStringInfoLength(profile));
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_raw_profile(image_info,ping,ping_info,(unsigned char *)
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            name,(unsigned char *) name,GetStringInfoDatum(profile),
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_32) GetStringInfoLength(profile));
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Setting up text chunk with %s profile",name);
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    name=GetNextImageProfile(image);
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Note image rendering intent.
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Setting up sRGB chunk");
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_set_sRGB(ping,ping_info,(int) (image->rendering_intent-1));
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_gAMA(ping,ping_info,0.45455);
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_mng) || !(ping_info->valid & PNG_INFO_sRGB))
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
72473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_chrm == 0) &&
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image chromaticity.
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PrimaryInfo
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             bp,
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             gp,
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             rp,
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             wp;
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           wp=image->chromaticity.white_point;
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           rp=image->chromaticity.red_primary;
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           gp=image->chromaticity.green_primary;
72723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           bp=image->chromaticity.blue_primary;
72733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               "  Setting up cHRM chunk");
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               bp.x,bp.y);
72793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info->interlace_type=image_info->interlace != NoInterlace;
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_colortype)
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ping_info->color_type = PNG_COLOR_TYPE_RGB;
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (ping_info->bit_depth < 8)
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ping_info->bit_depth=8;
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         ping_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->write_png_depth &&
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->write_png_depth != ping_info->bit_depth) ||
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->write_png_colortype-1 != ping_info->color_type))
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->bit_depth);
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->color_type);
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_error(ping,
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && !image->matte)
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",(int) logging);
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
73443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",(int) logging);
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width || image->page.height)
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       unsigned char
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[14];
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       LogPNGChunk((int) logging,mng_vpAg,9L);
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping->mode |= PNG_HAVE_IDAT;
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth <= 8)
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png24 || (mng_info->write_png_depth == 8 &&
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_RGB))
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (mng_info->write_png32 || (mng_info->write_png_depth == 8 &&
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_RGB_ALPHA))
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if ((!mng_info->write_png8 ||
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY ||
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA )&&
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ((mng_info->optimize || mng_info->IsPalette) && ImageIsGray(image)))
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=(image_matte ? 2 : 1);
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (!mng_info->IsPalette)
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            rowbytes*=(image_matte ? 4 : 3);
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->optimize || mng_info->IsPalette) &&
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ImageIsGray(image))
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=(image_matte ? 4 : 2);
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=(image_matte ? 8 : 6);
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging)
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Allocating %lu bytes of memory for pixels",rowbytes);
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*png_pixels));
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (setjmp(ping->jmpbuf))
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
74223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RelinquishSemaphoreInfo(png_semaphore);
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7430ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
7431ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
7432ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
74333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
74343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
74353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      !mng_info->write_png32) &&
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (mng_info->optimize || mng_info->IsPalette ||
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      !image_matte && ImageIsMonochrome(image))
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (y=0; y < (long) image->rows; y++)
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
74533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
74563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
74573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
74623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
74633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
74643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
74653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < (long) image->columns; i++)
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
74683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
74693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
74703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
74713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RedQuantum,png_pixels,&image->exception);
74743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < (long) image->columns; i++)
74773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
74783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
74793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
74803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
74813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
74823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
74833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
74843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
74853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
74863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
74873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
74883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
74903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
74913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
74933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
74943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
74963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
74973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image_matte ||
74983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (ping_info->bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
74993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (mng_info->optimize || mng_info->IsPalette) && ImageIsGray(image))
75003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
75013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (y=0; y < (long) image->rows; y++)
75023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
75043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
75073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->IsPalette)
75093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,GrayQuantum,png_pixels,&image->exception);
75113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
75123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,RedQuantum,png_pixels,&image->exception);
75143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else /* PNG_COLOR_TYPE_GRAY_ALPHA */
75163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
75243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
75263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
75273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
75293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
75313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_depth > 8) || (mng_info->write_png24 ||
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette)))
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (y=0; y < (long) image->rows; y++)
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->storage_class == DirectClass)
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,RedQuantum,png_pixels,&image->exception);
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,GrayQuantum,png_pixels,&image->exception);
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (image_matte != MagickFalse)
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBAQuantum,png_pixels,&image->exception);
75553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
75563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBQuantum,png_pixels,&image->exception);
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
75603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
75613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* not ((image_depth > 8) || (mng_info->write_png24 ||
75623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette))) */
75643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((ping_info->color_type != PNG_COLOR_TYPE_GRAY) &&
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (ping_info->color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
75673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging)
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum_info->depth=8;
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_depth=8;
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (y=0; y < (long) image->rows; y++)
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging)
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
75823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
75853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,IndexQuantum,png_pixels,&image->exception);
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7602b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
7603b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Writing PNG image data");
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Width: %lu",ping_info->width);
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Height: %lu",ping_info->height);
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG bit-depth written: %d",ping_info->bit_depth);
76203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color-type written: %d",ping_info->color_type);
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG Interlace method: %d",ping_info->interlace_type);
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER <= 10005)
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info->num_text=0;
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImagePropertyIterator(image);
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  property=GetNextImageProperty(image);
76383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (property != (const char *) NULL)
76393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10005)
76413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_textp
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      text;
76433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    value=GetImageProperty(image,property);
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (value != (const char *) NULL)
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10005)
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
76503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].key=(char *) property;
76513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text=(char *) value;
76523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text_length=strlen(value);
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].compression=image_info->compression == NoCompression ||
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image_info->compression == UndefinedCompression &&
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          text[0].text_length < 128) ? -1 : 0;
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
76573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up text chunk");
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    keyword: %s",text[0].key);
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_text(ping,ping_info,text,1);
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_free(ping,text);
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
76663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Work directly with ping_info struct; png_set_text before libpng version
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * 1.0.5a is leaky */
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ping_info->num_text == 0)
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->text=(png_text *) AcquireQuantumMemory(256,
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              sizeof(*ping_info->text));
76723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ping_info->text == (png_text *) NULL)
76733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
76763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
76773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i=ping_info->num_text++;
76783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (i > 255)
76793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
76803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ResourceLimitError,"Cannot write more than 256 PNG text chunks",
76813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "`%s'",image->filename);
76823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->text[i].key=(char *) property;
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->text[i].text=(char *) value;
76843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->text[i].text_length=strlen(value);
76853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->text[i].compression=
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->compression == NoCompression ||
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image_info->compression == UndefinedCompression &&
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->text[i].text_length < 128) ? -1 : 0;
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up text chunk");
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    keyword: %s",ping_info->text[i].key);
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
76963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    property=GetNextImageProperty(image);
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",(int) logging);
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (ping_info->width != mng_info->page.width) ||
77123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (ping_info->height != mng_info->page.height))
77133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
77153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
77183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
77193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
77203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_FRAM,27L);
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
77243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
77263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
77273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
77283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
77293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
77303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
77313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
77323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (png_uint_32) (mng_info->page.x + ping_info->width));
77343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
77363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (png_uint_32) (mng_info->page.y + ping_info->height));
77373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
77433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
77443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
77463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
77473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
77503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=save_image_depth;
77513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Save depth actually written */
77533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  s[0]=(char) ping_info->bit_depth;
77553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  s[1]='\0';
77563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProperty(image,"png:bit-depth-written",s);
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
77623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10007)
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_PLTE)
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->palette=(png_colorp)
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        RelinquishMagickMemory(ping_info->palette);
77673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->valid&=(~PNG_INFO_PLTE);
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_tRNS)
77703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->trans_alpha=(unsigned char *) RelinquishMagickMemory(
77723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->trans_alpha);
77733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->valid&=(~PNG_INFO_tRNS);
77743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
77763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
77783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
77803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
77823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RelinquishSemaphoreInfo(png_semaphore);
77833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
77843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
77863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
77883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
77893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
77903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
77913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
77933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
77953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
77963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
77973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
77983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
77993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
78003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
78013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
78043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
78053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
78073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
78093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
78113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
78133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
78153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
78173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
78193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
78213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
78233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
78243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
78253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
78273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
78283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
78293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparent).  The pixels contain 8-bit indices even if
78303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               they could be represented with 1, 2, or 4 bits. Note: grayscale
78313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
78323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               PNG grayscale type might be slightly more efficient.
78333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
78363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               one of the colors as transparent.
78373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
78393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
78403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
78413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               channel is present even if the image is fully opaque.
78423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
78443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
78453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
78463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               from the application programming interfaces.
78473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
78493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
78513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
78523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
78543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
78553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
78573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
78583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
78593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
78603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
78623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
78633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  If the image cannot be written without loss in the requested PNG8, PNG24,
78653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or PNG32 format or with the requested bit-depth and color-type without loss,
78663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a PNG file will not be written, and the encoder will return MagickFalse.
78673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
78683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
78693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
78703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transparency prior to attempting to write the image in a format that
78713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is subject to depth, color, or transparency limitations.
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
78743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Allow all other PNG subformats to be requested via new
78763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        "-define png:bit-depth -define png:color-type" options.
78773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
78793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
78803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
78813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
78833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
78843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
78853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
78863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
78883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
78903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
78913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
78933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
78943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
78953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  subsequent profiles from overwriting the preceding ones:
78963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x01:file01 -profile PNG-chunk-x02:file02
78983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
79013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
79023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
79033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
79043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
79053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
79063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
79083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
79093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
79113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
79123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
79143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
79153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
79173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
79183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
79203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
79213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
79223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
79233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
79243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
79253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
79263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
79283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
79293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
79313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
79323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
79333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
79343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
79363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
79373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
79403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
79413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
79423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
79433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
79443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
79463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
79483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
79493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
79503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
79523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = /* 3 */ 4;
79543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
79553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->depth = 8;
79563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0 /* this does not work */
79573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->matte == MagickTrue)
79583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,PaletteMatteType);
79593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
79603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,PaletteType);
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(image);
79623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
79633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
79663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = /* 2 */ 3;
79683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
79693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->depth = 8;
79703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->matte == MagickTrue)
79713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorMatteType);
79723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
79733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorType);
79743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(image);
79753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
79783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = /* 6 */  7;
79803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
79813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->depth = 8;
79823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->matte == MagickTrue)
79833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorMatteType);
79843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
79853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorType);
79863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(image);
79873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
79903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
79913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
79933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 1;
79943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
79953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 2;
79963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
79973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 4;
79983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
79993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
80003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
80013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 16;
80023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
80033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         "png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
80053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
80063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
80073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
80083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
80103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
80113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 1;
80123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
80133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 3;
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
80153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 4;
80163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
80173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 5;
80183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
80193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 7;
80203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
80213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         "png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
80233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
80243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOnePNGImage(mng_info,image_info,image);
80263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
80283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
80303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
80313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
80323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
80333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
80343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
80363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
80383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
80393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
80403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
80413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
80423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
80433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
80453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
80463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
80483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
80493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
80513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
80523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
80543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
80553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
80563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
80573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
80593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
80603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
80613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
80623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
80633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
80643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
80663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
80673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
80693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOneJNGImage()");
80703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
80723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
80733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
80743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
80763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
80773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
80783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
80793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
80803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
80813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
80823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
80843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
80863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
80873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
80883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
80893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
80903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
80923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
80943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
80953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
80963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
80983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
80993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
81003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
81013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
81023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
81053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
81063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
81073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
81083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
81093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
81103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
81123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
81133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
81173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
81183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
81193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
81253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
81273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
81303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
81323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
81353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
81373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
81403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
81423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
81433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
81453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
81463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
81473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
81493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
81533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
81543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
81553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
81583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
81593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
81613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
81643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
81653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
81673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
81693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
81703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             &image->exception);
81713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
81723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
81733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Successfully read jpeg_image into a blob, length=%lu.",
81753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (unsigned long) length);
81763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
81783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
81793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
81803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
81813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
81853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
81863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
81873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JHDR,16L);
81883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGLong(chunk+4,image->columns);
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGLong(chunk+8,image->rows);
81903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
81913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
81923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
81933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
81943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
81953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
81963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
81973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
81983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
81993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
82003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG width:%15lu",image->columns);
82043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG height:%14lu",image->rows);
82063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
82083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
82103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
82123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
82143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
82163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
82183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
82203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-b profiles */
82253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",(int) logging);
82263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
82293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
82303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
82323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
82343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
82353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
82363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
82383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
82393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
82403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
82413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    long
82433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
82443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
82463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
82473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
82483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
82493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,(unsigned long) (num_bytes-4L));
82503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    LogPNGChunk((int) logging,mng_bKGD,(unsigned long) (num_bytes-4L));
82523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
82533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
82553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
82563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
82573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
82583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
82593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
82603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
82613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
82623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
82633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
82643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
82663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
82683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
82693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
82703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
82713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
82723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_sRGB,1L);
82733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
82743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk[4]=(unsigned char) (image->rendering_intent-1);
82753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
82763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk[4]=(unsigned char) (PerceptualIntent-1);
82773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
82783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
82793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
82813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
82833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
82843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
82853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
82893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_gAMA,4L);
82903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+4,(unsigned long) (100000*image->gamma+0.5));
82913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
82923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
82933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
82943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
82953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
82963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
82973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
82983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
82993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
83013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
83023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
83033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
83043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
83053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_cHRM,32L);
83063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
83073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+4,(unsigned long) (100000*primary.x+0.5));
83083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+8,(unsigned long) (100000*primary.y+0.5));
83093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
83103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+12,(unsigned long) (100000*primary.x+0.5));
83113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+16,(unsigned long) (100000*primary.y+0.5));
83123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
83133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+20,(unsigned long) (100000*primary.x+0.5));
83143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+24,(unsigned long) (100000*primary.y+0.5));
83153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
83163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+28,(unsigned long) (100000*primary.x+0.5));
83173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+32,(unsigned long) (100000*primary.y+0.5));
83183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
83193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
83203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
83233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
83253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
83263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
83273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
83283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
83293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_pHYs,9L);
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
83313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+4,(unsigned long)
83333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
83343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+8,(unsigned long)
83353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
83363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
83373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
83393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
83413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              PNGLong(chunk+4,(unsigned long)
83433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
83443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              PNGLong(chunk+8,(unsigned long)
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
83463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
83473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
83483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
83493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              PNGLong(chunk+4,(unsigned long) (image->x_resolution+0.5));
83513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              PNGLong(chunk+8,(unsigned long) (image->y_resolution+0.5));
83523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
83533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
83543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
83563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
83573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
83603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
83623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
83633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
83643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
83653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
83663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_oFFs,9L);
83673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGsLong(chunk+4,(long) (image->page.x));
83683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGsLong(chunk+8,(long) (image->page.y));
83693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
83703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
83713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
83723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
83743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
83763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       LogPNGChunk((int) logging,mng_vpAg,9L);
83783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
83803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
83813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
83823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
83833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
83873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          register long
83913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
83923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          long
83943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
83953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
83973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
83983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Write IDAT chunks from blob, length=%lu.",
84003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (unsigned long) length);
84013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
84033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
84043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
84053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=8; i<(long) length; i+=len+12)
84063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
84073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
84083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
84093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
84103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
84113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
84123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,(unsigned long) len);
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_IDAT,(unsigned long) len);
84143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
84153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
84163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
84173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
84183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
84193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
84203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
84213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Skipping %c%c%c%c chunk, length=%lu.",
84233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *(p),*(p+1),*(p+2),*(p+3),len);
84243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
84253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
84263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
84273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
84293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
84313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
84323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Write JDAA chunk, length=%lu.",
84343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (unsigned long) length);
84353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,(unsigned long) length);
84363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
84373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_JDAA,length);
84383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
84393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
84403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
84413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
84423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
84433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
84453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
84483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
84513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
84523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
84533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
84543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
84583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
84603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
84613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
84623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
84633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
84653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
84663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
84673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
84693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
84703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Created jpeg_image, %lu x %lu.",jpeg_image->columns,
84743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->rows);
84753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
84773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
84783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
84793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
84803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
84813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
84843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
84853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Successfully read jpeg_image into a blob, length=%lu.",
84893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (unsigned long) length);
84903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Write JDAT chunk, length=%lu.",
84933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (unsigned long) length);
84943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
84963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,(unsigned long) length);
84973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
84983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JDAT,length);
84993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
85003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
85013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
85023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
85043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
85053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
85063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
85073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
85093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",(int) logging);
85103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
85123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
85133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
85143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_IEND,0);
85153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
85163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
85173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
85213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
85223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
85233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
85263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
85313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
85373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
85393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
85413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
85433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
85453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
85473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
85493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
85523ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
85533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
85543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
85553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
85563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
85583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
85593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
85613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
85623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
85643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
85653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
85673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
85683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
85693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
85703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
85713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
85723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
85733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
85753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
85763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
85773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
85783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
85803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
85813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
85823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
85833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
85843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
85853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
85863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
85873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
85883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
85893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
85903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
85913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
85923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
85943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
85963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
85973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
86003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
86013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
86023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
86033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
86043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
86103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
86113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
86123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
86143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
86153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
86173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
86183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
86203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
86213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
86233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
86243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
86253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
86263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
86273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
86293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
86303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
86313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
86323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
86343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
86353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
86363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
86373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
86383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
86403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
86413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
86433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
86473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
86483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned long
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
86513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
86533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
86543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10007)
86573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
86583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
86593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
86603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
86663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
86683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
86693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
86703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
86723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
86743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
86803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
86813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
86823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
86843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
86863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
86873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
86893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
86923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
86983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
86993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
87023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
87063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
87103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
87133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=MagickFalse;
87143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
87153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=(image_info->type == OptimizeType || image_info->type ==
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      UndefinedType);
87173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
87213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
87223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
87233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
87263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (optimize)
87273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: TRUE");
87293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
87303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: FALSE");
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Image_info depth: %ld",image_info->depth);
87343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
87363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
87383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
87403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Scene: %ld",scene++);
87423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "      Image depth: %lu",p->depth);
87443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
87483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
87503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
87513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
87533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
87543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
87563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
87573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: %lu",p->colors);
87593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
87603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
87623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
87633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
87643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
87653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Sometimes we get PseudoClass images whose RGB values don't match
87693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    the colors in the colormap.  This code syncs the RGB values.
87703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
87713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
87723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Image
87733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p;
87743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (p->taint && p->storage_class == PseudoClass)
87783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(p);
87793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->adjoin == MagickFalse)
87803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
87813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
87833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_BUILD_PALETTE
87853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (optimize)
87863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
87883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Sometimes we get DirectClass images that have 256 colors or fewer.
87893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        This code will convert them to PseudoClass and build a colormap.
87903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
87933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
87953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
87963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class != PseudoClass)
87973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p->colors=GetNumberColors(p,(FILE *) NULL,&p->exception);
87993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p->colors <= 256)
88003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
88013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p->colors=0;
88023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p->matte != MagickFalse)
88033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageType(p,PaletteMatteType);
88043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
88053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageType(p,PaletteType);
88063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
88073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
88093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
88153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
88163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
88173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
88183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
88203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
88213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
88223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
88233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
88253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
88263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
88273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
88293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
88303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
88313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
88323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
88333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
88343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
88353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
88373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
88383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
88403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
88413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
88423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
88433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
88453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
88463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
88473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
88483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
88493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
88503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
88513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
88523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
88533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
88563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
88573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
88583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
88593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
88603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
88613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
88623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
88633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
88643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
88663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
88673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
88683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
88703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
88713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
88723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
88733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
88753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
88763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
88773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
88793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
88803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
88813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
88823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
88833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
88843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
88853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
88863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
88873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
88883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
88893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
88903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
88913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
88923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
88933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
88943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
88953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
88963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
88973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
88993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
89003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
89013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
89023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
89033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
89073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
89083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
89093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
89103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
89113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
89123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
89133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
89143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
89153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
89163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
89173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
89183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
89203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
89213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
89223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
89243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
89253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
89263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
89283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
89333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
89343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
89353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
89363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
89383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
89393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
89463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
89493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
89523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
89623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
89653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
89733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 final_delay=10;
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 (void) ThrowMagickException(&image->exception,
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   "input has zero delay between all frames; assuming 10 cs",
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   "`%s'","");
89793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
89813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
89823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
89843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1UL*image->ticks_per_second/final_delay;
89853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
89863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
89873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
89893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
89983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
90103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     LogPNGChunk((int) logging,mng_MHDR,28L);
90113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+4,mng_info->page.width);
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+8,mng_info->page.height);
90133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
90143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
90163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
90183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
90453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
90463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
90473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
90483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
90493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
90503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
90523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
90533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
90623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
90633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
90643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,(unsigned long) length);
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_nEED,(unsigned long) length);
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_TERM,10L);
90803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
90813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
90823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
90833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
90853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               "     TERM delay: %lu",
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (png_uint_32) (mng_info->ticks_per_second*
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  final_delay/MagickMax(image->ticks_per_second,1)));
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
90953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 "     TERM iterations: %lu",PNG_UINT_31_MAX);
90973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 "     Image iterations: %lu",image->iterations);
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
91023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_sRGB,1L);
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) (image->rendering_intent-1);
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) (PerceptualIntent-1);
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
91233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
91323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
91333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_gAMA,4L);
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+4,(unsigned long) (100000*image->gamma+0.5));
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
91373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
91403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
91423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
91453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
91463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
91473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
91493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_cHRM,32L);
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+4,(unsigned long) (100000*primary.x+0.5));
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(unsigned long) (100000*primary.y+0.5));
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(unsigned long) (100000*primary.x+0.5));
91553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+16,(unsigned long) (100000*primary.y+0.5));
91563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+20,(unsigned long) (100000*primary.x+0.5));
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+24,(unsigned long) (100000*primary.y+0.5));
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+28,(unsigned long) (100000*primary.x+0.5));
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+32,(unsigned long) (100000*primary.y+0.5));
91623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
91643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
91723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
91743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_pHYs,9L);
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+4,(unsigned long)
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(unsigned long)
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
91823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
91873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 PNGLong(chunk+4,(unsigned long)
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 PNGLong(chunk+8,(unsigned long)
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
91953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 PNGLong(chunk+4,(unsigned long) (image->x_resolution+0.5));
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 PNGLong(chunk+8,(unsigned long) (image->y_resolution+0.5));
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
92013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
92053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
92143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
92153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_BACK,6L);
92163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
92173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
92183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
92193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
92203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
92213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
92223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
92233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
92243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
92253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
92273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
92283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_bKGD,6L);
92293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
92303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
92353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
92363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
92373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
92383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         unsigned long
92403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
92413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
92433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
92443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
92453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
92463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
92473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
92483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_PLTE,data_length);
92493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         for (i=0; i < (long) image->colors; i++)
92503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
92513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
92523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
92533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
92543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
92553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
92563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
92573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
92583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
92623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
92633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
92643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
92653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
92663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
92673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
92683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
92693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
92703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
92723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
92733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
92743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
92753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
92763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
92783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
92793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
92803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
92813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
92823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
92833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
92843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
92853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
92863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
92873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
92883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
92893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
92903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
92913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
92923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned long
92933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
92943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
92963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
92973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_PLTE,data_length);
92993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) image->colors; i++)
93003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
93013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
93023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
93043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
93053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
93073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
93123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
93133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
93163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
93173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        long
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
93273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
93323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
93363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_DEFI,12L);
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
93423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
93653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
93663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,1L);
93673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
93683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
93703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
93753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
93783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,10L);
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
93813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
93843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->delay=image->delay;
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
93993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
94023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
94073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
94323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
94373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_MEND,0L);
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
94503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* PNG_LIBPNG_VER > 95 */
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
94603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* PNG_LIBPNG_VER > 95 */
94703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9471