png.c revision a6a0663bea94c73cf424f0b49076e7c037d084d4
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%                                                                             %
217e41fe84a841d7b9d7b36b245b65e9dcb3314943cristy%  Copyright 1999-2011 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"
455c7cf4e469a4dad7e277783749155932252c52dfglennrp#include "magick/artifact.h"
465a2ca481ab4ff6751bba842263739966e53441aacristy#include "magick/attribute.h"
473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob.h"
483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob-private.h"
493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/cache.h"
503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color.h"
513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color-private.h"
524ccd4c0b8623aa47f1c10dd366666799e5957c3ccristy#include "magick/colormap.h"
533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/colorspace.h"
543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/constitute.h"
553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/enhance.h"
563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception.h"
573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception-private.h"
583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/geometry.h"
59f2e1166e90de2dfe2e6a2aed7cd5f73640f34a7acristy#include "magick/histogram.h"
603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image.h"
613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image-private.h"
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/layer.h"
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/list.h"
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/log.h"
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/magick.h"
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/memory_.h"
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/module.h"
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor.h"
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor-private.h"
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/option.h"
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/profile.h"
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/property.h"
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/resource_.h"
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/semaphore.h"
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/static.h"
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/statistic.h"
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/string_.h"
80f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy#include "magick/string-private.h"
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/transform.h"
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/utility.h"
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
84286a6355c4544b794da2b6df973faad07c69e541glennrp
857ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp/* Suppress libpng pedantic warnings that were added in
867ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * libpng-1.2.41 and libpng-1.4.0.  If you are working on
87faa852bad40107edae19405e76a299057668d795glennrp * migration to libpng-1.5, remove these defines and then
887ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * fix any code that generates warnings.
897ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp */
90991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp/* #define PNG_DEPRECATED   Use of this function is deprecated */
91faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_USE_RESULT   The result of this function must be checked */
92faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_NORETURN     This function does not return */
93faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_ALLOCATED    The result of the function is new memory */
94faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_DEPSTRUCT    Access to this struct member is deprecated */
95286a6355c4544b794da2b6df973faad07c69e541glennrp
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "png.h"
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* ImageMagick differences */
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define first_scene scene
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Optional declarations. Define or undefine them as you like.
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Features under construction.  Define these to work on them.
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_OBJECT_BUFFERS
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_BASI_SUPPORTED
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
1153241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp#define PNG_BUILD_PALETTE   /* This works as of 6.6.6 */
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (((color).red == (target).red) && \
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).green == (target).green) && \
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).blue == (target).blue))
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *png_semaphore = (SemaphoreInfo *) NULL;
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
174bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2468182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
264bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
342bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38835ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
398b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  MagickBooleanType
399b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    need_blob;
400b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
423bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* Added at version 6.6.6-7 */
45626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  MagickBooleanType
45726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
45826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
45926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
46026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
46126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
46226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
46326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
46426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
46526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
46626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
467a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
46826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
46926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
47026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt;
47126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4800c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4830c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4890c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
4900c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4910c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
4920c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
4938640fb5e9b1094f35f8beab436f81661b8a99448glennrp  LosslessReduceDepthOK(Image *image)
4940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
4950c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    MagickBooleanType
4960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      ok_to_reduce=MagickFalse;
4970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    /* Reduce bit depth if it can be reduced losslessly from 16 to 8.
4990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * Note that the method GetImageDepth doesn't check background
5000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * and doesn't handle PseudoClass specially.  Also it uses
5010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * multiplication and division by 257 instead of shifting, so
5020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * might be slower.
5030c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     */
5040c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5050c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    if (image->depth == 16)
5060c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
5070c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5080c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        const PixelPacket
5090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
5100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
5120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          (((((size_t) image->background_color.red >> 8) & 0xff)
5138640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.red & 0xff)) &&
5140c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp           ((((size_t) image->background_color.green >> 8) & 0xff)
5158640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.green & 0xff)) &&
5160c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp           ((((size_t) image->background_color.blue >> 8) & 0xff)
5178640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.blue & 0xff))) ? MagickTrue :
5188640fb5e9b1094f35f8beab436f81661b8a99448glennrp          MagickFalse;
5190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5200c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
5210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5220c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
5230c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5240c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
5250c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5268640fb5e9b1094f35f8beab436f81661b8a99448glennrp                ok_to_reduce=(((((size_t) image->colormap[indx].red >>
5278640fb5e9b1094f35f8beab436f81661b8a99448glennrp                    8) & 0xff)
5288640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].red & 0xff)) &&
5290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].green >> 8) & 0xff)
5308640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].green & 0xff)) &&
5310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].blue >> 8) & 0xff)
5328640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].blue & 0xff)) &&
5330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].opacity >> 8) & 0xff)
5348640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].opacity & 0xff))) ?
53513d07043243e0c8c151aad7db5240b75e76ca281cristy                  MagickTrue : MagickFalse;
5360c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5370c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5380c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5410c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
5420c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
5430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5440c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
5450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
5460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
5480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
5490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
5510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
5520c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5530c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5540c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              if (p == (const PixelPacket *) NULL)
5550c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
5560c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
5570c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5580c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
5590c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5600c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
5610c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5628640fb5e9b1094f35f8beab436f81661b8a99448glennrp                ok_to_reduce=((
5638640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((size_t) p->red >> 8) & 0xff) ==
5648640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->red & 0xff)) &&
5650c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) p->green >> 8) & 0xff) ==
5668640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->green & 0xff)) &&
5670c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) p->blue >> 8) & 0xff) ==
5688640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->blue & 0xff)) &&
5698640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((!image->matte ||
5708640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((size_t) p->opacity >> 8) & 0xff) ==
5718640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->opacity & 0xff))))) ? MagickTrue : MagickFalse;
5720c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5730c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5740c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5760c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                p++;
5770c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5788640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
5790c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
5800c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
5810c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5830c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
5840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5850c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5868640fb5e9b1094f35f8beab436f81661b8a99448glennrp                "  OK to reduce PNG bit depth to 8 without loss of info");
5870c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
588a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        else
589a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          {
590a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
591a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                "  Not OK to reduce PNG bit depth to 8 without loss of info");
592a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          }
5930c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
5940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5950c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
5960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
5970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
5980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
599e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
600e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_from_Magick_RenderingIntent(const RenderingIntent intent)
6010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
602e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
603e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
604e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
605e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
6060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
607e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
608e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
6090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
610e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
611e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
6120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
613e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
614e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
6150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
616e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
617e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
618e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
619e610a071534e448c46460a5aa39ede33bf56b329glennrp}
620e610a071534e448c46460a5aa39ede33bf56b329glennrp
621e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
622e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_to_Magick_RenderingIntent(const int png_intent)
6230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
624e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (png_intent)
625e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
626e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
627e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
6280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
629e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
630e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
6310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
632e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
633e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
6340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
635e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
636e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
6370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
638e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
639e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
640e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
641e610a071534e448c46460a5aa39ede33bf56b329glennrp}
642e610a071534e448c46460a5aa39ede33bf56b329glennrp
643bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
651bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6580c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
659dbb105fc25903e800273f7e980c0553060858a68glennrp
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
665dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s G r a y                                                     %
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
670dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
671dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
672dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
673dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
675dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsGray(Image *image)
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
680bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
682dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
683dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
688dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
689dbb105fc25903e800273f7e980c0553060858a68glennrp
690dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
692dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
693dbb105fc25903e800273f7e980c0553060858a68glennrp        if (IsGray(image->colormap+i) == MagickFalse)
694dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
695dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickTrue);
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
697bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
701dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
702dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
703dbb105fc25903e800273f7e980c0553060858a68glennrp    {
704dbb105fc25903e800273f7e980c0553060858a68glennrp       if (IsGray(p) == MagickFalse)
705dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
706dbb105fc25903e800273f7e980c0553060858a68glennrp       p++;
707dbb105fc25903e800273f7e980c0553060858a68glennrp    }
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
709dbb105fc25903e800273f7e980c0553060858a68glennrp  return(MagickTrue);
710dbb105fc25903e800273f7e980c0553060858a68glennrp}
711dbb105fc25903e800273f7e980c0553060858a68glennrp
712dbb105fc25903e800273f7e980c0553060858a68glennrp/*
713dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
714dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
715dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
716dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
717dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s M o n o c h r o m e                                         %
718dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
719dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
720dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
721dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
722dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
723dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
724dbb105fc25903e800273f7e980c0553060858a68glennrp%   and is more accurate.                                                     %
725dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
726dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
727dbb105fc25903e800273f7e980c0553060858a68glennrp*/
728dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsMonochrome(Image *image)
729dbb105fc25903e800273f7e980c0553060858a68glennrp{
730dbb105fc25903e800273f7e980c0553060858a68glennrp  register const PixelPacket
731dbb105fc25903e800273f7e980c0553060858a68glennrp    *p;
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
733dbb105fc25903e800273f7e980c0553060858a68glennrp  register ssize_t
734dbb105fc25903e800273f7e980c0553060858a68glennrp    i,
735dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
736dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
737a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
738dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image != (Image *) NULL);
739dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image->signature == MagickSignature);
740a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if (image->debug != MagickFalse)
741dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
742dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
743a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp    {
744dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
745dbb105fc25903e800273f7e980c0553060858a68glennrp      {
746dbb105fc25903e800273f7e980c0553060858a68glennrp        if ((IsGray(image->colormap+i) == MagickFalse) ||
747dbb105fc25903e800273f7e980c0553060858a68glennrp            ((image->colormap[i].red != 0) &&
748dbb105fc25903e800273f7e980c0553060858a68glennrp             (image->colormap[i].red != (Quantum) QuantumRange)))
749dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
750dbb105fc25903e800273f7e980c0553060858a68glennrp      }
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
753dbb105fc25903e800273f7e980c0553060858a68glennrp  for (y=0; y < (ssize_t) image->rows; y++)
754dbb105fc25903e800273f7e980c0553060858a68glennrp  {
755dbb105fc25903e800273f7e980c0553060858a68glennrp    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
756dbb105fc25903e800273f7e980c0553060858a68glennrp    if (p == (const PixelPacket *) NULL)
757dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
758dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsGray(p) == MagickFalse)
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->opacity != OpaqueOpacity) &&
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (p->opacity != (Quantum) TransparentOpacity))
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
775d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
893d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
894bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
916a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
924a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93703812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
93803812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
942e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
943e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
945d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
951d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
1065e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1066e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1094bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
11100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
11130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1170bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
11710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1185bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1197bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
12190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
12240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1237bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1239bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrpstatic void MngInfoFreeStruct(MngInfo *mng_info,
124421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    MagickBooleanType *have_mng_structure)
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
124621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp  if (*have_mng_structure != MagickFalse && (mng_info != (MngInfo *) NULL))
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1248bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
12530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
12570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
12710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
12740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
12770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
12800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1292bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1293bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1294bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1295bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1313bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
13158182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
13168182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
13170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13278182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13298182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGErrorHandler(png_struct *ping,png_const_charp message)
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
13380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
13420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
13450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1346e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1348faa852bad40107edae19405e76a299057668d795glennrp#else
1349faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1350faa852bad40107edae19405e76a299057668d795glennrp#endif
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGWarningHandler(png_struct *ping,png_const_charp message)
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
13600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1364cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
13650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
13790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
13820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_read_raw_profile(Image *image, const ImageInfo *image_info,
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1409bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14250c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1442f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
14430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
14560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
14680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1469bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
14850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
14940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
14970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1531bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
15330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1534bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1588faa852bad40107edae19405e76a299057668d795glennrp    pass,
1589faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1590faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1591faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1592faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1593faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
1594faa852bad40107edae19405e76a299057668d795glennrp    ping_num_trans;
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1596a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  LongPixelPacket
1597a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    transparent_color;
1598a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
16004383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1603faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1604faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1605faa852bad40107edae19405e76a299057668d795glennrp
1606faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1607faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1608faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1609faa852bad40107edae19405e76a299057668d795glennrp
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1620faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1621faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1622faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
1623faa852bad40107edae19405e76a299057668d795glennrp    ping_rowbytes;
1624faa852bad40107edae19405e76a299057668d795glennrp
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1631bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
16385c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1640bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
164839992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOnePNGImage()");
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1667f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
167025c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
167661b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
167761b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
167861b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
167961b4c957269727a0a2526edc2331881da8346100glennrp    {
168061b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
168161b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
168261b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
168361b4c957269727a0a2526edc2331881da8346100glennrp    }
168461b4c957269727a0a2526edc2331881da8346100glennrp#  endif
168561b4c957269727a0a2526edc2331881da8346100glennrp#endif
168661b4c957269727a0a2526edc2331881da8346100glennrp
168761b4c957269727a0a2526edc2331881da8346100glennrp
1688ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1691a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
1692a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
1693a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      "  image->matte=%d",(int) image->matte);
1694a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   PNGErrorHandler,PNGWarningHandler, NULL,
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
17100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
17180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
17260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1727faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1734f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
17390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
17417b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
17427b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
17437b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
17447b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
17450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1751faa852bad40107edae19405e76a299057668d795glennrp
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
17540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1787991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1788991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1789991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1803991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1807faa852bad40107edae19405e76a299057668d795glennrp
1808faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1809faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1810faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1811faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1812faa852bad40107edae19405e76a299057668d795glennrp
1813faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1814faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1815faa852bad40107edae19405e76a299057668d795glennrp
1816faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1817faa852bad40107edae19405e76a299057668d795glennrp
1818faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1820faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1821faa852bad40107edae19405e76a299057668d795glennrp        {
1822faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1823faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1824faa852bad40107edae19405e76a299057668d795glennrp        }
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1826faa852bad40107edae19405e76a299057668d795glennrp
1827faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1829faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1833e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1834e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
18350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1838faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
18390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1842faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
18430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1846faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1849faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1850faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1855e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
1856e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
1857e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1858e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
1859e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
1860e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1861e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
1862e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1893e610a071534e448c46460a5aa39ede33bf56b329glennrp      image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1894e610a071534e448c46460a5aa39ede33bf56b329glennrp        mng_info->global_srgb_intent);
18950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1898e610a071534e448c46460a5aa39ede33bf56b329glennrp        image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1899e610a071534e448c46460a5aa39ede33bf56b329glennrp          intent);
19000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1903e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1911faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1912faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1913faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
19140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1923faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1924faa852bad40107edae19405e76a299057668d795glennrp    {
1925faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1926faa852bad40107edae19405e76a299057668d795glennrp        {
1927faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1928faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1929faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1930faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1931faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1932faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1933faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1934faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1935faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1936faa852bad40107edae19405e76a299057668d795glennrp        }
1937faa852bad40107edae19405e76a299057668d795glennrp    }
19380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1939faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1956e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1958e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
1959e610a071534e448c46460a5aa39ede33bf56b329glennrp         PNG_RenderingIntent_from_Magick_RenderingIntent(
1960e610a071534e448c46460a5aa39ede33bf56b329glennrp         image->rendering_intent));
1961faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
1962faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
1963faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
1964faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
1967faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=png_get_x_offset_pixels(ping, ping_info);
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=png_get_y_offset_pixels(ping, ping_info);
19710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1975e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
1976e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
1980faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
1981faa852bad40107edae19405e76a299057668d795glennrp    {
1982faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
1983faa852bad40107edae19405e76a299057668d795glennrp        {
1984faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
1985faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
1986faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
1987faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
1988faa852bad40107edae19405e76a299057668d795glennrp        }
1989faa852bad40107edae19405e76a299057668d795glennrp    }
1990faa852bad40107edae19405e76a299057668d795glennrp
1991faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
20040881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
20050881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
20060881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
20070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2017e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2018e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2021faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
20300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2032faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
20380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2039faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2056faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2065faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2066faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
20670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
2089faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2090faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2093faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
21010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21022cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2104faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
2105faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
2106faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21092cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
21103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21112cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
21122cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
21132cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21142cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21152cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21162cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
21172cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
21182cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21192cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
21200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21212cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
21222cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
21230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21242cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
21252cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
21260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21272cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
21282cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
21290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21302cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
21312cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
21322cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21332cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
21342cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
21352cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
21362cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21372cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21382cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
21392cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21402cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
21410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21422cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21432cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
21442cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
21452cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
21462cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
2148faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
21490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
2151faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
21520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
2154faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
21550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2156f17da7472c6195cfc91626d98d166cae04345d34cristy          image->background_color.opacity=OpaqueOpacity;
21572cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21582cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21592cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2160e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
2161e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
2162e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
2163e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2167a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2168a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
2169a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  transparent_color.red=65537;
2170a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  transparent_color.green=65537;
2171a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  transparent_color.blue=65537;
2172a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  transparent_color.opacity=65537;
2173a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2174faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2177a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
218235ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
218335ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
218435ef824baa82511126ff0072ae30eee0da9c05a3cristy
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2189f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2191faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2192faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2193faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2194faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2195faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2196faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2202faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2207a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2208a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2209a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2210a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          scale_to_short = 65535L/((1UL << ping_bit_depth)-1);
2211a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2212a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2213a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2214a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2215a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
2216a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.opacity= scale_to_short*ping_trans_color->gray;
221705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2218faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
22200f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
22210f111984738842d27d04aed2a3f823d82a943506glennrp              {
22220f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22230f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
22240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22250f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22260f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
22270f111984738842d27d04aed2a3f823d82a943506glennrp              }
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2237faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2242faa852bad40107edae19405e76a299057668d795glennrp
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2244faa852bad40107edae19405e76a299057668d795glennrp
2245faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2246faa852bad40107edae19405e76a299057668d795glennrp
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2251bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2253bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2256faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2257faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2268faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2269faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2270faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2271faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2272faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2274befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2275befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2276befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2278befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2279befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2287faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2296bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
22970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2312faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
23210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2322bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
23290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2332bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2335faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
23360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
23390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2340bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
23503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
23530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23540ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2355347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2356347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2360e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2364f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
23690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
23760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2379faa852bad40107edae19405e76a299057668d795glennrp      ping_rowbytes*sizeof(*png_pixels));
23800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2382faa852bad40107edae19405e76a299057668d795glennrp    png_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sizeof(*png_pixels));
23840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2394faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
23983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2401f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
24023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
24050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
24080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
24120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
24147b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
24157b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
24167b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
24177b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
24180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
24203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2422ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
24230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2424ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2425ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2427c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
2428c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2429c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
2430c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
2431c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2432c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
2433c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2436c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
2437c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2438c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
2439c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
2440c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
2441c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#if  (MAGICKCORE_QUANTUM_DEPTH == 8)
2442c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        int
2443c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          depth;
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2445c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        depth=(ssize_t) ping_bit_depth;
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2447c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2448c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2449c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2450c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            MagickTrue : MagickFalse;
24510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2452c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
2453c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
2454c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
2455c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
24560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2457c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
2458c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
24590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2460c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          png_read_row(ping,png_pixels+row_offset,NULL);
2461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2463c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (q == (PixelPacket *) NULL)
2464c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
24650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2466c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#if  (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
2467c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp/* code deleted from version 6.6.6-8 */
2468c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#else  /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
24690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2470c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2472c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              GrayQuantum,png_pixels+row_offset,exception);
24730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2474c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2476c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              GrayAlphaQuantum,png_pixels+row_offset,exception);
24770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2478c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2480c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              RGBAQuantum,png_pixels+row_offset,exception);
24810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2482c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2483c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2484c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              IndexQuantum,png_pixels+row_offset,exception);
24850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2486c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
2487c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2488c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              RGBQuantum,png_pixels+row_offset,exception);
2489c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#endif
2490c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
2491c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2492c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
2493a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
2494a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2495a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
2496a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2497c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
2498c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
24995aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
25005aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
25015aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                   (q->opacity != OpaqueOpacity))
2502c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
2503a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2504a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2505a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
2506a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2507c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
2508c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
2509c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
25104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
25114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
2512a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    (ScaleQuantumToShort(q->red) == transparent_color.red &&
2513a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    ScaleQuantumToShort(q->green) == transparent_color.green &&
2514a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    ScaleQuantumToShort(q->blue) == transparent_color.blue))
25154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
2516a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2517a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2518a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
25194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
25204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
25214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
2522c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                q++;
2523c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
2524c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
25250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2526c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
2527c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2528c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2529c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
25300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2531c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
2532c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
2533c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
2534c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
2535c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
2536c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
25370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2538c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
25397a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2540c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
25417a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
25427a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
25437a287bfadeadea12e47c2376ca78a5d101687142cristy          }
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
2548c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
25553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2560faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
25620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
25650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
25680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2569bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2572faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
2573c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
2576c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
25790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25835c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=png_pixels+row_offset;
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2586c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2587faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2591bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2594bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2603bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
26053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
260947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2612bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2622bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
262847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2631bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
26390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
264247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2645faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2646bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
2655c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                if (q->opacity != OpaqueOpacity)
26560b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2661bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
266647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2669bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2672bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
268547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2686faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
2691c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
26920b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2697bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
27020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
27050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
27100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2711faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
2714afee4d36aae894a74306a3c492437ca55dce2badcristy                  q->opacity*=65537L;
271546f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
2716afee4d36aae894a74306a3c492437ca55dce2badcristy                  if (q->opacity != OpaqueOpacity)
27170b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
272147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
272547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2726faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
2729c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
27300b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
273747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
274047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
27480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2749bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
275080ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
27510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
27533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
27540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27557a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
27567a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2757cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2758cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
275947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27607a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
27617a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
27627a287bfadeadea12e47c2376ca78a5d101687142cristy          }
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2764c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27657a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
276847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
2772c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
27743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2775c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2776c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    image->matte=found_transparent_pixel;
2777c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2778c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
2779c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2780c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
2781c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2782c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
2783c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
27845aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
27855aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27865aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
2787a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
27885aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
27895aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
2790c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
2791c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
2792c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2793b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2794b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
27950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27965c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
27975c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2798aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
27995c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
28005c6f789db7a30bad01ace12b09ad9cd471339e94cristy
28015c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
28025c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
28035c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2804aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
28055c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
280647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2810bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
28113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
28133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
28143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
28153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
28163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2817f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
28183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
28223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
28233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
282447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2825faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
28293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
28343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2835c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28363c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
2837c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
28390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2841c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
28420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
28430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 image->colormap[x].opacity =
28450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                   ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
28460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
2847c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
284847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
28510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
28520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
28540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                     transparent_color.opacity)
28550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
28560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    image->colormap[x].opacity = (Quantum) TransparentOpacity;
28570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
28580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
28590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) SyncImage(image);
28610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
286247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2863a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
2864a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
2865a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
28660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
28670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
28690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
28700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
28710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2872c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (q == (PixelPacket *) NULL)
28740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
2875c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            indexes=GetAuthenticIndexQueue(image);
28770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2878a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
2879a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
2880a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
28810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
28820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
2883a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (ScaleQuantumToShort(q->red) == transparent_color.red &&
2884a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  ScaleQuantumToShort(q->green) == transparent_color.green &&
2885a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  ScaleQuantumToShort(q->blue) == transparent_color.blue)
28864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  q->opacity=(Quantum) TransparentOpacity;
28884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
28890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2890a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 0 /* I have not found a case where this is needed. */
28910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
28924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  q->opacity=(Quantum) OpaqueOpacity;
28944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
2895a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
28960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              q++;
28980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
29010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
2902c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
29030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
2904a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
2905c11cf6a442f3046940608a5743a68cc891deb13eglennrp
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29083c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
2909b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2910b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2911b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
291247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
2914bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) num_text; i++)
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
29210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_read_raw_profile(image,image_info,text,(int) i);
29240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
29293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
29430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
29470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29513c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
296473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
29650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
297247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
29800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
29930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
29960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
29990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
30040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3005faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
30070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3008faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3009faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3010faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3011faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3012faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3013faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3014faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3015faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
30160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3017faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
30303c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
303647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3049f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
30550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
30603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
306821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
306921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
30773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
30833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
30853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
308647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
309047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
309747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
310047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
310547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
310847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
311373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
311447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
311747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
312847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
31350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
31430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
314647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
314847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
31540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
315747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
31610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
316747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
31760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
31790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32314383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
32324383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
32334383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3234bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3257bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3272bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOneJNGImage()");
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
32890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
32980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
33000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
33030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
33310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
33340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3342e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3343e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
33470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
335047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
33540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
33570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3358bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
33600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
336347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
337047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3378bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
338647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
338947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
339447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3398f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
339947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3401f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
340247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
340547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
340947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
341347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
341747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
342147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
342547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
342947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
343547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
343847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
345473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
345547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
345847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
34610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
34680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
34720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
347973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
34800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
34860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
34970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
35010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
35040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
35130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
35160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
351903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
353647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
354347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
354647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
355547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3563bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
356503812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
358047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
36000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
36308182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
36310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36408182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
36418182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
36428182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
36438182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
36448182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
36458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
36468182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
36478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
364947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3658e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3659e610a071534e448c46460a5aa39ede33bf56b329glennrp              PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
367047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36798182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.x=mng_get_long(p);
36808182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.y=mng_get_long(&p[4]);
36810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
368847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
37008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
37080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* To do. */
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
37290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
375847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
37620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
37650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
37680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
37820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
37860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3787bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
379247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
37980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
380903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
38130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
38150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
38240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3826bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
383147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3833bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
38350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3837bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
38430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
385547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
385647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
38640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
38660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
38670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
38700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
38720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
38730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
38760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
38780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
38830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
38870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
392921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
393021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
39540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
39570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
396147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
396247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
396447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
396847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
396947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
397173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
39720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
397647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
397747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
39850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
39930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
39970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
400147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
40070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
40130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40274383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
402821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
402921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
40304383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4037bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4062bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4068bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4085bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
409438ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
409538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
409638ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4097bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
411947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
412047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
41300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
41330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
413747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
413847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
413947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
414073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
41410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
41440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
414547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
414647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
415647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
416047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
416147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4164bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4165bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
416947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4212e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4213e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
42170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
42200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
42230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
422747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
423047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4231bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
423347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
42430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
42470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
42540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
42580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
426347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
42680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
42750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4281bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
42830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4284bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
42860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4290e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4292e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
42968182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
42970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
43000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
43040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
43070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
43118182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
43150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
43180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
43210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
432847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
43300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
43330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
43410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4342e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4343e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4344f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
43450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4347bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4349bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
43510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
43540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
43670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43708182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
43718182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
43720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
43750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
43840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4386e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
43870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4389e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
44010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
44030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
44080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
44320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
44350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
44420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
44430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
44450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
44460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4450e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4451f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
44520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4454e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4455f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
44650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
44720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
44770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
44800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
44830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
44950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
44980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
45030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
45060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
45090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
452147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
452447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
452547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
45310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4532bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
453935ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
45480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
45540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
455847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4564bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
457112560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4579bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45828182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
45890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
459647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
459747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
46018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
46028182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
46048182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
46068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
46088182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
46108182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
46128182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
461747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
462147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4629e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4630e610a071534e448c46460a5aa39ede33bf56b329glennrp                  PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
463547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
463947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* To do. */
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
464947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
465247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
46590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
46620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
466647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
46700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
46740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
467747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
467847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
468047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4681bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
468347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
468547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4686bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
469747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
47018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
47020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47038182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
47048182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
47050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4706bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4707bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
47080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
47110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
47130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4716e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
471847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4721bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4722bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
47230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4724bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4725bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
47260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4727bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4728bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
47290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
47320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
47340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4737e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
473947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
47450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
4749e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4750e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
475147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
47590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4760bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
47620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4763bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4771e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4772e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
47730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
477747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
478147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
478847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
47930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
48030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
48140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4818e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4819e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
483647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
484847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
487247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
487347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4882bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4885bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
489747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4900bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
490447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
490547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4908bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
492547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4932bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
493547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
493647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
49378182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
49380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4941e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
4942e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
49430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
49460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
495747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
496147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
497347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
49800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
4984e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
4985f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
498647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
49910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
499647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
501447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
501847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
502547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
502847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
50450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
50480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
50510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
506247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
506847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
507447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
507747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
508347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
508647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
509247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
509547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
510147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
510447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
511047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
511347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
511947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
512247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
512847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
513247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
514047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
515947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
516647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
516947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
517647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
517947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
518447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
52008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
52028182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
520647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
521547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
522147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
522647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5229bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5231bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
523947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
524247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
524547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
524847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
525147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
525447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
525747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
526547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
526847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
527147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
527647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
528647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
529347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
529647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
530247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
531047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53118182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
53128182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5325bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5327bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
533547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
534247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
534647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
535347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
535647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
535747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
535847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5370e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5371e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
538847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
539547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
53980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
54000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
541047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
54210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5425e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5426e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
543047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
543747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
544447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
54500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
54530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
54620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
54710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
547747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
548147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
548647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5487bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
548847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
550047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
551347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
554647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
554947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
555147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
555247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
555447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55574e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
555847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
556147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
556447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
556647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
556747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
556947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
557347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
557647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
557847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
557947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
558147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55844e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
558547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
558847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
559147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
559347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
559447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
559647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5606bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5610bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
562547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
562647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
563047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
563247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5656bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
566047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5661bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
566947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
568047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
568547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
568847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
569147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
569447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5703e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5704bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
570947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
571847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
572147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5722bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5725bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
572647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5727bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5728bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
572947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5730bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5731bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
573247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5733bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
573547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5737bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
573847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
574247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5743bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
574947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5755bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
576147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5762bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
57645c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      /* TO DO: get color as function of indexes[x] */
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
577547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
578047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5784bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5785bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5787bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5788bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5790bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5791bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
579347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5795bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5798bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
580047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
581047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
581647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
581947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5822bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5823bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
583147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
583447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
583747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5856e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5858bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
586647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5867bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5868bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5870bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5871bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
587247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5873bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5874bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
587547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5876bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5877bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
587847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5879bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
588147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5883bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
588447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
589247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
589747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5903bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5906bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5909bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
5912bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
591547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
592547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
593147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
593447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
5939bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
594847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
5958bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
596147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5962bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
597047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
600447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6020bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6021bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
602747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
603947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
60632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
60642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       * if lossy
60652b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
60662b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
60672b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
60682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
60692b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
60700c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
60718640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if (LosslessReduceDepthOK(image) != MagickFalse)
60728640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6074d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
607647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6080bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6083d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6087d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
608947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
609147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
609547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
61060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
611747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
612147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
61340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
61370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
61420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
61450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
615347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
615747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
61620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
616747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
617347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
618147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
618647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
619247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
619547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
619847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
62060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
62090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
62120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
621747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
62230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
62250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6228e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6229e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
62300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
623847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
624147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6243e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
624447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6249e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6261bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
626647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
626947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
627247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
627547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
628447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
628747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
630447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
631447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
631747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6319e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6320e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
632147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6323f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6324f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
632547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6326f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6327e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6328e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6329f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6330f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
633147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
633547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
633847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
634125c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
634647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
634947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
635247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
635725c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6383bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
639647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
640247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
641047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
641447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
642247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
642547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
643047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
643347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
643647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
644247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
644747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
645247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
645547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
646047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
646547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
647547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
647947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
648647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
648947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
649447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
650247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
650747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
651547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
652247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
652947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
653018b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
653118b17443128598500357da7bff2f01683cf32890cristy  png_semaphore=AllocateSemaphoreInfo();
653218b17443128598500357da7bff2f01683cf32890cristy#endif
653347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
656447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6566514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy  if (png_semaphore != (SemaphoreInfo *) NULL)
6567514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy    DestroySemaphoreInfo(&png_semaphore);
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
657225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    some GIF animations don't convert properly)
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6658bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
66790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
66800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
66820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6701f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
670347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6704bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
671147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
671847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
672147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType png_write_chunk_from_profile(Image *image,
67284383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
674247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
674347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
674447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
674647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png_profile;
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
675247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
675347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
675447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
675547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
675647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
675747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
675847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            png_profile=CloneStringInfo(profile);
675947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data=GetStringInfoDatum(png_profile),
676047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            length=(png_uint_32) GetStringInfoLength(png_profile);
676147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
676247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
676347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
676447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
676547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
676647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
676747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
676847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            png_profile=DestroyStringInfo(png_profile);
676947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
677147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
677447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6778b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6779b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
6781b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp   const ImageInfo *IMimage_info,Image *IMimage)
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6783b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  Image
6784b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image;
6785b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6786b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  ImageInfo
6787b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image_info;
6788b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6802cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6803cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6804e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6805e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
68065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
680739992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
680839992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
68115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
68125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
68135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
68215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
68225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
68235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6824bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
682858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
682921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
683058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
683158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
6832d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
683339992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
6834991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
6835991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
6836991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
683726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
683826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
683926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
684026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
684126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
684226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
684326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
684426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
684526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
684626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
684726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
6848a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
684926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
685026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
685126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
685226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
68530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
68540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6860bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
6868f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
68690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
68705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
68715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
68725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
68735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
68745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
68755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6876bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
68775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
68785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6880bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6885dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
6886f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
68878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
68888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
68898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
6890dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
6891dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6892dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
6893dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
6894dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
6895dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOnePNGImage()");
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6899b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image = CloneImage(IMimage,0,0,MagickFalse,&IMimage->exception);
6900b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
6901b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6902b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  if (mng_info->need_blob != MagickFalse)
6903b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  {
6904b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) ==
6905b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       MagickFalse)
6906b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    {
6907b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
6908b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
6909b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      return(MagickFalse);
6910b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    }
6911b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  }
6912b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6914f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
69180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
69195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
69205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
69215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
69225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
69235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
69245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
69265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
69275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
69285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
69295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
69305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
69325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
69335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
69345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
69355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6936dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
6937dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
6938dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
6939dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6940d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
694139992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
6942991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
6943991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
6944991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
6945991d11dd9c33e65872778b81aff1347cd2878154glennrp
69460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
69470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
69480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_EXIF=mng_info->ping_exclude_EXIF; /* hex-encoded EXIF in zTXt */
69490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
69500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
69510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
69520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
69530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
69540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
69550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
69560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
69570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tRNS=mng_info->ping_exclude_tRNS;
69580e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
69590e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
69600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
69610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
69620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
69630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
69648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
69658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
69668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
69678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
69700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69713241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
69723241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
69733241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
69743241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
69753241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
69763241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp     (void) SyncImage(image);
69773241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
6978a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
6979a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
6980a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
6981a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
6982a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6983a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
6984a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
6985a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
6986a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
6987a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
6988a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
6989a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
69902b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
69912b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
69922b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
69932b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
69942b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  if (image->depth > 16)
69952b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
69962b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
69972b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
69988640fb5e9b1094f35f8beab436f81661b8a99448glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
69997e2c405930c984e8ffb49b26efdfe1649bf394d6cristy  if (image->depth == 16 && mng_info->write_png_colortype != 16)
70008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
70018640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
70028640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
70038640fb5e9b1094f35f8beab436f81661b8a99448glennrp
700483c2de583a59e41b57be8036d1cf7392c01d03d7glennrp#ifdef PNG_BUILD_PALETTE
7005d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype < 8 /* all */)
700683c2de583a59e41b57be8036d1cf7392c01d03d7glennrp    {
700783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp      /*
70087ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       * Sometimes we get DirectClass images that have 256 colors or fewer.
7009d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * This code will build a colormap.
70107ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       *
70113241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp       * Also, sometimes we get PseudoClass images with an out-of-date
70123241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp       * colormap.  This code will replace the colormap with a new one.
7013d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * Sometimes we get PseudoClass images that have more than 256 colors.
7014d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * This code will delete the colormap and change the image to
7015d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * DirectClass.
70168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       *
70178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       * Also we gather some information (number of opaque, transparent,
7018d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * and semitransparent pixels, and whether the image has any non-gray
7019d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * pixels) that we might need later. If the user wants to force
7020d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * GrayAlpha or RGBA (colortype 4 or 6) we probably don't need any
7021d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * of that.
70227ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       */
70233c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
70248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     ExceptionInfo
70258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       *exception;
70268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     int
70288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       n;
70298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     PixelPacket
7031d6bf1617e99df0272b231855a933a74e99b6578fglennrp       opaque[260],
7032d6bf1617e99df0272b231855a933a74e99b6578fglennrp       semitransparent[260],
7033d6bf1617e99df0272b231855a933a74e99b6578fglennrp       transparent[260];
70348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     register IndexPacket
70368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       *indexes;
70378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7038d6bf1617e99df0272b231855a933a74e99b6578fglennrp     register const PixelPacket
7039d6bf1617e99df0272b231855a933a74e99b6578fglennrp       *q;
7040d6bf1617e99df0272b231855a933a74e99b6578fglennrp
704103812ae402fb53d548f0e1d7d14720768f803c2dglennrp     if (logging != MagickFalse)
704203812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
704303812ae402fb53d548f0e1d7d14720768f803c2dglennrp           "    Enter BUILD_PALETTE:");
70443c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
70458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     image->colors=GetNumberColors(image,(FILE *) NULL,&image->exception);
7046f09bdedccf9ca10bc002a946227df3367cb58d14glennrp     image_colors=(int) image->colors;
70478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     if (logging != MagickFalse)
70497ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
70507ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image->columns=%.20g",(double) image->columns);
70528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image->rows=%.20g",(double) image->rows);
70548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
705558e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp               "      image->matte=%.20g",(double) image->matte);
70568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image->depth=%.20g",(double) image->depth);
70582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         if (image->colormap != NULL)
70607ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
70617ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      Original colormap:");
70638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "        i    (red,green,blue,opacity)");
70658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           for (i=0; i < (ssize_t) image->colors; i++)
70678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           {
70686185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             if (i < 300 || i >= image->colors - 10)
70696185c5395ac23a4c51586d671ec3e0ba9c126349glennrp               {
70706185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70716185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                     "        %d    (%d,%d,%d,%d)",
70726185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                      (int) i,
70736185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                      (int) image->colormap[i].red,
70746185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                      (int) image->colormap[i].green,
70756185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                      (int) image->colormap[i].blue,
70766185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                      (int) image->colormap[i].opacity);
70776185c5395ac23a4c51586d671ec3e0ba9c126349glennrp               }
70788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           }
70797ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
70802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             "      image->colors=%d",(int) image->colors);
70832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         if (image->colors == 0)
70858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             "        (zero means unknown)");
708783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
708803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
708903812ae402fb53d548f0e1d7d14720768f803c2dglennrp              "      Regenerate the colormap");
709003812ae402fb53d548f0e1d7d14720768f803c2dglennrp       }
70917ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       exception=(&image->exception);
70937ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7094d6bf1617e99df0272b231855a933a74e99b6578fglennrp       ping_have_color=MagickFalse;
7095d6bf1617e99df0272b231855a933a74e99b6578fglennrp       image_colors=0;
7096d6bf1617e99df0272b231855a933a74e99b6578fglennrp
70978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       for (y=0; y < (ssize_t) image->rows; y++)
70988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       {
709998bd891f2d35aeb2086bd36e81ededf2da65e714cristy         q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
71002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
71018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         if (q == (PixelPacket *) NULL)
71028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           break;
71037ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7104d6bf1617e99df0272b231855a933a74e99b6578fglennrp         for (x=0; x < (ssize_t) image->columns; x++)
7105d6bf1617e99df0272b231855a933a74e99b6578fglennrp            {
7106d6bf1617e99df0272b231855a933a74e99b6578fglennrp                if (q->red != q->green || q->red != q->blue)
7107d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  ping_have_color=MagickTrue;
71087ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7109a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                if (q->opacity == OpaqueOpacity)
7110d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  {
7111a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (number_opaque == 0)
7112a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      {
7113a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        opaque[0]=*q;
7114a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        opaque[0].opacity=OpaqueOpacity;
7115a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        number_opaque=1;
7116a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      }
71172cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7118a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    for (i=0; i< (ssize_t) number_opaque; i++)
7119a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      {
7120a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        if (IsColorEqual(opaque+i, (PixelPacket *) q))
7121a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                          break;
7122a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      }
71237ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7124a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (i ==  (ssize_t) number_opaque && number_opaque < 259)
7125a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      {
7126a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        number_opaque++;
7127a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        opaque[i] = *q;
7128a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        opaque[i].opacity = OpaqueOpacity;
7129a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      }
71308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
7131a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                else if (q->opacity == TransparentOpacity)
71326185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
71336185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                    if (number_transparent == 0)
71346185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                      {
7135a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        transparent[0]=*q;
71366185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        ping_trans_color.red=(unsigned short)(q->red);
71376185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        ping_trans_color.green=(unsigned short) (q->green);
71386185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        ping_trans_color.blue=(unsigned short) (q->blue);
71396185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        ping_trans_color.gray=(unsigned short) (q->blue);
71406185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        number_transparent = 1;
71416185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                      }
71426185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7143a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    for (i=0; i< (ssize_t) number_transparent; i++)
7144a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      {
7145a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        if (IsColorEqual(transparent+i, (PixelPacket *) q))
7146a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                          break;
7147a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      }
71486185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7149a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (i ==  (ssize_t) number_transparent &&
7150a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        number_transparent < 259)
7151a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      {
7152a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        number_transparent++;
7153a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        transparent[i] = *q;
7154a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      }
7155a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  }
7156a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                else
71578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
7158a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (number_semitransparent == 0)
7159a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      {
7160a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        semitransparent[0]=*q;
7161a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        number_semitransparent = 1;
7162a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      }
71633c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7164a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    for (i=0; i< (ssize_t) number_semitransparent; i++)
7165a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      {
7166a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        if (IsColorEqual(semitransparent+i,
7167a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                           (PixelPacket *) q) &&
7168a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                           q->opacity == semitransparent[i].opacity)
7169a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                          break;
7170a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      }
71713241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7172a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (i ==  (ssize_t) number_semitransparent &&
7173a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        number_semitransparent < 259)
7174a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      {
7175a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        number_semitransparent++;
7176a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        semitransparent[i] = *q;
7177a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      }
7178d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  }
71798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                q++;
71808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
71818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
71823c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7183a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          image_colors=number_opaque+number_transparent+number_semitransparent;
7184a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
718503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (logging != MagickFalse)
718603812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
71876185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              if (image_colors >= 256)
718803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71896185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                       "      image has more than 256 colors");
71903241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
719103812ae402fb53d548f0e1d7d14720768f803c2dglennrp              else
719203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7193f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                       "      image has %d colors",image_colors);
719403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
71952cc891a179d622dde7bbb8854138851e828bc6eaglennrp
71966185c5395ac23a4c51586d671ec3e0ba9c126349glennrp          if (image_colors < 257)
71976185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            {
7198a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              PixelPacket
7199a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                colormap[260];
7200a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
72016185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            /*
72026185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              Initialize image colormap.
72036185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            */
72042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
72056185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            if (logging != MagickFalse)
72066185c5395ac23a4c51586d671ec3e0ba9c126349glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72076185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                     "      Sort the new colormap");
72083241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
72096185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            /* Sort palette, transparent first */;
72103241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
72116185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            n = 0;
72123241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
72136185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            for (i=0; i<number_transparent; i++)
72146185c5395ac23a4c51586d671ec3e0ba9c126349glennrp               colormap[n++] = transparent[i];
72153241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
72166185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            for (i=0; i<number_semitransparent; i++)
72176185c5395ac23a4c51586d671ec3e0ba9c126349glennrp               colormap[n++] = semitransparent[i];
72186185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
72196185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            for (i=0; i<number_opaque; i++)
72206185c5395ac23a4c51586d671ec3e0ba9c126349glennrp               colormap[n++] = opaque[i];
72216185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
72226185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            if (ping_exclude_bKGD == MagickFalse)
72234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
72246185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                /* Add the background color to the palette, if it
72256185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                 * isn't already there.
72266185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                 */
72276185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                for (i=0; i<number_opaque; i++)
72286185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                {
72296185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   if (IsColorEqual(opaque+i,
72306185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                      &image->background_color))
72316185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   break;
72326185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                }
72336185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
72346185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                if (number_opaque < 257 && i == number_opaque)
72356185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                {
72366185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   opaque[i]=image->background_color;
72376185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   opaque[i].opacity = OpaqueOpacity;
72386185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   number_opaque++;
72396185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                }
72404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
72413241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
72426185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            if ((mng_info->ping_exclude_tRNS == MagickFalse ||
72436185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                (number_transparent == 0 && number_semitransparent == 0)) &&
72446185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                (((mng_info->write_png_colortype-1) ==
72456185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                PNG_COLOR_TYPE_PALETTE) ||
72466185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                (mng_info->write_png_colortype == 0)))
72474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
72486185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                 if (logging != MagickFalse)
72496185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
72506185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                     if (n !=  (ssize_t) image_colors)
72516185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72526185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        "   image_colors (%d) and n (%d)  don't match",
72536185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        image_colors, n);
72544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
72556185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72566185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        "      AcquireImageColormap");
72576185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                    }
7258d6bf1617e99df0272b231855a933a74e99b6578fglennrp
72596185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              image->colors = image_colors;
7260d6bf1617e99df0272b231855a933a74e99b6578fglennrp
72616185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              if (AcquireImageColormap(image,image_colors) ==
72626185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  MagickFalse)
72636185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                 ThrowWriterException(ResourceLimitError,
72646185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                    "MemoryAllocationFailed");
7265d6bf1617e99df0272b231855a933a74e99b6578fglennrp
72666185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              for (i=0; i< (ssize_t) image_colors; i++)
72676185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                 image->colormap[i] = colormap[i];
72683241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
72696185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              if (logging != MagickFalse)
72706185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                {
72716185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72726185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        "      image->colors=%d (%d)",
72736185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        (int) image->colors, image_colors);
72743241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
72756185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72766185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        "      Update the pixel indexes");
727703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
72783241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
72796185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              for (y=0; y < (ssize_t) image->rows; y++)
72806185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
72816185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                q=GetAuthenticPixels(image,0,y,image->columns,1,
72826185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                    exception);
72832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
72846185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                if (q == (PixelPacket *) NULL)
72856185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  break;
72863c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
72876185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                indexes=GetAuthenticIndexQueue(image);
72883c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
72896185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                for (x=0; x < (ssize_t) image->columns; x++)
729003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
72916185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  for (i=0; i< (ssize_t) image_colors; i++)
72926185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
72936185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                    if ((image->matte == MagickFalse ||
72946185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        image->colormap[i].opacity == q->opacity) &&
72956185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                        (IsColorEqual(&image->colormap[i],(PixelPacket *) q)))
72966185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                    {
72976185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                      indexes[x]=(IndexPacket) i;
72986185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                      break;
72996185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                    }
73006185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
73016185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  q++;
730203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
730383c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
73046185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                if (SyncAuthenticPixels(image,exception) == MagickFalse)
73056185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   break;
73066185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
73076185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
730803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         }
73093c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
731003812ae402fb53d548f0e1d7d14720768f803c2dglennrp       if (logging != MagickFalse)
731103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         {
731203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
731303812ae402fb53d548f0e1d7d14720768f803c2dglennrp              "      image->colors=%d", (int) image->colors);
73143c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
731503812ae402fb53d548f0e1d7d14720768f803c2dglennrp           if (image->colormap != NULL)
731603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             {
731703812ae402fb53d548f0e1d7d14720768f803c2dglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
731803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                   "       i     (red,green,blue,opacity)");
73193c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
732003812ae402fb53d548f0e1d7d14720768f803c2dglennrp               for (i=0; i < (ssize_t) image->colors; i++)
732103812ae402fb53d548f0e1d7d14720768f803c2dglennrp               {
73226185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                 if (i < 300 || i >= image->colors - 10)
73236185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
73246185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73256185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                         "       %d     (%d,%d,%d,%d)",
73266185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                          (int) i,
73276185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                          (int) image->colormap[i].red,
73286185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                          (int) image->colormap[i].green,
73296185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                          (int) image->colormap[i].blue,
73306185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                          (int) image->colormap[i].opacity);
73316185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   }
733203812ae402fb53d548f0e1d7d14720768f803c2dglennrp               }
733303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             }
733403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
73356185c5395ac23a4c51586d671ec3e0ba9c126349glennrp            if (logging != MagickFalse)
73366185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
7337a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                if (number_transparent < 257)
7338a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7339a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "      number_transparent     = %d",
7340a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        number_transparent);
7341a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                else
73426185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7343a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7344a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "      number_transparent     > 256");
73456185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7346a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                if (number_opaque < 257)
7347a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7348a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "      number_opaque          = %d",
7349a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        number_opaque);
7350a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                else
7351a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7352a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "      number_opaque          > 256");
7353a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7354a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                if (number_semitransparent < 257)
7355a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7356a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "      number_semitransparent = %d",
7357a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        number_semitransparent);
7358a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                else
7359a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7360a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7361a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "      number_semitransparent > 256");
73626185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              }
73636185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
736403812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
736503812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
736603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         }
736783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp    }
73683c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp#endif /* PNG_BUILD_PALETTE */
73693c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
73700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
73710e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
73720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
73730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      int colortype=mng_info->write_png_colortype;
73740e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
73750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
73760e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
73770e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
73780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
73790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
73800e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
73814383ec8c3c8811128f5a8a034d67c47db5e7e75acristy      if (colortype != 0 && mng_info->write_png_colortype != (ssize_t) colortype)
73820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
73830b206f5daa453dc1035db5890cabc899736dc2d0glennrp
73840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
73850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
73863c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
73873c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
73883c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
73893c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
7390f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
73913c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
739283c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
73930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
73948eb57274a813fc3f2e2f96b166eb569f5e17aa26glennrp    image_colors <= 256;
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
74030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
74070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
74110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
74130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
74223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
74303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
74313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
74333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7434f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
74353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7436b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      if (mng_info->need_blob != MagickFalse)
7437b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
7438b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
7439b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
74482b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
74532b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74562b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
74573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
74582b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
74594e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
74604e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
74612b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
74623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
74633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
74640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
74670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
74693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
74703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
74710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
74740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
74770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
74793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7481e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
74823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7483e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
74843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7485e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
74863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74878640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
74883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74898640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
74903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74918640fb5e9b1094f35f8beab436f81661b8a99448glennrp
74923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
74935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
7494dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
749526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
74963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
749726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
749826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
74993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
75003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
75013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
7503dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7504dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
75073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7508dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
7509dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
7510dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
75113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7512dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
75143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7515dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
7516dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution);
7517dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution);
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7519991d11dd9c33e65872778b81aff1347cd2878154glennrp
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7522dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
7523dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) image->x_resolution;
7524dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) image->y_resolution;
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7526991d11dd9c33e65872778b81aff1347cd2878154glennrp
7527991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
752926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7531a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
753226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
753326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
7534a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7536a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
7537a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
7538a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
7539a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
7540a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
7541a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
75420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7543a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
7544a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
75450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7546a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
7547a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
75480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7549a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
7550a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
75510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7552a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
7553a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
75540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7555a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
7556a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
75570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7558a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
7559a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
75600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
75610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
75633b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
75643b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75653b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
75663b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
75673b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75683b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
75693b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
75700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
757226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
75790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /* TO DO: make this a function cause it's used twice, except
75840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
75850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
75878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
75888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
75890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
75910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
75920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
75930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
75940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
75960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
7598f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
75990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
76010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
76020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
76030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
76040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
76050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
76060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
76080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
76100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %5ld (%5d,%5d,%5d)",
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
76152b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
76168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
76178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
76188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
76195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
762058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
76218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
76220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
76230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
76240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
76250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
76268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
76298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
76300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          /* PNG8 can't have semitransparent colors so we threshold them
76328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           * to 0 or 255
76338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           */
76348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (; i < (ssize_t) number_semitransparent; i++)
76358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=image->colormap[i].opacity >
76368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                OpaqueOpacity/2 ? 0 : 255;
76370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76382cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
76398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
76400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
76420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
76430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
76458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
76468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
76470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp    if (ping_exclude_bKGD == MagickFalse)
76494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
76504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        /*
76514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         * Identify which colormap entry is the background color.
76524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         */
76534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
76544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
76554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
76560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
76584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
76600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
76645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
76705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
76760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
76783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
76800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
76825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
76842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
76858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
76868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      else /* write_ping_colortype not specified */
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76933c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
76940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7695d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
76968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
76970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7698d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
77013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
77030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7704d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
77090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77105aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
77115aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
77125aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
77135aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
77145f1c1fff2a55c4d8756556e78c1f307d352ed1b8cristy          if (image_info->type == UndefinedType ||
77158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             image_info->type == OptimizeType)
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77175aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
77188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
77195aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
77205aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
77215aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
77225aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
77235aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
77240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77250b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
77265aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
77275aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
77285aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
77295aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
77308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
77315aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
77325aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
77335aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
77345aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
77355aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
77365aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
77375aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
77388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
77390b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
77405aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
77415aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
77425aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
77435aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
77445aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
77450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
77465aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
77473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
775026c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77518640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
775226c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
77535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
77540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
77550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
77560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
77570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
77580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
77590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7761d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
7762d6bf1617e99df0272b231855a933a74e99b6578fglennrp
77635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->matte == MagickFalse && image->colors < 256)
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ImageIsMonochrome(image))
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
77695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth=1;
77703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
77713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
77723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77738640fb5e9b1094f35f8beab436f81661b8a99448glennrp
77745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
77753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
777635ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
77775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
77780f111984738842d27d04aed2a3f823d82a943506glennrp
77790f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
77800f111984738842d27d04aed2a3f823d82a943506glennrp           {
77810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
77820f111984738842d27d04aed2a3f823d82a943506glennrp              (void) ThrowMagickException(&image->exception,
77830f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
77840f111984738842d27d04aed2a3f823d82a943506glennrp                "image has 0 colors", "`%s'","");
77850f111984738842d27d04aed2a3f823d82a943506glennrp           }
77860f111984738842d27d04aed2a3f823d82a943506glennrp
778735ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
77885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
7789d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
77903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7791d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
7792d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
7793d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7794d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
77950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7796d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7797d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
7798d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
77990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7800d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
7801d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
78023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
78032cc891a179d622dde7bbb8854138851e828bc6eaglennrp
78045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
78052b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
78063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
78073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
78083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7809e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
78100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7812e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
78130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7815e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
78160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78183c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
78198640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
78208640fb5e9b1094f35f8beab436f81661b8a99448glennrp
78218640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7822e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
78233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
78243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
782558e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
78263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
78274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
78284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
78293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
78312b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
78324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_color != MagickFalse)
78334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             ping_color_type=PNG_COLOR_TYPE_RGBA;
78342b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
78364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
78373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
78384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
78394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
78404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
78414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
78424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
7843a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
78444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
78454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_color_type&=0x03;
78464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
78470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
78494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
78504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
78514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                mask;
78523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
78540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
78564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
78570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
78594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
78600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
78624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
78630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
78654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
78660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
78684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
78690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
78714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
78720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
78744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
78750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
78774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(PixelIntensityToQuantum(
78784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
78790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
78810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
78834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
78840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
78864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
78874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
78884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                Determine if there is one and only one transparent color
78894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                and if so if it is fully transparent.
78904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
78914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (logging != MagickFalse)
78924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    "  Is there a single fully transparent color?");
78948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
78954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (number_transparent > 1 || number_semitransparent > 0)
78964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
78974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                ping_have_tRNS = MagickFalse;
78984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
78994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    "  ... No.");
79014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
79024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              else
79034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
79044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
79054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    "  ... Yes: (%d,%d,%d), (gray: %d)",
79074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (int) ping_trans_color.red,
79084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (int) ping_trans_color.green,
79094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (int) ping_trans_color.blue,
79104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (int) ping_trans_color.gray);
79114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
79124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
79132b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
79154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
79164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
79170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
79194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
79204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
79214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
79224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
79234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
79244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
79254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
79264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
79274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
79284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
79293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
79315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
79325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
79335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
79345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
79363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
79373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79388640fb5e9b1094f35f8beab436f81661b8a99448glennrp
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
79400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79412e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
79423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
79430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
794439992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
79453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
794658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp        ImageIsGray(image) && (image_matte == MagickFalse || image_depth >= 8))
79473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
794835ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
79490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
79519c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
79520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
79543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
79564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
79573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
79584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
79594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
79604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
79614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
79634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
79644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
79654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
79663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
79670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
79693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
79700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
7972f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
79730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
79755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
79760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
79783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
79805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
79813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
79823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
79833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
79845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
79850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
798635ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
7987bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
79885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
79893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
79903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79912b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
79930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
79943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
79953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
79963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
79983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
79993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
80003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
80013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
80023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8003bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
80043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
80053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
80063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
80073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
80093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
80113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
80120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
80150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
80173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
80183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
80192b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
80203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
80219c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
80220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
80249c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
80250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
80279c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
80283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
80293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
80302b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
80315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
80323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
80330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
80350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
80373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
803817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
803917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
80403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
80413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
80423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
80433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
80443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
80455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
80460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
804758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (mng_info->have_write_global_plte && matte == MagickFalse)
80483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
80499c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
80500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80513b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
80529c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80539c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
80543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
80550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
80573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8058bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
80593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
80603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
80613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
80623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
80633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
80640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80653b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
80663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
806798156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
8068f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
80690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
807039992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
80713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
80720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
8074d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
80753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8076befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
8077befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
8078befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
80795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
8080befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
80810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8082befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
80835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
80843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
80850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
80870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
808858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
80890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
80900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
8091d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
8092d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
80930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
80943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8095d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
8096d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
80973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
80990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
81000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8101d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
81020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
8103c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
8104c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
8105c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8106c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
8107c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
8108d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
8109d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8110d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
8111d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
8112d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       ping_trans_alpha[i]= (png_byte) (255-
8113d6bf1617e99df0272b231855a933a74e99b6578fglennrp                          ScaleQuantumToChar(image->colormap[i].opacity));
8114d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
81150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
81160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
81173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
81183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
81190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8122c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
81243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
81250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
81273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
81284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
81294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
81304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
81324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
81334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
81344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
81354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
81364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
81375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
81385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
81395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
81405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
81414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
81424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
81434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
81444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
81464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
81474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
81484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
81494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81534383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
81544383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
81552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
81583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
81595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
81613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
81643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
816535ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
816635ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
816735ef824baa82511126ff0072ae30eee0da9c05a3cristy
816822ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
81693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
817126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
81723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8173a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
81743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
81753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
81773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81783c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Setting up bKGD chunk (2)");
81793b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
8180991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
818126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
81845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
81853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
818617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
818726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
818826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
818917a1485544c62993fc7a94e343c87fed5f3e6407glennrp    if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
819017a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
819117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
819217a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
819317a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
819417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
819517a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
819617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8197a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
8198a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
819917a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
820017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
820117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
820217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
82033b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
82040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
82050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
82070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
8208a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
820913d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
8210a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
82110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
82123b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
82133b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
82140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
82150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
82170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
82180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
82190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
82200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
8221a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
822217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8223d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
82243c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
82253b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
82263b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82273b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
82283c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
82293c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
823017a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
823126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
823217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
82363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
82383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
82393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
82410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
82430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
82460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
82470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
82490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
82530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
82550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
82573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
82580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
82603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
82623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
82633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8264bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
82650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
82690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
82713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
82743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
82780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
82803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
82853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82862b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
82893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
82930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
82953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
82983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
82993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
83013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
83022b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
83043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
83053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
83063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
83088640fb5e9b1094f35f8beab436f81661b8a99448glennrp      base_filter=PNG_ALL_FILTERS;
83090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83108640fb5e9b1094f35f8beab436f81661b8a99448glennrp    else
83118640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if ((quality % 10) != 5)
83123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
83130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83148640fb5e9b1094f35f8beab436f81661b8a99448glennrp      else
83158640fb5e9b1094f35f8beab436f81661b8a99448glennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
83165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
83173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
83188640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_NO_FILTERS;
83190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83208640fb5e9b1094f35f8beab436f81661b8a99448glennrp        else
83218640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_ALL_FILTERS;
83220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
83243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
83253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
83263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
83283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
83293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
83313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
83322b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
83343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
83353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8336c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  if (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse)
8337c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
8338c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
8339c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8341c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
83420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8343c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
8344c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
8345c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
8346c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
8347c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
834826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
8349c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
8350c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
8351c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
8352c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                       png_set_iCCP(ping,ping_info,(const png_charp) name,0,
8353e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
8354c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
8355e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
8356e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
8357e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
8358c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
8359c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
836026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
83610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8362c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
83633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8364c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
8365c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
8366c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  png_write_raw_profile(image_info,ping,ping_info,
8367c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
8368c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
8369c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
8370c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
8371c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
83720b206f5daa453dc1035db5890cabc899736dc2d0glennrp
8373c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
8374c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8375c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
83760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8377c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
8378c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
83803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
83823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
83833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
83843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
838626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
838726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
838826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
838926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
839026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
839126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
839226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
839326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
83940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
839526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
839626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            PNG_RenderingIntent_from_Magick_RenderingIntent(
839726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            image->rendering_intent)));
83980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
839926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_gAMA == MagickFalse)
840026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            png_set_gAMA(ping,ping_info,0.45455);
840126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
84023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
840326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
84045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
84053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
84063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84072cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
84082cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
840926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
841026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
84113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
84123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
84143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
84153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
84163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
84173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
84183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
84203b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
84213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
84223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
842326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
84242b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
842526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
84263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
842726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
842826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
842926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
843026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
843126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
843226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
843326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
843426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
843526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
843626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
843726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
843826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
843926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
844026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
844126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
844226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
844326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
844426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
844526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
844626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
844726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
844826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
844926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
845026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
845126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
845226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
84533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8454dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
84555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
84563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
84583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
84593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
84613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8462d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
84633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
84653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
84663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
84675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
84682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
84695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
84705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
84713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
84720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
84743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
84755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
84763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
84790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
84805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
84813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
84825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
8483991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
84840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
84853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
84873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
84890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
84900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
84920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
84930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
84943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
84953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
84983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
84995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
85003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
85010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
85023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
85033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
85043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
85063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
85075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
85083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
85093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
85100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
85113bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
85123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
85133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
851558e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (image_matte != MagickFalse && image->matte == MagickFalse)
85163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
85183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
85193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
85200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8521b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
8522b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8523b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
85243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8526991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (image->matte == MagickTrue)
8527e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
8528991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
8529991d11dd9c33e65872778b81aff1347cd2878154glennrp        if (ping_color_type != 3 || ping_num_trans > 0)
8530c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
8531991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
8532c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
8533c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8534c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
8535c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
8536e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
8537e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
85383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
85413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
85435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
85445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
85455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
85465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
854739992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
854839992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
8549f09bdedccf9ca10bc002a946227df3367cb58d14glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
85500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85513b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
855239992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
85538640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
85540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
8555d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
85560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8557d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
8558d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
85590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
85600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
85610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
8562d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
85630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
85640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
85650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8566d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
85670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
85680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
85690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
85700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
85710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
857239992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
857339992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
857439992b4dd9b12ef752d55b8e402c069698851f72glennrp
857526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
857626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
857726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
857826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
857926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
8580991d11dd9c33e65872778b81aff1347cd2878154glennrp
858126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
8582dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
858326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
858426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
858526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
858626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
858726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
858826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
858926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
8590dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
8591dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8592dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
85934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
8594dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
859526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
859626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
859726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
859826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
8599dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
860026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
860126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
860226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
860326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
860426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
8605dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
8606dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
8607dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
86083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
8609991d11dd9c33e65872778b81aff1347cd2878154glennrp
861039992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
8611991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
86123b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
86130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
86140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
86160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
8617991d11dd9c33e65872778b81aff1347cd2878154glennrp
86180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
86190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
86200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
86210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
86220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
8623991d11dd9c33e65872778b81aff1347cd2878154glennrp
86240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
86250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
86260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
86270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
86280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
86290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
86300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86313b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
86320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
86330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8634c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
86350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
86360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
86370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
86380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
86390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
86400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
8641991d11dd9c33e65872778b81aff1347cd2878154glennrp
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
86434383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
8645991d11dd9c33e65872778b81aff1347cd2878154glennrp
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
86474383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
86483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
864926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
86524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
865326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
865426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
865526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
865626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
865726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
865826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
865903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
866026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
866126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
866226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
866326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
866426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
866526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
86663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
86699c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
86703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
86719c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
86723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
8680b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
8681b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
86827202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
86833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8684b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
8686b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8688b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
8689b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
8690b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8692b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
8694b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8696b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
8697b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86993b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
87003b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8702b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8703b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
87040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8705b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8706e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*png_pixels));
87100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
87130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
87175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
87183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
87203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
87213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
87223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
87233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
87243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
87263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
87273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
87283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
87293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
87303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8732f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8734b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      if (mng_info->need_blob != MagickFalse)
8735b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
8736b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
8737b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
87383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8740ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
8741ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
8742ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
87433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
87443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
87468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
87488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
87498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
87503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
875158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp       image_matte == MagickFalse && ImageIsMonochrome(image))
87523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
87543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
87560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
87583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
87593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
87603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
87613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
87623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
8763bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
87643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8765a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
87663241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp          if (logging != MagickFalse)
87673b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87683b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
8769a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
87703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
87710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
87733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
87740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
87773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
87793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
87803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
87813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
87823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
87833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
8784bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
87853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
87863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
87883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RedQuantum,png_pixels,&image->exception);
87943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
8797bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
87983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
87993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
88000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88013b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
8802b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8803b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
88040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
88063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
88073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
88083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
88123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
88173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
88193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
882058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp         (image_matte != MagickFalse ||
88215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
882239992b4dd9b12ef752d55b8e402c069698851f72glennrp         (mng_info->IsPalette) && ImageIsGray(image))
88233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
88248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
88258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
88260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8830bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
88313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
88332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
88353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
88362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
88383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
88398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
88403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,GrayQuantum,png_pixels,&image->exception);
88422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
88443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,RedQuantum,png_pixels,&image->exception);
88462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
88488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
88503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
88512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
8853b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
88543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
8855b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
88572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
8860b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
88612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88623b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
8863b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
88652cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
88673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
88708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
88718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
88728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
88738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
88748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
88758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
88768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
88770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
88793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
88808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
88818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
88820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
88843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
88868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
88878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
88888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
88898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
8890b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
88918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
88928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   &image->exception);
88932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
88958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
88962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
88988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
88998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
89008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
89018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        quantum_info,RedQuantum,png_pixels,&image->exception);
89022cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
89048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
89058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        quantum_info,GrayQuantum,png_pixels,&image->exception);
89068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
89072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
89098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
89108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
89118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      quantum_info,GrayAlphaQuantum,png_pixels,
89128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      &image->exception);
89132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
89158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
89178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
89182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
89208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
89218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,RGBAQuantum,png_pixels,&image->exception);
89222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
89248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
89258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,RGBQuantum,png_pixels,&image->exception);
89262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89273b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
8928b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
89302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                png_write_row(ping,png_pixels);
8932b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
89338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
89342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
89368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
89378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
89388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
89398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
89408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
89418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
89428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
89438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
89448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
89462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
89488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
89498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
89502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
89528640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
89538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
89548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
89562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
89582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
89608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
89612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
89638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
8964d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       quantum_info,GrayQuantum,png_pixels,&image->exception);
89652cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
89678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
89688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
89698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
89712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
8973d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         quantum_info,GrayAlphaQuantum,png_pixels,
8974d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         &image->exception);
89758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
89762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
89788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
89798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,IndexQuantum,png_pixels,&image->exception);
89802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse && y <= 2)
89828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
89838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        "  Writing row of pixels (4)");
89852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        "  png_pixels[0]=%d,png_pixels[1]=%d",
89888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        (int)png_pixels[0],(int)png_pixels[1]);
89898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
89908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                png_write_row(ping,png_pixels);
89918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
89928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
89932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
89958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
89968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
89978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
89988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
89998640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
90028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
90038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9004b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
9005b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9010b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
90110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9013e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
90140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9016e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
90170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
90230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
90260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
90320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
90350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
904226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_tEXt == MagickFalse && ping_exclude_zTXt == MagickFalse)
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
904426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
904526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
904626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
904726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
904826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
904926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
90502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
905126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      value=GetImageProperty(image,property);
905226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (value != (const char *) NULL)
905326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
905426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
905526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].key=(char *) property;
905626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].text=(char *) value;
905726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].text_length=strlen(value);
90582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
905926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_tEXt != MagickFalse)
90604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
90612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
906226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          else if (ping_exclude_zTXt != MagickFalse)
90634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             text[0].compression=PNG_TEXT_COMPRESSION_NONE;
90642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
906526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          else
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
90674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             text[0].compression=image_info->compression == NoCompression ||
90684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               (image_info->compression == UndefinedCompression &&
90694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
90704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               PNG_TEXT_COMPRESSION_zTXt ;
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
90722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
907326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
907426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
907526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
907626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up text chunk");
90772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
907826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
907926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "    keyword: %s",text[0].key);
908026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
90812cc891a179d622dde7bbb8854138851e828bc6eaglennrp
908226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_text(ping,ping_info,text,1);
908326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_free(ping,text);
908426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
908526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
908626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
90904383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
90950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
90970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
91015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
91025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
911203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
91235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
91265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
91320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
91373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
91403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
91410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
91455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
91463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
91473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
91493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9151f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9154b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  if (mng_info->need_blob != MagickFalse)
9155b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp     (void) CloseBlob(image);
9156b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9157b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=DestroyImageInfo(image_info);
9158b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image=DestroyImage(image);
9159b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9160b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
9161b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
9162b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
9163b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9164b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  (void) SetImageProperty(IMimage,"png:bit-depth-written",s);
9165b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
91663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
91690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
91723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
91873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
91953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
92013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
92053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparent).  The pixels contain 8-bit indices even if
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               they could be represented with 1, 2, or 4 bits. Note: grayscale
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
92143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               PNG grayscale type might be slightly more efficient.
92153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
92173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
92183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               one of the colors as transparent.
92193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
92213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
92223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
92230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
92243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
92263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
92273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
9228bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
9229bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
9230bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
92353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
92363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
92383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
92393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
92413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
92423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
92433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
92443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
92463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
92473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  If the image cannot be written without loss in the requested PNG8, PNG24,
92493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or PNG32 format or with the requested bit-depth and color-type without loss,
92503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a PNG file will not be written, and the encoder will return MagickFalse.
92513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
92523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
92533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
92543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transparency prior to attempting to write the image in a format that
92553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is subject to depth, color, or transparency limitations.
92563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
92583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
92613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
92623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
92643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
92653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
92663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
92673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
92693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
92713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
9272bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
9273bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
92743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
92763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
9278bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
92793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9280bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
92813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92823241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
92830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
9284d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
92850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
92860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
92870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
92883241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%      transparent color first, if PNG_BUILD_PALETTE is defined.
92890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
9290d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
9291d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
9292d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      requested via the "-define PNG:bit-depth=N" option.
9293d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
9294d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
9295d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
9296d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
92970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
93003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
93013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
93023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
930421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
930521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
930621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
93073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
93133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
931621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
93175c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
93185c7cf4e469a4dad7e277783749155932252c52dfglennrp
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
93273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
93283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
933273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
93330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
9342a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
93493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93539c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
93549c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
93559c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93609c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
93619c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
93629c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
93630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93649c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
93659c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
93660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93679c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
93689c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
93690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93709c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93759c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
93769c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
93779c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
93780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93799c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
93809c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
93810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93829c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
93839c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
93840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93859c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
93898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
93939c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
93940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
93969c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
93970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
93999c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
94000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
94029c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
94030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
94059c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
94060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9407bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
9408bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
9409bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
9410bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
9411bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
9412bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
94149c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9415bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
94190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
94249c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
94250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
94279c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
94280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
94309c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
94310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
94339c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
94340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
94369c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
94370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9438bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
9439bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
9440bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
9441bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
9442bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
9443bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
94459c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9446d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
94500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The default is to not exclude any chunks except for any
94520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
94530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Chunks can be listed for exclusion via a "PNG:exclude-chunk"
94550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
94560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
94570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
94580e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
94590e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
94610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * A "PNG:include-chunk" define takes  priority over both the
94630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * mng_info and the "PNG:exclude-chunk" define.  Like the
94640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
94650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * well as a comma-separated list.
94660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
94680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
94690e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
94700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94710e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
94720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
94730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
94740e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
94760e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
94770e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
94790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * artifact to "none,gama".
94800e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
94810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
948226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
948326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
948426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
948526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
948626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
948726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
948826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
948926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
949026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
949126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
949226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
9493a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
949426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
949526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
949626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
949726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
949803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
949903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
95005c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
95015c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
95025c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
9503acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
95045c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
9505acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
9506acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9507acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
9508acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
95095c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
9510acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
95115c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
951226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9513acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9514acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
9515acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
9516acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
951703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
951803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
951926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
952003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
952103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
952226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
952303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
952426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
952503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
95262cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
95272cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
95282cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95292cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
95302cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
95312cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95322cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
95332cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
953403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
953503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
953603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
953703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
953803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
953903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
954003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
954103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
954203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
954303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
954403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
954503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
954603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
954703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
954803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
954903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
955003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
955103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
9552a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
955303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
955403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
955503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
955603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
955703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
95582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
955903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
956003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
956103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
956203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
956303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
956403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
956503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
956603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
956703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
956803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
956903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
957003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
9571a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
957203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
957303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
957403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
957503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
95762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
957703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
957803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
95792cc891a179d622dde7bbb8854138851e828bc6eaglennrp
958003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
958103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
95822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
958303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
958403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
95852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
958603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
958703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
95882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
958903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
959003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
95912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
959203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
959303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
959403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
959503812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
95962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
959703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
959803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
95992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
960003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
960103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
96022cc891a179d622dde7bbb8854138851e828bc6eaglennrp
960303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
960403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
96052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9606a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
9607a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
96082cc891a179d622dde7bbb8854138851e828bc6eaglennrp
960903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
961003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
96112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9612a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
9613a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
9614a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
961503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
961603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
96172cc891a179d622dde7bbb8854138851e828bc6eaglennrp
961803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
961903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
96202cc891a179d622dde7bbb8854138851e828bc6eaglennrp
962103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
962203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
96232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
962403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
9625ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
962626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
962726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
96285c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
96295c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
96305c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
9631acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
96325c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
9633acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
9634acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9635acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
9636acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
96375c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
9638acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
96395c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
964026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9641acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9642acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
9643acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
9644acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
964503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
964603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
964703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
964803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
964926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
965003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
965126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
965203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
96532cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
96542cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
96552cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96562cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
96572cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
96582cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96592cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
96602cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
966103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
966203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
966303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
966403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
966503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
966603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
966703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
966803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
966903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
967003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
967103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
967203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
967303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
967403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
967503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
967603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
967703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
9678a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
967903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
968003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
968103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
968203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
968303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
96842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
968503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
968603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
968703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
968803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
968903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
969003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
969103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
969203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
969303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
969403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
969503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
969603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
9697a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
969803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
969903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
970003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
970103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
97022cc891a179d622dde7bbb8854138851e828bc6eaglennrp
970303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
970403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
97052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
970603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
970703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
97082cc891a179d622dde7bbb8854138851e828bc6eaglennrp
970903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
971003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
97112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
971203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
971303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
97142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
971503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
971603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
97172cc891a179d622dde7bbb8854138851e828bc6eaglennrp
971803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
971903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
972003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
972103812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
97222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
972303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
972403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
97252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
972603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
972703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
97282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
972903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
973003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
97312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9732a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
9733a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
97342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
973503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
973603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
97372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9738a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
9739a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
9740a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
974103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
974203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
97432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
974403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
974503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
97462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
974703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
974803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
97492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
975003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
9751ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
975226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
975326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
975403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
975526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
975626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
975726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      "  Chunks to be excluded from the output PNG:");
975826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
975926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
976026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
976126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
976226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
976326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
976426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
976526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
976626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
976726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
976826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
976926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
977026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
977126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
977226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
977326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
977426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
977526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
977626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
977726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
977826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
977926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
978026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
978126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
978226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
978326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
978426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
978526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
978626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
978726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
978826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
978926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
9790a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
9791a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9792a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
979326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
979426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
979526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
979626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
979726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
979826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
979926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
980026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
980126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
980226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
980326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9804b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
98053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9806b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  status=WriteOnePNGImage(mng_info,image_info,image);
98073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
98090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
98120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
98143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
98153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
98173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
98193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
98203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
98213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
98223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
98233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
98243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
98263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
98273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
982903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
98303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
98313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
98333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
98343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
98363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
98373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
98383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
98393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
98413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
98423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
98433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
98443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
98453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9846bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
98473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
98483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
98503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOneJNGImage()");
98513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
98533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
98543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
98553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
98573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
98583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
98593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
98603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
98613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
98623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
98653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
98683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
98693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
98733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
98750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
98773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
98783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
98800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
98820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
98850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
98873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
98890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
98910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
98933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
98940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
98963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
98983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
98990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
99013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
99020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
99050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
99073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
99083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
99093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
99103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
99113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
99143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
99163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
99173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
99183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
99193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
99213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
99233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
99243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
99263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
99283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
99293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
99303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
99313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
99333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
99343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
99363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
99373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
99403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
99413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
99453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
99463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
99503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
99533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
99553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
99563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
99573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
99583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
9961f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
99623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
99630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9966e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
9967e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
99683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
99703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
99733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
99773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
997903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
99804e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
99814e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
99833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
99843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
99853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
99863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
99883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
99903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
99913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
99923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
99933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9995f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
99960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9998f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
99990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
100020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
100050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
100080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
100110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
100140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
100170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
100200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
100233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
100264383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
100273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
100303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
100333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
100343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
100353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
100363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
100373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
100393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
100403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
100413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
100423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10043bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
100443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
100453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
100473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
100483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
100493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
10050bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
100513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1005203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
100533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
100543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
100553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
100563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
100583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
100593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
100613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
100623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
100633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
100653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
100673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
100693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
100703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
100713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
100723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1007303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
100740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
10076e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10077e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
10078e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
100790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
10081e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10082e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
10083e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
100840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
100863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
100873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
100893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
100913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
100923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
100933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
100943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
100953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
100963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1009703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1009835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
101003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
101013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
101020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
101043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
101053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
101063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
101073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
101083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
101103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
101113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
101123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
101133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1011403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
101153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1011635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1011735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
101183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1011935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1012035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
101213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1012235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1012335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
101243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1012535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1012635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
101273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
101283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
101303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
101333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
101353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
101363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
101373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
101383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1013903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
101403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
101413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1014235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
101433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
101440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1014535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
101463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
101470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
101493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
101500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
101523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
101533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
101543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1015535ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
101570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1015835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
101593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
101600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
101623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
101630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
101653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1016635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1016735ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
101683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
101693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
101703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
101713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
101723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
101733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
101763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
101783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
101793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
101803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
101813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1018203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
10183bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
10184bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
101853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
101863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
101873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
101883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
101923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1019303812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
101943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
101953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
101963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
101973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
101983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
101993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
102033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
102053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10206bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
102073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
102083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10209bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
102103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
102113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
102133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
102143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10215e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
10216f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
102173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
102193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
102203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
10221bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
102223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
102233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
102243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
102250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
102273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
102283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
10229bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1023003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
102313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
102323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
102333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
102343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
102350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
102373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
102383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
102393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10240e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
10241e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
102423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
102433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
102443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
102453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
102463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
102473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
102483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
102493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
102503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10251e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
10252bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
102533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1025403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
102553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
102563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
102573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
102583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
102593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
102603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
102613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
102623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
102653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
102683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
102693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
102703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
102713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
102753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
102773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
102783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
102793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
102803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
102823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
102833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
102843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
102863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
102873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10290e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
10291e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
102923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
102943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
102950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
102973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
102983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
102990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
103013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
103030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
103050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
103073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10309e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
10310e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
103113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10313e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
103143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
103150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
10317bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
103183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1031903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
103203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
103213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
103223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
103233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
103253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
103263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
103273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
103283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
103304383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
103313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
103333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
103343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1033503812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
103363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
103373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
103383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
103403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
103420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
103443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
103453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
103483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
103503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
103513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
103523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
103533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
103543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
103553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
103563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
103593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
103613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
103633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
103653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
103673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
103693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
103713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
103743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
103753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
103763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1037721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1037803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
103793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
103803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
103823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
103833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
103853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
103863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
103873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
103883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
103893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
103903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
103913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
103923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
103933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
103943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
103953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
103963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
103983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
103993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
104003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1040173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
104023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
104033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
104043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
104063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
104073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
104083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
104093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
104103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
104123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
104143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
104153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
104173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
104183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
104193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
104203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
104213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
104223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
104233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
104273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
104283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
104293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
104303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
104323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
104333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1043521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
104363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
104373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1043803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1043903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1044003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
104413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
104423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
104433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
104453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
104463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
104473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
104483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
104503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
104513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
104523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
104533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
104543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
104553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
104563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
104573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10458bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
104593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
104603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
104623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
104633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
104653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
104663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
104673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10468bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
104693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
104703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10471bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
104723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
104733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
104743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10475d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
104763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
104773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
104783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
104793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
104803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
104833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
104843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
104853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
104863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
104873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
104883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
104893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
104903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
104913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
104923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
104933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
104963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
104973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1049873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
104993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
105003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
105013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
105023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
105033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
105043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
105053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
105063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
105073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
105083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
105103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
105113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
105123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
105133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
105143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
105153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
105163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
105173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
105183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
105193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
105213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
105223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
105233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
105253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
105263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
105273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
105293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
105303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
105323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
105343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
105353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
105363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
105390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10541e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
105420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
105453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
105473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
105483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
105493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10550e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
105510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10553e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
105540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
105563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
105580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
105603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
105620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
105643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
105660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
105700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
105723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10573e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
105740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
105763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
105780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
105803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
105823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
105833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
105853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
105873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
105883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
105893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
105903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
105913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
105923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
105953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
105963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
105983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
105993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
106003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
106013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
106023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
106033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
106043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
106053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
106083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
106103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
106113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
106123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
106153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
106183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
106193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
106203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
106223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
106233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
106253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
106283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
106303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
106323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
106333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
106353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
106363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
106383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
106393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
106403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
106410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
106433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
106443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
106450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
106473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
106480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
106503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
106510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
106533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
106543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
106553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
106563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
106570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
106593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
106600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
106620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
106643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
106653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
106660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
106683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
106693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
106703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
106713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
106723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
106733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
106740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
106763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
106773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
106783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
106793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
106803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
106813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
106823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
106833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
106843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
106853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
106863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
106873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
106883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
106893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
106903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
106913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
106923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
106933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
106940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
106963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
106970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
106993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
107010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
107043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
107053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
107060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
107083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
107103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
107113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
107123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
107133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
107143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
107153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
107163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
107173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
107183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
107213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
107233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
107243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
107283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
107293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
107303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
107323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
107333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
107353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
107363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
107383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
107463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
107523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
107563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
107573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
107580261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
10759d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
10760d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
10761d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
10762d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
10763d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
10764d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
10765d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
107714e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->ticks_per_second=(png_uint_32) (image->ticks_per_second/final_delay);
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
107740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
107770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
107800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
107833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
107843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
107853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
107870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
107893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
107933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
107963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
107983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1080103812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
108024e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
108034e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
108043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
108073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
108083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
108103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
108113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
108140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
108163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
108180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
108223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
108230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
108253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
108263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
108280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
108323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
108343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
108350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
108373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
108390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
108413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
108423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
108440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
108483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
108493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
108513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
108553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
108563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
108603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
10862bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1086303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
108693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
108753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1087703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
108783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
108793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
108820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
108850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
108880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10892e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
10893e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
108940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
108963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10897e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
108980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10901e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
109023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
109033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
109043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
109053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
109063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
109073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
109083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
109093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
109103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
109113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
109123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
109133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
109143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
109163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1091703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
109180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
10920e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
10921e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
10922e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
109230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
10925e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
10926e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
10927e610a071534e448c46460a5aa39ede33bf56b329glennrp             (PerceptualIntent));
109280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
109303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
109313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
109323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
109330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
109353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
109393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
109403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
109413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
109423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1094303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1094435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
109453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
109463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
109473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
109503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
109513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
109533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
109573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
109583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1095903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
109603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1096135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1096235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1096435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1096535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
109663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1096735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1096835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
109693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1097035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1097135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
109723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
109733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
109743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
109753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
109763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
109773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
109783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
109793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
109803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
109813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
109823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
109833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1098403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
109850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
109873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1098835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
109893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
109900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1099135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
109923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
109930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
109953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
109960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
109983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
109993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
110003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1100135ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
110023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
110030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1100435ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
110053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
110060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
110083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
110090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
110113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1101235ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1101335ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
110143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
110153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
110183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
110193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
110203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
110233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
110253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
110263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
110273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
110283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
110293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
110303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
110313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1103203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
110333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
110343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
110353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
110363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
110383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
110393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
110403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
110413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
110423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
110433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
110443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1104503812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
110463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
110473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
110483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
110493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
110503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
110523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
110533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
110543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
110553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
11056bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
110573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
110583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
110603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
110613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
110623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
110633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
110643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1106503812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
110660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11067bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
110683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
110693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
110703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
110713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
110723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
110730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
110753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
110763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
110773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
110783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
110793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
110813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
110833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
110843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
110853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
110873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
110883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
110893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
110923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
110933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
110943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
110953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
110963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
111023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
111053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
11111bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
111123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
111153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1111703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
111180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11119bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
111213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
111233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
111243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
111250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
111273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
111283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
111293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
111303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
111313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
111323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
111333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
111343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
111353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
111363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
111373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11138bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
111393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
111403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
111413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
111433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
111443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
111453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
111463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
111473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
111483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
111493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
111503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
111513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
111523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
111533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
111543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
111553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
111563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
111573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1115803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
111593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
111603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
111613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
111623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
111633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
111643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
111653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
111663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
111673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
111683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
111693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
111723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
111743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
111753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
111773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
111783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
111793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
111803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
111813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
111823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
111833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
111843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
111853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
111863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1118703812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
111883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
111893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
111903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
111913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
111923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
111933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
111943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
111953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
111963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
111973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
111983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1119903812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
112003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
112013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
112023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
112033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
112043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
112083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
112093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
112114e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
112143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
112183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
112213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
112283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
112293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
112303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
112313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
112333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
112353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
112372f2e514554975d510c88df54de98c6cdc1080f1cglennrp
11238b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
112392f2e514554975d510c88df54de98c6cdc1080f1cglennrp
112402f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
112412f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
112422f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
112432f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
112442f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
112452f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
112462f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
112472f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
112482f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
112492f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
112502f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
112512f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
11252a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
112532f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
112542f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
112552f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
112562f2e514554975d510c88df54de98c6cdc1080f1cglennrp
112573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
112583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
112593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
112613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
112623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
112633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
112643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
112653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
112663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
112673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
112683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
112693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
112703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
112713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
112720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
112743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
112750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
112770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
112793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
112813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
112823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
112833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
112843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
112853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
112863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1128703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
112883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
112893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
112903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
112933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
112953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
112960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
112990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
113013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11302d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1130339992b4dd9b12ef752d55b8e402c069698851f72glennrp
113043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
113083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
113090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
113113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
113123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1131339992b4dd9b12ef752d55b8e402c069698851f72glennrp
113143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
113153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
113163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
113173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11318d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
113193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11320