png.c revision afee4d36aae894a74306a3c492437ca55dce2bad
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
24405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrptypedef struct _UShortPixelPacket
24505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp{
24605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp  unsigned short
24705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    red,
24805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    green,
24905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    blue,
25005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    opacity,
25105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    index;
25205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp} UShortPixelPacket;
25305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2658182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
274bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39835ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
408b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  MagickBooleanType
409b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    need_blob;
410b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
433bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* Added at version 6.6.6-7 */
46626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  MagickBooleanType
46726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
46826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
46926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
47026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
47126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
47226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
47326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
47426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
47526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
47626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
477a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
47826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
47926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
48026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt;
48126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4900c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4930c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
5000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
5020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
5038640fb5e9b1094f35f8beab436f81661b8a99448glennrp  LosslessReduceDepthOK(Image *image)
5040c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
5050c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    MagickBooleanType
5060c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      ok_to_reduce=MagickFalse;
5070c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5080c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    /* Reduce bit depth if it can be reduced losslessly from 16 to 8.
5090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * Note that the method GetImageDepth doesn't check background
5100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * and doesn't handle PseudoClass specially.  Also it uses
5110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * multiplication and division by 257 instead of shifting, so
5120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * might be slower.
5130c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     */
5140c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5150c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    if (image->depth == 16)
5160c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
5170c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5180c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        const PixelPacket
5190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
5200c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
5220c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          (((((size_t) image->background_color.red >> 8) & 0xff)
5238640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.red & 0xff)) &&
5240c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp           ((((size_t) image->background_color.green >> 8) & 0xff)
5258640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.green & 0xff)) &&
5260c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp           ((((size_t) image->background_color.blue >> 8) & 0xff)
5278640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.blue & 0xff))) ? MagickTrue :
5288640fb5e9b1094f35f8beab436f81661b8a99448glennrp          MagickFalse;
5290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
5310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5320c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
5330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5340c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
5350c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5368640fb5e9b1094f35f8beab436f81661b8a99448glennrp                ok_to_reduce=(((((size_t) image->colormap[indx].red >>
5378640fb5e9b1094f35f8beab436f81661b8a99448glennrp                    8) & 0xff)
5388640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].red & 0xff)) &&
5390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].green >> 8) & 0xff)
5408640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].green & 0xff)) &&
5410c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].blue >> 8) & 0xff)
5428640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].blue & 0xff)) &&
5430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].opacity >> 8) & 0xff)
5448640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].opacity & 0xff))) ?
54513d07043243e0c8c151aad7db5240b75e76ca281cristy                  MagickTrue : MagickFalse;
5460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
5520c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
5530c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5540c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
5550c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
5560c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5570c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
5580c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
5590c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5600c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
5610c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
5620c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5630c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5640c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              if (p == (const PixelPacket *) NULL)
5650c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
5660c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
5670c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5680c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
5690c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5700c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
5710c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5728640fb5e9b1094f35f8beab436f81661b8a99448glennrp                ok_to_reduce=((
5738640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((size_t) p->red >> 8) & 0xff) ==
5748640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->red & 0xff)) &&
5750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) p->green >> 8) & 0xff) ==
5768640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->green & 0xff)) &&
5770c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) p->blue >> 8) & 0xff) ==
5788640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->blue & 0xff)) &&
5798640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((!image->matte ||
5808640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((size_t) p->opacity >> 8) & 0xff) ==
5818640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->opacity & 0xff))))) ? MagickTrue : MagickFalse;
5820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5830c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5850c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5860c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                p++;
5870c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5888640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
5890c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
5900c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
5910c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5920c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5930c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
5940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5950c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5968640fb5e9b1094f35f8beab436f81661b8a99448glennrp                "  OK to reduce PNG bit depth to 8 without loss of info");
5970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
5990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
6000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
6010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
6020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
6030c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
604e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
605e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_from_Magick_RenderingIntent(const RenderingIntent intent)
6060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
607e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
608e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
609e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
610e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
6110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
612e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
613e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
6140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
615e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
616e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
6170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
618e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
619e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
6200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
621e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
622e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
623e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
624e610a071534e448c46460a5aa39ede33bf56b329glennrp}
625e610a071534e448c46460a5aa39ede33bf56b329glennrp
626e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
627e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_to_Magick_RenderingIntent(const int png_intent)
6280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
629e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (png_intent)
630e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
631e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
632e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
6330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
634e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
635e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
6360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
637e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
638e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
6390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
640e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
641e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
6420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
643e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
644e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
645e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
646e610a071534e448c46460a5aa39ede33bf56b329glennrp}
647e610a071534e448c46460a5aa39ede33bf56b329glennrp
648bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6550c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
656bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6630c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
664dbb105fc25903e800273f7e980c0553060858a68glennrp
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
670dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s G r a y                                                     %
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
675dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
676dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
677dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
678dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
680dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsGray(Image *image)
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
685bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
687dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
688dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
693dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
694dbb105fc25903e800273f7e980c0553060858a68glennrp
695dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
697dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
698dbb105fc25903e800273f7e980c0553060858a68glennrp        if (IsGray(image->colormap+i) == MagickFalse)
699dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
700dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickTrue);
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
702bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
706dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
707dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
708dbb105fc25903e800273f7e980c0553060858a68glennrp    {
709dbb105fc25903e800273f7e980c0553060858a68glennrp       if (IsGray(p) == MagickFalse)
710dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
711dbb105fc25903e800273f7e980c0553060858a68glennrp       p++;
712dbb105fc25903e800273f7e980c0553060858a68glennrp    }
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
714dbb105fc25903e800273f7e980c0553060858a68glennrp  return(MagickTrue);
715dbb105fc25903e800273f7e980c0553060858a68glennrp}
716dbb105fc25903e800273f7e980c0553060858a68glennrp
717dbb105fc25903e800273f7e980c0553060858a68glennrp/*
718dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
719dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
720dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
721dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
722dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s M o n o c h r o m e                                         %
723dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
724dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
725dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
726dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
727dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
728dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
729dbb105fc25903e800273f7e980c0553060858a68glennrp%   and is more accurate.                                                     %
730dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
731dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
732dbb105fc25903e800273f7e980c0553060858a68glennrp*/
733dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsMonochrome(Image *image)
734dbb105fc25903e800273f7e980c0553060858a68glennrp{
735dbb105fc25903e800273f7e980c0553060858a68glennrp  register const PixelPacket
736dbb105fc25903e800273f7e980c0553060858a68glennrp    *p;
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
738dbb105fc25903e800273f7e980c0553060858a68glennrp  register ssize_t
739dbb105fc25903e800273f7e980c0553060858a68glennrp    i,
740dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
741dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
742a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
743dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image != (Image *) NULL);
744dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image->signature == MagickSignature);
745a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if (image->debug != MagickFalse)
746dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
747dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
748a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp    {
749dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
750dbb105fc25903e800273f7e980c0553060858a68glennrp      {
751dbb105fc25903e800273f7e980c0553060858a68glennrp        if ((IsGray(image->colormap+i) == MagickFalse) ||
752dbb105fc25903e800273f7e980c0553060858a68glennrp            ((image->colormap[i].red != 0) &&
753dbb105fc25903e800273f7e980c0553060858a68glennrp             (image->colormap[i].red != (Quantum) QuantumRange)))
754dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
755dbb105fc25903e800273f7e980c0553060858a68glennrp      }
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
758dbb105fc25903e800273f7e980c0553060858a68glennrp  for (y=0; y < (ssize_t) image->rows; y++)
759dbb105fc25903e800273f7e980c0553060858a68glennrp  {
760dbb105fc25903e800273f7e980c0553060858a68glennrp    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
761dbb105fc25903e800273f7e980c0553060858a68glennrp    if (p == (const PixelPacket *) NULL)
762dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
763dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsGray(p) == MagickFalse)
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->opacity != OpaqueOpacity) &&
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (p->opacity != (Quantum) TransparentOpacity))
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
780d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
898d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
899bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
921a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
929a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94203812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
94303812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
947e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
948e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
950d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
956d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
1070e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1071e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1099bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
11150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
11180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1175bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
11760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1190bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
12010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1202bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
12240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
12290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1242bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1244bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1252bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
12570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
12610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
12750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
12780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
12810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
12840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1296bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1297bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1298bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1299bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1317bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
13198182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
13208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
13210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13318182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13338182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGErrorHandler(png_struct *ping,png_const_charp message)
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
13420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
13460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
13490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1350faa852bad40107edae19405e76a299057668d795glennrp#if PNG_LIBPNG_VER < 10500
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1352faa852bad40107edae19405e76a299057668d795glennrp#else
1353faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1354faa852bad40107edae19405e76a299057668d795glennrp#endif
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGWarningHandler(png_struct *ping,png_const_charp message)
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
13640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1368cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
13690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
13830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
13860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_read_raw_profile(Image *image, const ImageInfo *image_info,
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1413bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1446f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
14470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
14600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
14720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1473bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
14890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
14980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
15010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1535bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
15370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1538bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1592faa852bad40107edae19405e76a299057668d795glennrp    pass,
1593faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1594faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1595faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1596faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1597faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
1598faa852bad40107edae19405e76a299057668d795glennrp    ping_num_trans;
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
16014383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
160405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp  UShortPixelPacket
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent_color;
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1607faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1608faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1609faa852bad40107edae19405e76a299057668d795glennrp
1610faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1611faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1612faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1613faa852bad40107edae19405e76a299057668d795glennrp
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1624faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1625faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1626faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
1627faa852bad40107edae19405e76a299057668d795glennrp    ping_rowbytes;
1628faa852bad40107edae19405e76a299057668d795glennrp
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1635bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
16425c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1644bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
165239992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOnePNGImage()");
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1671f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
167425c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
168061b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
168161b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
168261b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
168361b4c957269727a0a2526edc2331881da8346100glennrp    {
168461b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
168561b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
168661b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
168761b4c957269727a0a2526edc2331881da8346100glennrp    }
168861b4c957269727a0a2526edc2331881da8346100glennrp#  endif
168961b4c957269727a0a2526edc2331881da8346100glennrp#endif
169061b4c957269727a0a2526edc2331881da8346100glennrp
169161b4c957269727a0a2526edc2331881da8346100glennrp
1692ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
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
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        info,
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1886e610a071534e448c46460a5aa39ede33bf56b329glennrp      image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1887e610a071534e448c46460a5aa39ede33bf56b329glennrp        mng_info->global_srgb_intent);
18880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1891e610a071534e448c46460a5aa39ede33bf56b329glennrp        image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1892e610a071534e448c46460a5aa39ede33bf56b329glennrp          intent);
18930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1896e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1904faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1905faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1906faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
19070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1916faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1917faa852bad40107edae19405e76a299057668d795glennrp    {
1918faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1919faa852bad40107edae19405e76a299057668d795glennrp        {
1920faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1921faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1922faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1923faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1924faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1925faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1926faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1927faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1928faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1929faa852bad40107edae19405e76a299057668d795glennrp        }
1930faa852bad40107edae19405e76a299057668d795glennrp    }
19310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1932faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1949e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1951e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
1952e610a071534e448c46460a5aa39ede33bf56b329glennrp         PNG_RenderingIntent_from_Magick_RenderingIntent(
1953e610a071534e448c46460a5aa39ede33bf56b329glennrp         image->rendering_intent));
1954faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
1955faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
1956faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
1957faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
1960faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=png_get_x_offset_pixels(ping, ping_info);
19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=png_get_y_offset_pixels(ping, ping_info);
19640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1968e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
1969e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
1973faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
1974faa852bad40107edae19405e76a299057668d795glennrp    {
1975faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
1976faa852bad40107edae19405e76a299057668d795glennrp        {
1977faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
1978faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
1979faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
1980faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
1981faa852bad40107edae19405e76a299057668d795glennrp        }
1982faa852bad40107edae19405e76a299057668d795glennrp    }
1983faa852bad40107edae19405e76a299057668d795glennrp
1984faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
19970881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
19980881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
19990881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
20000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2010e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2011e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2014faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
20230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2025faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
20310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2032faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2049faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2058faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2059faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
20600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
2082faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2083faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2086faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
20940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20952cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2097faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
2098faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
2099faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21022cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21042cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
21052cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
21062cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21072cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21082cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21092cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
21102cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
21112cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21122cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
21130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21142cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
21152cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
21160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21172cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
21182cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
21190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21202cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
21212cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
21220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21232cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
21242cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
21252cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21262cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
21272cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
21282cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
21292cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21302cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21312cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
21322cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21332cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
21340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21352cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21362cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
21372cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
21382cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
21392cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
2141faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
21420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
2144faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
21450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
2147faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
21480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2149f17da7472c6195cfc91626d98d166cae04345d34cristy          image->background_color.opacity=OpaqueOpacity;
21502cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21512cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21522cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2153e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
2154e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
2155e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
2156e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.red=0;
21613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.green=0;
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.blue=0;
21633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.opacity=0;
2164faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
21713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
217235ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
217335ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
217435ef824baa82511126ff0072ae30eee0da9c05a3cristy
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2179f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2181faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2182faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2183faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2184faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2185faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2186faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2192faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
219705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.red= (unsigned short)(ping_trans_color->red);
219805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.green= (unsigned short) (ping_trans_color->green);
219905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.blue= (unsigned short) (ping_trans_color->blue);
220005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.opacity= (unsigned short) (ping_trans_color->gray);
220105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2202faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
22040f111984738842d27d04aed2a3f823d82a943506glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22050f111984738842d27d04aed2a3f823d82a943506glennrp              if (ping_bit_depth < MAGICKCORE_QUANTUM_DEPTH)
22060f111984738842d27d04aed2a3f823d82a943506glennrp#endif
220705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp              transparent_color.opacity=(unsigned short) (
22080f111984738842d27d04aed2a3f823d82a943506glennrp                  ping_trans_color->gray *
220905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                  (65535L/((1UL << ping_bit_depth)-1)));
22100f111984738842d27d04aed2a3f823d82a943506glennrp
221105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
221205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp              else
221305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                transparent_color.opacity=(unsigned short) (
221405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                    (ping_trans_color->gray * 65535L)/
221505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                   ((1UL << ping_bit_depth)-1));
22160f111984738842d27d04aed2a3f823d82a943506glennrp#endif
22170f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
22180f111984738842d27d04aed2a3f823d82a943506glennrp              {
22190f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22200f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
22210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22220f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22230f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
22240f111984738842d27d04aed2a3f823d82a943506glennrp              }
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2234faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2239faa852bad40107edae19405e76a299057668d795glennrp
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2241faa852bad40107edae19405e76a299057668d795glennrp
2242faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2243faa852bad40107edae19405e76a299057668d795glennrp
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2248bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2250bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2253faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2254faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2265faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2266faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2267faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2268faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2269faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2271befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2272befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2273befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2275befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2276befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2284faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2293bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
22940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2309faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
23180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2319bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
23260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2329bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2332faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
23330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
23360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2337bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
23493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
23500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23510ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2352347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2353347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2357e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2361f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
23660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
23730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2376faa852bad40107edae19405e76a299057668d795glennrp      ping_rowbytes*sizeof(*png_pixels));
23770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2379faa852bad40107edae19405e76a299057668d795glennrp    png_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sizeof(*png_pixels));
23810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2391faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2398f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
24013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
24020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
24050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
24090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
24117b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
24127b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
24137b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
24147b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
24150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
24173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2419ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
24200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2421ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2422ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2424c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
2425c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2426c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
2427c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
2428c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2429c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
2430c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2433c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
2434c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2435c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
2436c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
2437c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
2438c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#if  (MAGICKCORE_QUANTUM_DEPTH == 8)
2439c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        int
2440c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          depth;
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2442c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        depth=(ssize_t) ping_bit_depth;
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2444c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2445c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2446c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2447c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            MagickTrue : MagickFalse;
24480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2449c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
2450c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
2451c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
2452c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
24530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2454c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
2455c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
24560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2457c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          png_read_row(ping,png_pixels+row_offset,NULL);
2458c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2460c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (q == (PixelPacket *) NULL)
2461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
24620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2463c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#if  (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
2464c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp/* code deleted from version 6.6.6-8 */
2465c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#else  /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
24660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2467c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2469c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              GrayQuantum,png_pixels+row_offset,exception);
24700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2471c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2473c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              GrayAlphaQuantum,png_pixels+row_offset,exception);
24740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2475c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2477c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              RGBAQuantum,png_pixels+row_offset,exception);
24780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2479c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2480c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2481c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              IndexQuantum,png_pixels+row_offset,exception);
24820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2483c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
2484c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2485c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              RGBQuantum,png_pixels+row_offset,exception);
2486c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#endif
2487c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
2488c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2489c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
2490c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
2491c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
24925aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
24935aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
24945aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                   (q->opacity != OpaqueOpacity))
2495c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
2496c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
2497c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
2498c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
24994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
25004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
25014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (q->red == transparent_color.red &&
25024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    q->green == transparent_color.green &&
25034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    q->blue == transparent_color.blue))
25044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
25054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
25064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
25074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
2508c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                q++;
2509c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
2510c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
25110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2512c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
2513c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2514c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2515c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
25160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2517c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
2518c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
2519c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
2520c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
2521c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
2522c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
25230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2524c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
25257a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2526c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
25277a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
25287a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
25297a287bfadeadea12e47c2376ca78a5d101687142cristy          }
25303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
2534c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
25423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2546faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
25473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
25480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
25510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
25540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2555bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
25573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2558faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
2559c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
2562c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
25650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25695c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=png_pixels+row_offset;
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2572c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2573faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2577bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2580bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2589bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
259547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2598bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2608bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
261447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2617bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
26250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
262847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2631faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2632bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
2641c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                if (q->opacity != OpaqueOpacity)
2642c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  found_transparent_pixel = MagickTrue;
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2647bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
265247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2655bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2658bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
267147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2672faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
2677c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
2678c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2683bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
26960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2697faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
2700afee4d36aae894a74306a3c492437ca55dce2badcristy                  q->opacity*=65537L;
270146f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
2702afee4d36aae894a74306a3c492437ca55dce2badcristy                  if (q->opacity != OpaqueOpacity)
2703c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
270747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
271147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2712faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
2715c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
2716c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
272347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
272647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
27340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2735bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
273680ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
27370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
27400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27417a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
27427a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2743cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2744cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
274547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27467a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
27477a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
27487a287bfadeadea12e47c2376ca78a5d101687142cristy          }
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2750c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27517a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
275447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
2758c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2761c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2762c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    image->matte=found_transparent_pixel;
2763c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2764c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
2765c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2766c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
2767c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2768c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
2769c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
27705aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
27715aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27725aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
27735aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
27745aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
2775c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
2776c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
2777c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2778b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2779b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
27800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27815c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
27825c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2783aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
27845c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
27855c6f789db7a30bad01ace12b09ad9cd471339e94cristy
27865c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
27875c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
27885c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2789aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
27905c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
279147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
27933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2795bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
27963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
27983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
27993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
28003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2802f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
28033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
28073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
280947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2810faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
28133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
28143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
28173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2820c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28213c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
2822c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
28240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2826c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
28270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
28280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 image->colormap[x].opacity =
28300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                   ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
28310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
2832c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
283347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
28360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
28370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
28390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                     transparent_color.opacity)
28400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
28410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    image->colormap[x].opacity = (Quantum) TransparentOpacity;
28420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
28430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
28440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) SyncImage(image);
28460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
284747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
28490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
28510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
28520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
28530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2854c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (q == (PixelPacket *) NULL)
28560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
2857c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            indexes=GetAuthenticIndexQueue(image);
28590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
28610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
28624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ScaleQuantumToChar(q->red) == transparent_color.red &&
28634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ScaleQuantumToChar(q->green) == transparent_color.green &&
28644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ScaleQuantumToChar(q->blue) == transparent_color.blue)
28654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  q->opacity=(Quantum) TransparentOpacity;
28674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
28680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
28704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  q->opacity=(Quantum) OpaqueOpacity;
28724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
28730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              q++;
28750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
28780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
2879c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
28800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
2881c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
28833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28843c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
2885b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2886b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2887b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
288847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
2890bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) num_text; i++)
28913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
28933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
28970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_read_raw_profile(image,image_info,text,(int) i);
29000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
29043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
29190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
29230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29273c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
29293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
294073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
29410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
29463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
294847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
29513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
29560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
29690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
29720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
29750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2981faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
29830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2984faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
2985faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
2986faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
2987faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
2988faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
2989faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
2990faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
2991faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
29920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2993faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
30063c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
301247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3025f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
30310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
30534383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    have_mng_structure;
30544383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
30554383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
30603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
306647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
307047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
30753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
307747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
308047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
30833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
308547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
308847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
309373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
309447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
309747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
310847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
31150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
31230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
312647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
312847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
31340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
313747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
31410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
314747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
31560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
31590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32114383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
32124383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
32134383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3214bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3237bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3252bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOneJNGImage()");
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
32690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
32780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
32800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
32830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
33110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
33140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3322e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3323e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
33270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
333047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
33340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
33370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3338bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
33400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
334347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
335047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3358bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3360bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
336647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
336947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
337447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3378f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
337947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3381f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
338247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
338547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
338947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
339347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
339747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
340147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
340547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
340947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
341547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
341847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
343473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
343547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
343847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
34410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
34480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
34520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
345973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
34600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
34660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
34770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
34810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
34840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
34930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
34960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
349903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
351647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
352347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
352647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
353547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3543bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
354503812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
35463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
356047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
35800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
36108182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
36110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
36218182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
36228182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
36238182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
36248182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
36258182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
36268182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
36278182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
362947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3638e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3639e610a071534e448c46460a5aa39ede33bf56b329glennrp              PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
365047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36598182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.x=mng_get_long(p);
36608182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.y=mng_get_long(&p[4]);
36610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
366847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36798182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
36808182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* To do. */
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
37090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
373847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
37420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
37450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
37480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
37620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
37660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3767bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
377247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
37780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
378903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
37930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
37950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
38040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3806bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
381147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3813bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
38150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3817bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
38230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
383547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
383647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
38440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
38460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
38470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
38500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
38520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
38530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
38560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
38580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
38630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
38670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
39184383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    have_mng_structure;
39194383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
39204383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
39380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
39410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
394547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
394647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
394847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
395247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
395347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
395573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
39560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
396047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
396147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
39690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
39770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
39810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
398547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
39910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
39970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40144383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
40154383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
40164383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4023bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4048bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4054bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4071bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
408038ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
408138ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
408238ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4083bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
410547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
410647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
41160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
41190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
412347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
412447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
412547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
412673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
41270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
41300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
413147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
413247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
414247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
414647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
414747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4150bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4151bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
415547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4198e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4199e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
42030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
42060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
42090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
421347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
421647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4217bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
421947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
42290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
42330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
42400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
42440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
424947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
42540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
42610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4267bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
42690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4270bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
42720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4276e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4278e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
42828182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
42830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
42860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
42900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
42930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
42978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
43010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
43040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
43070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
431447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
43160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
43190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
43270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4328e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4329e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4330f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
43310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4333bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4335bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
43370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
43400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
43530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
43578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
43580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
43610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
43700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4372e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
43730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4375e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
43870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
43890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
43940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
44180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
44210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
44280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
44290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
44310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
44320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4436e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4437f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
44380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4440e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4441f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
44510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
44580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
44630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
44660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
44690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
44810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
44840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
44890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
44920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
44950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
450747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
451047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
451147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
45170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4518bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
452535ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
45340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
45400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
454447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4550bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
455712560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4565bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45688182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
45750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
458247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
458347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
45878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
45888182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
45908182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
45928182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
45948182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
45968182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
45988182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
460347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
460747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4615e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4616e610a071534e448c46460a5aa39ede33bf56b329glennrp                  PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
462147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
462547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* To do. */
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
463547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
463847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
46450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
46480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
465247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
46560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
46600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
466347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
466447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
466647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4667bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
466947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
467147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4672bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
468347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
46868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
46878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
46880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
46908182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
46910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4692bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4693bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
46940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
46970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
46990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4702e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
470447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4707bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4708bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
47090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4710bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4711bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
47120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4713bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4714bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
47150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
47180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
47200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4723e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
472547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
47310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
4735e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4736e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
473747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
47450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4746bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
47480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4749bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4757e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4758e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
47590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
476347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
476747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
477447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
47790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
47890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
48000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4804e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4805e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
482247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
483447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
485847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
485947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4868bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4871bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
488347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4886bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
489047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
489147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4894bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
491147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4918bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
492147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
492247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
49238182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
49240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4927e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
4928e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
49290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
49320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
494347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
494747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
495947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
49660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
4970e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
4971f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
497247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
49770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
498247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
500047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
500447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
501147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
501447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
50310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
50340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
50370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
504847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
505447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
506047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
506347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
506947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
507247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
507847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
508147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
508747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
509047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
509647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
509947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
510547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
510847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
511447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
511847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
512647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
514547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
515247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
515547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
516247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
516547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
517047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
51868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
51888182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
519247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
520147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
520747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
521247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5215bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5217bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
522547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
522847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
523147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
523447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
523747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
524047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
524347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
525147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
525447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
525747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
526247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
527247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
527947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
528247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
528847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
529647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
52988182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5311bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5313bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
532147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
532847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
533247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
533947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
534247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
534347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
534447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5356e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5357e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
537447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
538147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
53840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
53860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
539647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
54070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5411e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5412e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
541647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
542347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
543047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
54360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
54390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
54480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
54570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
546347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
546747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
547247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5473bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
547447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
548647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
549947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
553247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
553547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
553747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
553847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
554047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55434e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
554447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
554747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
555047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
555247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
555347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
555547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
555947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
556247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
556447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
556547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
556747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55704e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
557147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
557447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
557747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
557947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
558047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
558247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5592bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5596bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
561147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
561247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
561647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
561847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5642bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
564647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5647bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
565547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
566647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
567147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
567447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
567747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
568047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5689e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5690bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
569547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
570447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
570747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5708bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5711bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
571247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5713bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5714bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
571547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5716bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5717bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
571847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5719bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
572147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5723bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
572447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
572847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5729bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
573547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5741bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
574747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5748bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
57505c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      /* TO DO: get color as function of indexes[x] */
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
576147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
576647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5771bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5773bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5774bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5777bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
577947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5781bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5784bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
578647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
579647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
580247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
580547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5808bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5809bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
581747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
582047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
582347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5842e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5844bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
585247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5853bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5854bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5856bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5857bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
585847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5859bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5860bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
586147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5862bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5863bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
586447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5865bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
586747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5869bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
587047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
587847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
588347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5889bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5892bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5895bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
5898bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
590147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
591147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
591747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
592047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
5925bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
593447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
5944bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
594747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5948bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
595647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
599047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6006bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6007bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
601347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
602547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60482b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
60492b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
60502b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       * if lossy
60512b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
60522b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
60532b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
60542b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
60552b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
60560c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
60578640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if (LosslessReduceDepthOK(image) != MagickFalse)
60588640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6060d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
606247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6066bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6069d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6073d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
607547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
607747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
608147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
60920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
610347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
610747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
61200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
61230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
61280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
61310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
613947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
614347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
61480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
615347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
615947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
616747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
617247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
617847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
618147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
618447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
61920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
61950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
61980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
620347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
62090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
62110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6214e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6215e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
62160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
622447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
622747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6229e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
623047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6235e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6247bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
625247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
625547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
625847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
626147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
627047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
627347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
629047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
630047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
630347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6305e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6306e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
630747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6309f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6310f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
631147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6312f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6313e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6314e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6315f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6316f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
631747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
632147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
632447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
632725c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
633247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
633547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
633847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
634325c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6366bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6369bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
638247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
638847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
639647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
640047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
640847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
641147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
641647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
641947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
642247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
642847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
643347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
643847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
644147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
644647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
645147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
646147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
646547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
647247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
647547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
648047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
648847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
649347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
650147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
650847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
651547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
651618b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
651718b17443128598500357da7bff2f01683cf32890cristy  png_semaphore=AllocateSemaphoreInfo();
651818b17443128598500357da7bff2f01683cf32890cristy#endif
651947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
655047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6552514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy  if (png_semaphore != (SemaphoreInfo *) NULL)
6553514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy    DestroySemaphoreInfo(&png_semaphore);
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
655825c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    some GIF animations don't convert properly)
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6644bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
66650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
66660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
66680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6687f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
668947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6690bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
669747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
670447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
670747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType png_write_chunk_from_profile(Image *image,
67144383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
672847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
672947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
673047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
673247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png_profile;
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
673847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
673947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
674047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
674147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
674247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
674347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
674447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            png_profile=CloneStringInfo(profile);
674547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data=GetStringInfoDatum(png_profile),
674647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            length=(png_uint_32) GetStringInfoLength(png_profile);
674747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
674847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
674947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
675047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
675147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
675247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
675347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
675447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            png_profile=DestroyStringInfo(png_profile);
675547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
675747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
676047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6764b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6765b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
6767b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp   const ImageInfo *IMimage_info,Image *IMimage)
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6769b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  Image
6770b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image;
6771b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6772b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  ImageInfo
6773b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image_info;
6774b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
67873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_matte,
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6789cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6790cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
67914383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
67924383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
67934383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
6794e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6795e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
67965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
679739992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
679839992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
68015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
68025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
68035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
68115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
68125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
68135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6814bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
6818d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
681939992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
6820991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
6821991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
6822991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
682326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
682426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
682526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
682626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
682726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
682826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
682926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
683026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
683126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
683226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
683326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
6834a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
683526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
683626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
683726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
683826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
68390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
68400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6846bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
68483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte;
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
68570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
68585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
68595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
68605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
68615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
68625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
68635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6864bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_colors,
68665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
68675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6869bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
687039992b4dd9b12ef752d55b8e402c069698851f72glennrp    number_colors,
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
68743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6875dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
68768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
68778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
68788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
6879dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
6880dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6881dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
6882dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
6883dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
6884dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOnePNGImage()");
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6888b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image = CloneImage(IMimage,0,0,MagickFalse,&IMimage->exception);
6889b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
6890b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6891b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  if (mng_info->need_blob != MagickFalse)
6892b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  {
6893b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) ==
6894b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       MagickFalse)
6895b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    {
6896b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
6897b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
6898b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      return(MagickFalse);
6899b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    }
6900b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  }
6901b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6903f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
69070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
69085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
69095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
69105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
69115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
69125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
69135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
69155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
69165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
69175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
69185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
69195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
69215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
69225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
69235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
69245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6925dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
6926dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
6927dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
6928dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6929d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
693039992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
6931991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
6932991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
6933991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
6934991d11dd9c33e65872778b81aff1347cd2878154glennrp
69350e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
69360e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
69370e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_EXIF=mng_info->ping_exclude_EXIF; /* hex-encoded EXIF in zTXt */
69380e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
69390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
69400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
69410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
69420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
69430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
69440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
69450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
69460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tRNS=mng_info->ping_exclude_tRNS;
69470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
69480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
69490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
69500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
69510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
69520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
69538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
69548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
69558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
69568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
69590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69603241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
69613241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
69623241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
69633241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
69643241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
69653241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp     (void) SyncImage(image);
69663241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
69672b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
69682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
69692b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
69702b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
69712b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  if (image->depth > 16)
69722b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
69732b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
69742b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
69758640fb5e9b1094f35f8beab436f81661b8a99448glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
69767e2c405930c984e8ffb49b26efdfe1649bf394d6cristy  if (image->depth == 16 && mng_info->write_png_colortype != 16)
69778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
69788640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
69798640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
69808640fb5e9b1094f35f8beab436f81661b8a99448glennrp
698183c2de583a59e41b57be8036d1cf7392c01d03d7glennrp#ifdef PNG_BUILD_PALETTE
6982d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype < 8 /* all */)
698383c2de583a59e41b57be8036d1cf7392c01d03d7glennrp    {
698483c2de583a59e41b57be8036d1cf7392c01d03d7glennrp      /*
69857ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       * Sometimes we get DirectClass images that have 256 colors or fewer.
6986d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * This code will build a colormap.
69877ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       *
69883241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp       * Also, sometimes we get PseudoClass images with an out-of-date
69893241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp       * colormap.  This code will replace the colormap with a new one.
6990d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * Sometimes we get PseudoClass images that have more than 256 colors.
6991d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * This code will delete the colormap and change the image to
6992d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * DirectClass.
69938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       *
69948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       * Also we gather some information (number of opaque, transparent,
6995d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * and semitransparent pixels, and whether the image has any non-gray
6996d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * pixels) that we might need later. If the user wants to force
6997d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * GrayAlpha or RGBA (colortype 4 or 6) we probably don't need any
6998d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * of that.
69997ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       */
70003c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
70018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     ExceptionInfo
70028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       *exception;
70038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     int
70058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       n;
70068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     PixelPacket
7008d6bf1617e99df0272b231855a933a74e99b6578fglennrp       colormap[800],
7009d6bf1617e99df0272b231855a933a74e99b6578fglennrp       opaque[260],
7010d6bf1617e99df0272b231855a933a74e99b6578fglennrp       semitransparent[260],
7011d6bf1617e99df0272b231855a933a74e99b6578fglennrp       transparent[260];
70128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     register IndexPacket
70148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       *indexes;
70158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7016d6bf1617e99df0272b231855a933a74e99b6578fglennrp     register const PixelPacket
7017d6bf1617e99df0272b231855a933a74e99b6578fglennrp       *q;
7018d6bf1617e99df0272b231855a933a74e99b6578fglennrp
701903812ae402fb53d548f0e1d7d14720768f803c2dglennrp     if (logging != MagickFalse)
702003812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
702103812ae402fb53d548f0e1d7d14720768f803c2dglennrp           "    Enter BUILD_PALETTE:");
70223c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
70238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     image->colors=GetNumberColors(image,(FILE *) NULL,&image->exception);
70248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     image_colors=image->colors;
70258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     if (logging != MagickFalse)
70277ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
70287ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image->columns=%.20g",(double) image->columns);
70308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image->rows=%.20g",(double) image->rows);
70328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image_matte=%.20g",(double) image->matte);
70348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image->depth=%.20g",(double) image->depth);
70362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         if (image->colormap != NULL)
70387ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
70397ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      Original colormap:");
70418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "        i    (red,green,blue,opacity)");
70438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           for (i=0; i < (ssize_t) image->colors; i++)
70458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           {
70468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                 "        %d    (%d,%d,%d,%d)",
70488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (int) i,
70498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (int) image->colormap[i].red,
70508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (int) image->colormap[i].green,
70518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (int) image->colormap[i].blue,
70528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (int) image->colormap[i].opacity);
70538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           }
70547ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
70552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             "      image->colors=%d",(int) image->colors);
70582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         if (image->colors == 0)
70608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             "        (zero means unknown)");
706283c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
706303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
706403812ae402fb53d548f0e1d7d14720768f803c2dglennrp              "      Regenerate the colormap");
706503812ae402fb53d548f0e1d7d14720768f803c2dglennrp       }
70667ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       exception=(&image->exception);
70687ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7069d6bf1617e99df0272b231855a933a74e99b6578fglennrp       ping_have_color=MagickFalse;
7070d6bf1617e99df0272b231855a933a74e99b6578fglennrp       image_colors=0;
7071d6bf1617e99df0272b231855a933a74e99b6578fglennrp
70728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       for (y=0; y < (ssize_t) image->rows; y++)
70738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       {
707498bd891f2d35aeb2086bd36e81ededf2da65e714cristy         q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
70752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         if (q == (PixelPacket *) NULL)
70778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           break;
70787ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7079d6bf1617e99df0272b231855a933a74e99b6578fglennrp         for (x=0; x < (ssize_t) image->columns; x++)
7080d6bf1617e99df0272b231855a933a74e99b6578fglennrp            {
7081d6bf1617e99df0272b231855a933a74e99b6578fglennrp                if (q->red != q->green || q->red != q->blue)
7082d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  ping_have_color=MagickTrue;
70837ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7084d6bf1617e99df0272b231855a933a74e99b6578fglennrp                if (image_colors == 0)
7085d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  {
7086d6bf1617e99df0272b231855a933a74e99b6578fglennrp                   /* Initialize the colormap */
7087d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    colormap[0]=*q;
7088d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7089d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    if (image->matte == MagickFalse)
7090d6bf1617e99df0272b231855a933a74e99b6578fglennrp                          colormap[0].opacity = OpaqueOpacity;
70912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7092d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    image_colors=1;
7093d6bf1617e99df0272b231855a933a74e99b6578fglennrp                   }
70947ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70954383ec8c3c8811128f5a8a034d67c47db5e7e75acristy                for (i=0; i< (ssize_t) image_colors; i++)
70968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
70978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (((image->matte == MagickFalse ||
70988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        colormap[i].opacity == q->opacity)) &&
70998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        (IsColorEqual(colormap+i, (PixelPacket *) q)))
71008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      break;
71018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
71027ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
71034383ec8c3c8811128f5a8a034d67c47db5e7e75acristy                if (i ==  (ssize_t) image_colors && image_colors < 299)
71048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
71053c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7106d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    image_colors++;
71073241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7108d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    colormap[i]=*q;
71093241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7110d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    if (image->matte == MagickFalse)
7111d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       colormap[i].opacity = OpaqueOpacity;
7112d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  }
71133241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                q++;
71158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
71168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
71173c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
71182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
711903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (logging != MagickFalse)
712003812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
712103812ae402fb53d548f0e1d7d14720768f803c2dglennrp              if (image_colors >= 800)
712203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
712303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                       "      image has more than 800 colors");
71243241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
712503812ae402fb53d548f0e1d7d14720768f803c2dglennrp              else
712603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
712703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                       "      image has %d colors",(int)image_colors);
712803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
71292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
713003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /*
713103812ae402fb53d548f0e1d7d14720768f803c2dglennrp            Initialize image colormap.
713203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          */
71332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
713403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (logging != MagickFalse)
71358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   "      Sort the new colormap");
71373241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
713803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* Sort palette, transparent first */;
71394383ec8c3c8811128f5a8a034d67c47db5e7e75acristy          for (i=0; i< (ssize_t) image_colors; i++)
714003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          {
714103812ae402fb53d548f0e1d7d14720768f803c2dglennrp             if (colormap[i].opacity == OpaqueOpacity)
714203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                opaque[number_opaque++] = colormap[i];
71433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
714403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             else if (colormap[i].opacity == TransparentOpacity)
714503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                transparent[number_transparent++] = colormap[i];
71463241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
714703812ae402fb53d548f0e1d7d14720768f803c2dglennrp             else
714803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                semitransparent[number_semitransparent++] =
714903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    colormap[i];
715003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          }
71513241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71523241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
715303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          n = 0;
71543241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
715503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (i=0; i<number_transparent; i++)
715603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             colormap[n++] = transparent[i];
71573241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
715803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (i=0; i<number_semitransparent; i++)
715903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             colormap[n++] = semitransparent[i];
71603241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
716103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (i=0; i<number_opaque; i++)
716203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             colormap[n++] = opaque[i];
71633241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_exclude_bKGD == MagickFalse)
71654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
71664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /* Add the background color to the palette, if it
71674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               * isn't already there.
71684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               */
71694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              for (i=0; i<number_opaque; i++)
71704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
71714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 if (IsColorEqual(opaque+i,
71724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    &image->background_color))
71734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 break;
71744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
71753241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (number_opaque < 257 && i == number_opaque)
71774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
71784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 opaque[i]=image->background_color;
71794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 opaque[i].opacity = OpaqueOpacity;
71804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 number_opaque++;
71814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
71824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
71834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
71844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent == 1)
71854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
71864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red= (unsigned short)(transparent[0].red);
71874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green= (unsigned short) (transparent[0].green);
71884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue= (unsigned short) (transparent[0].blue);
71894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray= (unsigned short) (transparent[0].blue);
71904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
7191d6bf1617e99df0272b231855a933a74e99b6578fglennrp
719203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (logging != MagickFalse)
719303812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
719403812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
719503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      number_transparent     = %d",
719603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    number_transparent);
7197d6bf1617e99df0272b231855a933a74e99b6578fglennrp
719803812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
719903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      number_opaque          = %d",
720003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    number_opaque);
7201d6bf1617e99df0272b231855a933a74e99b6578fglennrp
720203812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
720303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      number_semitransparent = %d",
720403812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    number_semitransparent);
720503812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
72063241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
72070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if ((mng_info->ping_exclude_tRNS == MagickFalse ||
72080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (number_transparent == 0 && number_semitransparent == 0)) &&
72090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (((mng_info->write_png_colortype-1) == PNG_COLOR_TYPE_PALETTE) ||
72100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (mng_info->write_png_colortype == 0)))
721103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          {
721203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             if (logging != MagickFalse)
721303812ae402fb53d548f0e1d7d14720768f803c2dglennrp               {
72144383ec8c3c8811128f5a8a034d67c47db5e7e75acristy                 if (n !=  (ssize_t) image_colors)
721503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
721603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "   image_colors (%d) and n (%d)  don't match",
721703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    (int) image_colors, n);
72183241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
721903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
722003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      AcquireImageColormap");
722103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
72223241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
722303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          image->colors = image_colors;
72243241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
722503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (AcquireImageColormap(image,image_colors) ==
722603812ae402fb53d548f0e1d7d14720768f803c2dglennrp              MagickFalse)
722703812ae402fb53d548f0e1d7d14720768f803c2dglennrp             ThrowWriterException(ResourceLimitError,
722803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                "MemoryAllocationFailed");
72293241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
72304383ec8c3c8811128f5a8a034d67c47db5e7e75acristy          for (i=0; i< (ssize_t) image_colors; i++)
723103812ae402fb53d548f0e1d7d14720768f803c2dglennrp             image->colormap[i] = colormap[i];
72323c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
723303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (logging != MagickFalse)
723403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
723503812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
723603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      image->colors=%d (%d)",
723703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    (int) image->colors, (int) image_colors);
72387ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
723903812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
724003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      Update the pixel indexes");
724103812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
72423241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
724303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (y=0; y < (ssize_t) image->rows; y++)
724403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          {
724503812ae402fb53d548f0e1d7d14720768f803c2dglennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,
724603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                exception);
72472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
724803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            if (q == (PixelPacket *) NULL)
724903812ae402fb53d548f0e1d7d14720768f803c2dglennrp              break;
72503c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
725103812ae402fb53d548f0e1d7d14720768f803c2dglennrp            indexes=GetAuthenticIndexQueue(image);
72523c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
725303812ae402fb53d548f0e1d7d14720768f803c2dglennrp            for (x=0; x < (ssize_t) image->columns; x++)
725403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
72554383ec8c3c8811128f5a8a034d67c47db5e7e75acristy              for (i=0; i< (ssize_t) image_colors; i++)
725603812ae402fb53d548f0e1d7d14720768f803c2dglennrp              {
725703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                if ((image->matte == MagickFalse ||
725803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    image->colormap[i].opacity == q->opacity) &&
725903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    (IsColorEqual(&image->colormap[i],(PixelPacket *) q)))
726003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
726103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                  indexes[x]=(IndexPacket) i;
72628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
726303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
726403812ae402fb53d548f0e1d7d14720768f803c2dglennrp              }
726503812ae402fb53d548f0e1d7d14720768f803c2dglennrp              q++;
72668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
726783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
726803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
726903812ae402fb53d548f0e1d7d14720768f803c2dglennrp               break;
727003812ae402fb53d548f0e1d7d14720768f803c2dglennrp         }
727103812ae402fb53d548f0e1d7d14720768f803c2dglennrp       }
72723c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
727303812ae402fb53d548f0e1d7d14720768f803c2dglennrp       if (logging != MagickFalse)
727403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         {
727503812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
727603812ae402fb53d548f0e1d7d14720768f803c2dglennrp              "      image->colors=%d", (int) image->colors);
72773c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
727803812ae402fb53d548f0e1d7d14720768f803c2dglennrp           if (image->colormap != NULL)
727903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             {
728003812ae402fb53d548f0e1d7d14720768f803c2dglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
728103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                   "       i     (red,green,blue,opacity)");
72823c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
728303812ae402fb53d548f0e1d7d14720768f803c2dglennrp               for (i=0; i < (ssize_t) image->colors; i++)
728403812ae402fb53d548f0e1d7d14720768f803c2dglennrp               {
728503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
728603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                     "       %d     (%d,%d,%d,%d)",
728703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                      (int) i,
728803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                      (int) image->colormap[i].red,
728903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                      (int) image->colormap[i].green,
729003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                      (int) image->colormap[i].blue,
729103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                      (int) image->colormap[i].opacity);
729203812ae402fb53d548f0e1d7d14720768f803c2dglennrp               }
729303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             }
729403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
729503812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
729603812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
729703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         }
729883c2de583a59e41b57be8036d1cf7392c01d03d7glennrp    }
72993c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp#endif /* PNG_BUILD_PALETTE */
73003c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
73010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
73020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
73030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
73040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      int colortype=mng_info->write_png_colortype;
73050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
73060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
73070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
73080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
73090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
73100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
73110e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
73124383ec8c3c8811128f5a8a034d67c47db5e7e75acristy      if (colortype != 0 && mng_info->write_png_colortype != (ssize_t) colortype)
73130e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
73140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
73150e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
73160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
73173c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
73183c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
73193c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
73203c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
73213c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_colors=image->colors;
73223c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
732383c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
73240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
73258eb57274a813fc3f2e2f96b166eb569f5e17aa26glennrp    image_colors <= 256;
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
73340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
73380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
73420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
73440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7365f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7367b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      if (mng_info->need_blob != MagickFalse)
7368b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
7369b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
7370b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
73792b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
73842b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73872b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
73892b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
73904e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
73914e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
73922b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
73950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
73980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
74020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
74050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
74080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7412e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7414e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7416e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74188640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74208640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74228640fb5e9b1094f35f8beab436f81661b8a99448glennrp
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
74245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
7425dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
742626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
742826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
742926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
74303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
74313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
7434dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7435dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7439dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
7440dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
7441dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7443dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7446dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
7447dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution);
7448dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution);
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7450991d11dd9c33e65872778b81aff1347cd2878154glennrp
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7453dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
7454dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) image->x_resolution;
7455dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) image->y_resolution;
74563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7457991d11dd9c33e65872778b81aff1347cd2878154glennrp
7458991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
746026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7462a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
746326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
746426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
7465a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7467a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
7468a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
7469a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
7470a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
7471a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
7472a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
74730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7474a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
7475a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
74760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7477a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
7478a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
74790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7480a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
7481a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
74820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7483a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
7484a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
74850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7486a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
7487a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
74880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7489a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
7490a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
74910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
74920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
74943b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
74953b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74963b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
74973b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
74983b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74993b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
75003b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
75010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
750326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
75043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
75073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
75083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
75093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
75100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
75123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /* TO DO: make this a function cause it's used twice, except
75150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
75160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
75188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
75198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
75200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
75220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
75230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
75240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
75250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
75270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
75290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (int) number_colors, (int) image_colors);
75300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
75320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
75330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
75340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
75350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
75360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
75370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
75390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
75410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %5ld (%5d,%5d,%5d)",
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
75462b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
75478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
75488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
75498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
75505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
75518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (matte)
75528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
75530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
75540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
75550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
75560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
75578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
75608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
75610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          /* PNG8 can't have semitransparent colors so we threshold them
75638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           * to 0 or 255
75648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           */
75658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (; i < (ssize_t) number_semitransparent; i++)
75668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=image->colormap[i].opacity >
75678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                OpaqueOpacity/2 ? 0 : 255;
75680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75692cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
75708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
75710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
75730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
75740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
75768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
75778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
75780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp    if (ping_exclude_bKGD == MagickFalse)
75804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
75814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        /*
75824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         * Identify which colormap entry is the background color.
75834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         */
75844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
75854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
75864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
75870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
75894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
75910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
75955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
76015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
76070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
76110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
76135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
76152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
76168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
76178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      else /* write_ping_colortype not specified */
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76243c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
76250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7626d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
76278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
76280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7629d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7635d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
76383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
76393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76415aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
76425aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
76435aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
76445aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
76455f1c1fff2a55c4d8756556e78c1f307d352ed1b8cristy          if (image_info->type == UndefinedType ||
76468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             image_info->type == OptimizeType)
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76485aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
76498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
76505aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
76515aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
76525aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
76535aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
76545aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
76550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76565aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  else
76575aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
76585aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
76595aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
76605aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
76618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
76625aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
76635aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
76645aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
76655aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
76665aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
76675aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
76685aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
76698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
76705aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  else
76715aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
76725aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
76735aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
76745aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
76755aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
76760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
76775aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
76783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
768126c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76828640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
768326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
76845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
76850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
76860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
76870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
76880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
76890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
76900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7692d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
7693d6bf1617e99df0272b231855a933a74e99b6578fglennrp
76945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->matte == MagickFalse && image->colors < 256)
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ImageIsMonochrome(image))
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
77005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth=1;
77013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77048640fb5e9b1094f35f8beab436f81661b8a99448glennrp
77055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
770735ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
77085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
77090f111984738842d27d04aed2a3f823d82a943506glennrp
77100f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
77110f111984738842d27d04aed2a3f823d82a943506glennrp           {
77120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
77130f111984738842d27d04aed2a3f823d82a943506glennrp              (void) ThrowMagickException(&image->exception,
77140f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
77150f111984738842d27d04aed2a3f823d82a943506glennrp                "image has 0 colors", "`%s'","");
77160f111984738842d27d04aed2a3f823d82a943506glennrp           }
77170f111984738842d27d04aed2a3f823d82a943506glennrp
771835ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
77195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
7720d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7722d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
7723d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
7724d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7725d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
77260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7727d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7728d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
7729d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
77300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7731d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
7732d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
77355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
77362b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7740e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
77410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7743e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
77440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7746e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
77470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77493c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
77508640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
77518640fb5e9b1094f35f8beab436f81661b8a99448glennrp
77528640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7753e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
77543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (matte)
77573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
77594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
77622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_color != MagickFalse)
77644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             ping_color_type=PNG_COLOR_TYPE_RGBA;
77652b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
77674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
77694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
77704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
77714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
77724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
77734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
77744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
77754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_color_type&=0x03;
77764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
77770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
77794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
77804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
77814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                mask;
77823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
77840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
77864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
77870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
77894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
77900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
77924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
77930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
77954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
77960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
77984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
77990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
78014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
78020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
78044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
78050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
78074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(PixelIntensityToQuantum(
78084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
78090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
78110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
78134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
78140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
78164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
78174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
78184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                Determine if there is one and only one transparent color
78194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                and if so if it is fully transparent.
78204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
78214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (logging != MagickFalse)
78224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    "  Is there a single fully transparent color?");
78248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
78254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (number_transparent > 1 || number_semitransparent > 0)
78264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
78274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                ping_have_tRNS = MagickFalse;
78284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
78294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    "  ... No.");
78314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
78324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              else
78334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
78344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
78354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    "  ... Yes: (%d,%d,%d), (gray: %d)",
78374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (int) ping_trans_color.red,
78384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (int) ping_trans_color.green,
78394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (int) ping_trans_color.blue,
78404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (int) ping_trans_color.gray);
78414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
78424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
78432b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
78444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
78454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
78464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
78470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
78494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
78504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
78514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
78524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
78534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
78544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
78554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
78564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
78574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
78584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
78593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
78603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
78615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
78625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
78635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
78645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
78653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
78663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
78688640fb5e9b1094f35f8beab436f81661b8a99448glennrp
78693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
78700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78712e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
78730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
787439992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
78753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
78763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageIsGray(image) && (!image_matte || image_depth >= 8))
78773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
787835ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
78790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
78819c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
78820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
78843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
78864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
78873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
78884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
78894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
78904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
78914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
78934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
78944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
78954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
78963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
78970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
78993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
79000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
790235ef824baa82511126ff0072ae30eee0da9c05a3cristy          image_colors=one << image_depth;
79030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
79055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
79060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
79083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
79105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
79113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
79123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
79133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
79145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
79150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
791635ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
7917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
79185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
79193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
79203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79212b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
79230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
79243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
79253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
79263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
79283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
79293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
79313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
79323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7933bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
79343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
79363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
79373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
79413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
79420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
79443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
79450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
79473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
79483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
79492b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
79519c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
79520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
79549c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
79550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
79579c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
79583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
79602b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
79623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
79630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
79650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
79673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
796817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
796917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
79703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
79713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
79733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
79743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
79755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
79760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->have_write_global_plte && !matte)
79783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
79799c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
79800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79813b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
79829c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79839c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
79843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
79873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7988bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
79893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
79903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
79913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
79923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
79933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
79940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79953b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
79963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
799798156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
799898156a3a465a004545e39434c63052b955a74d1cglennrp                    (int) number_colors);
79990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
800039992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
80013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
80020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
8004d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
80053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8006befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
8007befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
8008befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
80095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
8010befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
80110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8012befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
80135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
80150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
80170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
80190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
80200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
8021d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
8022d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
80230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
80243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8025d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
8026d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
80273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
80290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
80300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8031d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
80320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
8033c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
8034c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
8035c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8036c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
8037c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
8038d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
8039d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8040d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
8041d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
8042d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       ping_trans_alpha[i]= (png_byte) (255-
8043d6bf1617e99df0272b231855a933a74e99b6578fglennrp                          ScaleQuantumToChar(image->colormap[i].opacity));
8044d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
80450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
80460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
80473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
80483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
80490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
80513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8052c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
80533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
80543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
80550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
80573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
80584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
80594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
80604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
80624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
80634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
80644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
80654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
80664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
80675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
80685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
80695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
80705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
80714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
80724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
80734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
80744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
80764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
80774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
80784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
80794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
80803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
80813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
80823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80834383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
80844383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
80852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
80863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
80873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
80883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
80895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
80903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
80913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
80923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
80933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
80943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
809535ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
809635ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
809735ef824baa82511126ff0072ae30eee0da9c05a3cristy
809822ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
80993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
810126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
81023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8103a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
81053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
81073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81083c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Setting up bKGD chunk (2)");
81093b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
8110991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
811126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
81123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
81145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
811617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
811726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
811826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
811917a1485544c62993fc7a94e343c87fed5f3e6407glennrp    if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
812017a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
812117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
812217a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
812317a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
812417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
812517a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
812617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8127a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
8128a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
812917a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
813017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
813117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
813217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
81333b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
81340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
81350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
81370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
8138a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
813913d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
8140a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
81410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
81423b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
81433b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
81440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
81450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
81470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
81480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
81490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
81500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
8151a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
815217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8153d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
81543c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
81553b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
81563b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81573b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
81583c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
81593c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
816017a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
816126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
816217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
81710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
81730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
81760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
81770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
81790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
81830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
81850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
81873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
81880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
81903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
81923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
81933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8194bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
81950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
81973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
81990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
82013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
82043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
82080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
82103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
82153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82162b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
82173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
82183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
82230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
82253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
82283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
82293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
82313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
82322b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
82343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
82353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
82363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
82388640fb5e9b1094f35f8beab436f81661b8a99448glennrp      base_filter=PNG_ALL_FILTERS;
82390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82408640fb5e9b1094f35f8beab436f81661b8a99448glennrp    else
82418640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if ((quality % 10) != 5)
82423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
82430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82448640fb5e9b1094f35f8beab436f81661b8a99448glennrp      else
82458640fb5e9b1094f35f8beab436f81661b8a99448glennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
82465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
82473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
82488640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_NO_FILTERS;
82490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82508640fb5e9b1094f35f8beab436f81661b8a99448glennrp        else
82518640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_ALL_FILTERS;
82520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
82553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
82563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
82583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
82593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
82613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
82622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
82633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
82643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
82653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8266c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  if (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse)
8267c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
8268c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
8269c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
82703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8271c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
82720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8273c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
8274c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
8275c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
8276c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
8277c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
827826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
8279c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
8280c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
8281c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
8282c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                       png_set_iCCP(ping,ping_info,(const png_charp) name,0,
8283c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
8284c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
8285c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
828626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
82870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8288c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
82893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8290c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
8291c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
8292c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  png_write_raw_profile(image_info,ping,ping_info,
8293c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
8294c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
8295c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
8296c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
8297c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
8298c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
8299c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
8300c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8301c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
83020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8303c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
8304c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
83053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
83063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
83083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
83093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
83103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
83113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
831226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
831326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
831426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
831526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
831626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
831726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
831826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
831926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
83200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
832126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
832226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            PNG_RenderingIntent_from_Magick_RenderingIntent(
832326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            image->rendering_intent)));
83240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
832526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_gAMA == MagickFalse)
832626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            png_set_gAMA(ping,ping_info,0.45455);
832726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
83283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
832926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
83305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
83313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
83323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83332cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
83342cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
833526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
833626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
83373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
83383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
83413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
83423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
83433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
83443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
83463b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
83473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
83483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
834926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
83502b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
835126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
83523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
835326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
835426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
835526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
835626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
835726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
835826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
835926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
836026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
836126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
836226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
836326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
836426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
836526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
836626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
836726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
836826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
836926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
837026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
837126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
837226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
837326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
837426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
837526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
837626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
837726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
837826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8380dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
83815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
83823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
83843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
83873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8388d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
83913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
83923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
83935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
83942b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
83965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
83973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
83980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
84003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
84015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
84023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
84050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
84065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
84073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
84085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
8409991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
84100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
84113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
84150e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
84160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
84180e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
84190e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
84203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
84213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
84243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
84255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
84263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
84270e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
84283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
84293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
84323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
84335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
84343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
84353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84360e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
84373bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
84383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
84393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84418640fb5e9b1094f35f8beab436f81661b8a99448glennrp  if (image_matte && !image->matte)
84423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
84443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
84453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
84460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8447b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
8448b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8449b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
84503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8452991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (image->matte == MagickTrue)
8453e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
8454991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
8455991d11dd9c33e65872778b81aff1347cd2878154glennrp        if (ping_color_type != 3 || ping_num_trans > 0)
8456c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
8457991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
8458c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
8459c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8460c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
8461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
8462e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
8463e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
84643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
84673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
84695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
84705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
84715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
84725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
847339992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
847439992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
847539992b4dd9b12ef752d55b8e402c069698851f72glennrp      png_set_PLTE(ping,ping_info,palette,(int) number_colors);
84760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84773b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
847839992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
84798640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
84800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
8481d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
84820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8483d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
8484d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
84850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
84860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
84870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
8488d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
84890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
84900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
84910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8492d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
84930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
84940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
84950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
84960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
84970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
849839992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
849939992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
850039992b4dd9b12ef752d55b8e402c069698851f72glennrp
850126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
850226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
850326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
850426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
850526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
8506991d11dd9c33e65872778b81aff1347cd2878154glennrp
850726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
8508dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
850926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
851026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
851126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
851226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
851326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
851426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
851526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
8516dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
8517dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8518dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
85194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
8520dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
852126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
852226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
852326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
852426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
8525dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
852626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
852726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
852826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
852926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
853026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
8531dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
8532dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
8533dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
85343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
8535991d11dd9c33e65872778b81aff1347cd2878154glennrp
853639992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
8537991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
85383b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
85390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
85400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
85420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
8543991d11dd9c33e65872778b81aff1347cd2878154glennrp
85440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
85450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
85460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
85470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
85480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
8549991d11dd9c33e65872778b81aff1347cd2878154glennrp
85500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
85510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
85520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
85530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
85540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
85550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
85560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85573b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
85580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
85590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8560c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
85610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
85620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
85630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
85640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
85650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
85660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
8567991d11dd9c33e65872778b81aff1347cd2878154glennrp
85683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
85694383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
85703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
8571991d11dd9c33e65872778b81aff1347cd2878154glennrp
85723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
85734383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
857526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
85763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
85784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
857926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
858026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
858126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
858226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
858326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
858426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
858503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
858626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
858726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
858826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
858926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
859026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
859126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
85923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
85959c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
85963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
85979c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
85983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
86023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
86043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
8606b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
8607b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
86087202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8610b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
86113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
8612b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8614b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
8615b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
8616b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8618b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
86193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
8620b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8622b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
8623b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86253b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
86263b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
86273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8628b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8629b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
86300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8631b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8632e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
86353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*png_pixels));
86360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
86383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
86390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
86473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
86483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
86493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
86513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
86533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
86543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
86563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
86573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8658f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
86593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8660b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      if (mng_info->need_blob != MagickFalse)
8661b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
8662b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
8663b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
86653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8666ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
8667ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
8668ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
86693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
86703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
86728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
86748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
86758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
86778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !image_matte && ImageIsMonochrome(image))
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
86803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
86813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
86820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
86843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
86863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
86873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
8689bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
86903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8691a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
86923241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp          if (logging != MagickFalse)
86933b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86943b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
8695a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
86970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
86993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
87000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
87023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
87053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
87063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
8710bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
87133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
87143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
87173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
87183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RedQuantum,png_pixels,&image->exception);
87203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
8723bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
87243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
87260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87273b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
8728b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8729b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
87300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
87343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
87363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
87373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
87383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
87403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
87433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
87463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image_matte ||
87475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
874839992b4dd9b12ef752d55b8e402c069698851f72glennrp         (mng_info->IsPalette) && ImageIsGray(image))
87493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
87508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
87518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
87520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
87543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8756bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
87573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
87592cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
87613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
87622cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
87643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
87658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
87663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,GrayQuantum,png_pixels,&image->exception);
87682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
87703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,RedQuantum,png_pixels,&image->exception);
87722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
87748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
8779b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
87803b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
8781b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
87832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
8786b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
87872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87883b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
8789b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
87912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
87933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
87968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
87978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
87988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
87998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
88008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
88018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
88028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
88030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
88053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
88068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
88078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
88080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
88128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
88138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
88148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
88158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
8816b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
88178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
88188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   &image->exception);
88192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
88218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
88222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
88248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
88258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
88268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        quantum_info,RedQuantum,png_pixels,&image->exception);
88282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
88308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        quantum_info,GrayQuantum,png_pixels,&image->exception);
88328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
88332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
88358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
88368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      quantum_info,GrayAlphaQuantum,png_pixels,
88388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      &image->exception);
88392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
88418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
88438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
88442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
88468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,RGBAQuantum,png_pixels,&image->exception);
88482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
88508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,RGBQuantum,png_pixels,&image->exception);
88522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88533b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
8854b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
88562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                png_write_row(ping,png_pixels);
8858b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
88598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
88602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
88628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
88638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
88648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
88658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
88668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
88678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
88688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
88698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
88708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
88722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
88748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
88758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
88762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
88788640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
88798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
88808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
88822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
88842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
88868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
88872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
88898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
8890d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       quantum_info,GrayQuantum,png_pixels,&image->exception);
88912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
88938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
88948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
88958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
88972cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
8899d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         quantum_info,GrayAlphaQuantum,png_pixels,
8900d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         &image->exception);
89018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
89022cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
89048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
89058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,IndexQuantum,png_pixels,&image->exception);
89062cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse && y <= 2)
89088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
89098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        "  Writing row of pixels (4)");
89112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        "  png_pixels[0]=%d,png_pixels[1]=%d",
89148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        (int)png_pixels[0],(int)png_pixels[1]);
89158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
89168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                png_write_row(ping,png_pixels);
89178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
89188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
89192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
89208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
89218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
89228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
89238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
89248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
89258640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
89263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
89288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
89298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8930b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
8931b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8936b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
89370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8939e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
89400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8942e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
89430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
89463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
89490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
89520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
89580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
89610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
896826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_tEXt == MagickFalse && ping_exclude_zTXt == MagickFalse)
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
897026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
897126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
897226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
897326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
897426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
897526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
89762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
897726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      value=GetImageProperty(image,property);
897826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (value != (const char *) NULL)
897926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
898026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
898126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].key=(char *) property;
898226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].text=(char *) value;
898326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].text_length=strlen(value);
89842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
898526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_tEXt != MagickFalse)
89864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
89872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
898826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          else if (ping_exclude_zTXt != MagickFalse)
89894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             text[0].compression=PNG_TEXT_COMPRESSION_NONE;
89902cc891a179d622dde7bbb8854138851e828bc6eaglennrp
899126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          else
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
89934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             text[0].compression=image_info->compression == NoCompression ||
89944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               (image_info->compression == UndefinedCompression &&
89954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
89964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               PNG_TEXT_COMPRESSION_zTXt ;
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
899926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
900026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
900126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
900226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up text chunk");
90032cc891a179d622dde7bbb8854138851e828bc6eaglennrp
900426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
900526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "    keyword: %s",text[0].key);
900626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
90072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
900826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_text(ping,ping_info,text,1);
900926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_free(ping,text);
901026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
901126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
901226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
90133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
90164383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
90210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
90230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
90275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
90285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
903803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
90453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
90463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
90473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
90483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
90495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
90503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
90525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
90533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
90580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
90633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
90643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
90670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
90715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9077f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9080b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  if (mng_info->need_blob != MagickFalse)
9081b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp     (void) CloseBlob(image);
9082b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9083b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=DestroyImageInfo(image_info);
9084b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image=DestroyImage(image);
9085b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9086b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
9087b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
9088b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
9089b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9090b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  (void) SetImageProperty(IMimage,"png:bit-depth-written",s);
9091b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
90950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
90973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
91233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
91323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
91333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
91373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparent).  The pixels contain 8-bit indices even if
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               they could be represented with 1, 2, or 4 bits. Note: grayscale
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
91403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               PNG grayscale type might be slightly more efficient.
91413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               one of the colors as transparent.
91453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
91473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
91490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
9154bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
9155bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
9156bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
91623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
91643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
91693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
91723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  If the image cannot be written without loss in the requested PNG8, PNG24,
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or PNG32 format or with the requested bit-depth and color-type without loss,
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a PNG file will not be written, and the encoder will return MagickFalse.
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transparency prior to attempting to write the image in a format that
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is subject to depth, color, or transparency limitations.
91823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
91873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
91953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
9198bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
9199bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
9204bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
92053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9206bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
92083241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
92090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
9210d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
92110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
92120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
92130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
92143241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%      transparent color first, if PNG_BUILD_PALETTE is defined.
92150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
9216d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
9217d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
9218d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      requested via the "-define PNG:bit-depth=N" option.
9219d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
9220d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
9221d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
9222d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
92230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
92243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
92263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
92273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
92283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
92293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
92303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
92343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
92363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
92373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
92393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
92403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
924126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  int
924226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    i;
924326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
92445c7cf4e469a4dad7e277783749155932252c52dfglennrp  int
92455c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
92465c7cf4e469a4dad7e277783749155932252c52dfglennrp
924703812ae402fb53d548f0e1d7d14720768f803c2dglennrp  MagickBooleanType
924803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding,
92493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
92503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
92523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
92533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
92543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
92553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
92563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
92573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
92583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
92593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
92613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
92623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
92633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
926473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
92650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
92673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
92680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
92703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
92713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
92723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
92733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
9274a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
92753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
92763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
92783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
92803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
92813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
92823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
92843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92859c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
92869c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
92879c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
92883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
92913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92929c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
92939c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
92949c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
92950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92969c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
92979c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
92980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92999c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
93009c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
93010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93029c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93079c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
93089c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
93099c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
93100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93119c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
93129c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
93130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93149c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
93159c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
93160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93179c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
93218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
93259c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
93260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
93289c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
93290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
93319c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
93320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
93349c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
93350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
93379c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
93380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9339bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
9340bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
9341bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
9342bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
9343bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
9344bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
93469c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9347bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
93510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
93569c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
93570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
93599c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
93600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
93629c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
93630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
93659c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
93660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
93689c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
93690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9370bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
9371bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
9372bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
9373bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
9374bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
9375bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
93779c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9378d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
93820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
93830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The default is to not exclude any chunks except for any
93840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
93850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
93860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Chunks can be listed for exclusion via a "PNG:exclude-chunk"
93870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
93880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
93890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
93900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
93910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
93920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
93930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
93940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * A "PNG:include-chunk" define takes  priority over both the
93950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * mng_info and the "PNG:exclude-chunk" define.  Like the
93960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
93970e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * well as a comma-separated list.
93980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
93990e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
94000e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
94010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
94020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
94040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
94050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
94060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
94080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
94090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
94100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
94110e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * artifact to "none,gama".
94120e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
94130e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
941426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
941526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
941626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
941726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
941826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
941926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
942026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
942126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
942226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
942326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
942426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
9425a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
942626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
942726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
942826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
942926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
943003812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
943103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
94325c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
94335c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
94345c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
9435acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
94365c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
9437acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
9438acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9439acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
9440acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
94415c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
9442acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
94435c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
944426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9445acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9446acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
9447acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
9448acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
944903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
945003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
945126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
945203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
945303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
945426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
945503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
945626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
945703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
94582cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
94592cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
94602cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94612cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
94622cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
94632cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94642cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
94652cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
946603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
946703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
946803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
946903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
947003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
947103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
947203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
947303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
947403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
947503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
947603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
947703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
947803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
947903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
948003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
948103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
948203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
948303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
9484a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
948503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
948603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
948703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
948803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
948903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
94902cc891a179d622dde7bbb8854138851e828bc6eaglennrp
949103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
949203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
949303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
949403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
949503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
949603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
949703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
949803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
949903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
950003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
950103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
950203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
9503a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
950403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
950503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
950603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
950703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
95082cc891a179d622dde7bbb8854138851e828bc6eaglennrp
950903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
951003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
95112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
951203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
951303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
95142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
951503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
951603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
95172cc891a179d622dde7bbb8854138851e828bc6eaglennrp
951803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
951903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
95202cc891a179d622dde7bbb8854138851e828bc6eaglennrp
952103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
952203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
95232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
952403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
952503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
952603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
952703812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
95282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
952903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
953003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
95312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
953203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
953303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
95342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
953503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
953603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
95372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9538a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
9539a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
95402cc891a179d622dde7bbb8854138851e828bc6eaglennrp
954103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
954203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
95432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9544a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
9545a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
9546a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
954703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
954803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
95492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
955003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
955103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
95522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
955303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
955403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
95552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
955603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
9557ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
955826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
955926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
95605c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
95615c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
95625c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
9563acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
95645c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
9565acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
9566acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9567acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
9568acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
95695c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
9570acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
95715c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
957226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9573acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9574acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
9575acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
9576acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
957703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
957803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
957903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
958003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
958126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
958203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
958326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
958403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
95852cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
95862cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
95872cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95882cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
95892cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
95902cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95912cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
95922cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
959303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
959403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
959503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
959603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
959703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
959803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
959903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
960003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
960103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
960203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
960303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
960403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
960503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
960603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
960703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
960803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
960903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
9610a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
961103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
961203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
961303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
961403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
961503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
96162cc891a179d622dde7bbb8854138851e828bc6eaglennrp
961703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
961803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
961903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
962003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
962103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
962203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
962303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
962403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
962503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
962603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
962703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
962803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
9629a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
963003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
963103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
963203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
963303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
96342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
963503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
963603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
96372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
963803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
963903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
96402cc891a179d622dde7bbb8854138851e828bc6eaglennrp
964103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
964203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
96432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
964403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
964503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
96462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
964703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
964803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
96492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
965003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
965103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
965203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
965303812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
96542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
965503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
965603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
96572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
965803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
965903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
96602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
966103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
966203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
96632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9664a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
9665a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
96662cc891a179d622dde7bbb8854138851e828bc6eaglennrp
966703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
966803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
96692cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9670a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
9671a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
9672a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
967303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
967403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
96752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
967603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
967703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
96782cc891a179d622dde7bbb8854138851e828bc6eaglennrp
967903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
968003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
96812cc891a179d622dde7bbb8854138851e828bc6eaglennrp
968203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
9683ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
968426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
968526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
968603812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
968726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
968826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
968926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      "  Chunks to be excluded from the output PNG:");
969026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
969126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
969226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
969326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
969426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
969526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
969626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
969726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
969826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
969926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
970026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
970126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
970226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
970326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
970426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
970526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
970626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
970726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
970826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
970926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
971026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
971126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
971226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
971326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
971426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
971526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
971626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
971726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
971826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
971926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
972026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
972126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
9722a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
9723a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9724a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
972526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
972626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
972726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
972826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
972926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
973026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
973126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
973226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
973326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
973426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
973526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9736b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
97373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9738b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  status=WriteOnePNGImage(mng_info,image_info,image);
97393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
97410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
97440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
97463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
97473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
97493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
97513ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
97523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
97533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
97543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
97553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
97563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
97583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
97593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
976103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
97623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
97633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
97653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
97663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
97683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
97693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
97703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
97713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
97733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
97743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
97753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
97763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
97773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9778bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
97793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
97803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
97823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOneJNGImage()");
97833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
97853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
97863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
97873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
97893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
97903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
97913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
97923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
97933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
97943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
97953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
97973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
97993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
98003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
98013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
98023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
98053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
98070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
98093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
98103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
98120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
98140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
98163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
98170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
98193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
98210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
98230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
98253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
98260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
98283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
98293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
98303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
98310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
98333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
98340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
98363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
98370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
98393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
98403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
98413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
98423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
98433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
98463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
98483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
98493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
98503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
98513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
98533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
98553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
98563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
98573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
98583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
98603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
98613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
98623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
98653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
98663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
98683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
98693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
98723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
98733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
98753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
98763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
98773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
98783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
98803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
98813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
98823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
98873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
98893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
98903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
98923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
9893f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
98943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
98950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9898e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
9899e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
99003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
99023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
99033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
99053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
99063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
99093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
99103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
991103812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
99124e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
99134e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
99143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
99153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
99163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
99173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
99183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
99193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
99203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
99213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
99223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
99233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
99243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9927f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
99280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9930f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
99310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
99340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
99370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
99400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
99430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
99460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
99490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
99520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
99553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
99584383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
99593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
99613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
99623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
99633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
99673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
99683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
99733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9975bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
99773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
99793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
99803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
99813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
9982bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
99833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
998403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
99853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
99863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
99883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
99903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
99913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
99923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
99933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
99943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
99953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
99963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
99973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
99993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
100013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
100023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
100033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
100043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1000503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
100060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
10008e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10009e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
10010e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
100110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
10013e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10014e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
10015e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
100160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
100183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
100193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
100233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
100243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
100253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
100263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
100273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
100283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1002903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1003035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
100313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
100323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
100333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
100340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
100363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
100373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
100383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
100393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
100403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
100423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
100433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
100443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
100453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1004603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
100473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1004835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1004935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
100503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1005135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1005235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
100533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1005435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1005535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
100563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1005735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1005835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
100593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
100613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
100623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
100653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
100673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
100683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
100693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
100703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1007103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
100723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
100733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1007435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
100753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
100760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1007735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
100783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
100790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
100813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
100820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
100843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
100853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
100863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1008735ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
100883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
100890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1009035ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
100913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
100920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
100943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
100950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
100973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1009835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1009935ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
101003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
101013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
101023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
101033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
101043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
101053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
101083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
101103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
101113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
101123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
101133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1011403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
10115bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
10116bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
101173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
101183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
101193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
101203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
101223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
101243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1012503812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
101263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
101273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
101283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
101303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
101313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
101353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
101373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10138bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
101393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
101403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10141bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
101423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
101433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
101453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
101463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10147e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
10148f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
101493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
101513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
101523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
10153bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
101543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
101553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
101570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
101593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
101603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
10161bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1016203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
101633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
101643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
101653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
101663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
101670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
101693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
101703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
101713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10172e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
10173e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
101743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
101753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
101763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
101773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
101783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
101793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
101803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
101813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
101823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10183e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
10184bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
101853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1018603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
101873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
101883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
101893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
101913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
101923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
101933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
101943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
101973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
102003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
102013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
102023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
102033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
102073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
102093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
102103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
102113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
102123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
102143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
102153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
102163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
102183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
102193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10222e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
10223e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
102243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
102263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
102270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
102293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
102303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
102310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
102350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
102370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10241e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
10242e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
102433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10245e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
102463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
10249bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
102503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1025103812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
102523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
102533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
102543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
102553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
102573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
102583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
102593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
102603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
102624383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
102633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
102653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
102663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1026703812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
102683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
102693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
102703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
102740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
102763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
102773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
102803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
102823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
102833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
102843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
102853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
102863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
102873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
102883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
102903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
102913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
102923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
102933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
102943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
102953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
102963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
102973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
102983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
102993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
103013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
103033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
103043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
103063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
103073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
103083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1030903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
103103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
103113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
103133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
103143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
103163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
103173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
103193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
103203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
103213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
103223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
103233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
103243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
103253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
103263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
103273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
103283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
103293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
103303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
103323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
103333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
103343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1033573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
103363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
103373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
103383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
103393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
103403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
103413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
103423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
103433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
103443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
103463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
103483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
103493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
103513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
103523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
103533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
103543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
103553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
103563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
103573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103603ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
103613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
103623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
103633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
103643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
103663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
103673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
103693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
103703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1037103812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1037203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1037303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
103743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
103753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
103763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
103783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
103793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
103803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
103813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
103823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
103843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
103853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
103863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
103873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
103883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
103893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
103903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
103913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10392bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
103933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
103943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
103963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
103973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
103993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
104003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
104013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10402bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
104033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
104043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10405bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
104063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
104073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
104083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10409d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
104103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
104113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
104123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
104133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
104143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
104173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
104183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
104193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
104203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
104213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
104223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
104233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
104243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
104253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
104263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
104273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
104303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
104313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1043273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
104333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
104343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
104353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
104373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
104383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
104393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
104403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
104413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
104423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
104443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
104453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
104463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
104473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
104483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
104493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
104503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
104513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
104523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
104533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
104553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
104563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
104573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
104593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
104603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
104613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
104633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
104643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
104663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
104673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
104683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
104693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
104703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
104730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10475e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
104760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
104793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
104813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
104823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
104833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10484e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
104850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10487e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
104880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
104903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
104920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
104943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
104960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
104983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
105000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
105023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
105040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
105063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10507e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
105080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
105103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
105120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
105143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
105153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
105163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
105173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
105193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
105203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
105213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
105223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
105233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
105243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
105253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
105263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
105273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
105293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
105303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
105323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
105333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
105343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
105353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
105363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
105373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
105383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
105393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
105413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
105423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
105443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
105453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
105463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
105473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
105493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
105503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
105513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
105523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
105533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
105543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
105553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
105563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
105573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
105583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
105593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
105603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
105613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
105623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
105633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
105643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
105653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
105663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
105673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
105693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
105703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
105723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
105733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
105743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
105750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
105773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
105783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
105790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
105820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
105843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
105850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
105873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
105883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
105893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
105903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
105910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
105940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
105960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
105983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
105993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
106000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
106023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
106033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
106043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
106053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
106063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
106080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
106103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
106113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
106123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
106143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
106153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
106183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
106193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
106203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
106223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
106233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
106253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
106280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
106303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
106310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
106333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
106350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
106383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
106393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
106400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
106423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
106433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
106443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
106453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
106463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
106473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
106483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
106493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
106503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
106513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
106523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
106533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
106543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
106553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
106563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
106573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
106583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
106593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
106603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
106613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
106623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
106633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
106643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
106653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
106663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
106683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
106693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
106703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
106713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
106723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
106733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
106743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
106753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
106763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
106773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
106780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
106803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
106813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
106823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
106833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
106843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
106853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
106863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
106873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
106883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
106893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
106903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
106913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
106920261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
10693d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
10694d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
10695d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
10696d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
10697d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
10698d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
10699d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
107013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
107043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
107054e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->ticks_per_second=(png_uint_32) (image->ticks_per_second/final_delay);
107063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
107080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
107103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
107110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
107133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
107140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
107163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
107173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
107183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
107210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
107233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
107243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
107283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
107293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
107303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
107323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
107333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1073503812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
107364e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
107374e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
107383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
107463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
107480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
107520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
107563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
107570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
107603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
107613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
107620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
107690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
107713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
107730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
107773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
107780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
107803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
107833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
107843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
107853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
107873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
107883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
107893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
107933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
10796bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1079703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
107983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
108013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
108033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
108043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
108073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
108083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
108103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1081103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
108160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
108190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
108220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
108243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
108253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10826e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
10827e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
108280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10831e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
108320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
108343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10835e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
108363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
108373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
108393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
108403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
108413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
108423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
108483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
108493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1085103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
108520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
10854e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
10855e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
10856e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
108570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
10859e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
10860e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
10861e610a071534e448c46460a5aa39ede33bf56b329glennrp             (PerceptualIntent));
108620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
108670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
108693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
108753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1087703812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1087835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
108793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
108823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
108833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
108923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1089303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
108943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1089535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1089635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
108973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1089835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1089935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1090135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1090235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
109033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1090435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1090535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
109063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
109073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
109083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
109093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
109103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
109113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
109123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
109133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
109143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
109163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
109173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1091803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
109190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
109213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1092235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
109233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
109240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1092535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
109263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
109270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
109300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
109323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
109333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
109343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1093535ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
109370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1093835ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
109393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
109400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
109423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
109430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
109453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1094635ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1094735ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
109503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
109513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
109573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
109583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
109593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
109603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
109613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
109623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
109643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
109653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1096603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
109673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
109693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
109703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
109713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
109723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
109733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
109743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
109753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
109763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
109773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
109783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1097903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
109803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
109813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
109823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
109833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
109843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
109863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
109873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
109883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
109893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
10990bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
109913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
109923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
109943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
109953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
109963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
109973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
109983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1099903812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
110000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11001bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
110023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
110033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
110043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
110053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
110063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
110070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
110093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
110103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
110113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
110123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
110133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
110153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
110183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
110193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
110203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
110233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
110253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
110263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
110273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
110283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
110293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
110303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
110313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
110323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
110333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
110343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
110353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
110363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
110383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
110393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
110403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
110413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
110423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
110433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
110443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
11045bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
110463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
110473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
110493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
110503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1105103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
110520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11053bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
110543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
110553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
110563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
110573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
110583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
110590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
110613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
110623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
110633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
110643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
110653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
110673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
110683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
110693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
110703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
110713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11072bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
110733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
110743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
110753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
110773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
110783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
110793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
110803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
110833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
110843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
110853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
110873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
110883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
110893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
110903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1109203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
110933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
110943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
110953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
110963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
111023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
111113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
111123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
111143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
111153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
111173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
111183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
111193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1112103812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
111233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
111243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
111253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
111263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
111273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
111283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
111293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
111303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
111313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
111323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1113303812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
111343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
111353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
111363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
111373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
111383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
111393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
111403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
111413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
111423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
111433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
111443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
111454e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
111463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
111473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
111483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
111493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
111513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
111523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
111533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
111543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
111553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
111573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
111593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
111603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
111613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
111623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
111633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
111643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
111653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
111663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
111673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
111683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
111693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
111712f2e514554975d510c88df54de98c6cdc1080f1cglennrp
11172b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
111732f2e514554975d510c88df54de98c6cdc1080f1cglennrp
111742f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
111752f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
111762f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
111772f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
111782f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
111792f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
111802f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
111812f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
111822f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
111832f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
111842f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
111852f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
11186a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
111872f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
111882f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
111892f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
111902f2e514554975d510c88df54de98c6cdc1080f1cglennrp
111913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
111923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
111933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
111953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
111963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
111973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
111983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
111993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
112003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
112013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
112023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
112033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
112043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
112060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
112083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
112090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
112110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
112163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
112183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1122103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
112293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
112300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
112330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
112353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11236d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1123739992b4dd9b12ef752d55b8e402c069698851f72glennrp
112383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
112393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
112403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
112413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
112430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
112453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
112463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1124739992b4dd9b12ef752d55b8e402c069698851f72glennrp
112483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
112493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
112503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
112513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11252d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
112533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11254