png.c revision 2cc891a179d622dde7bbb8854138851e828bc6ea
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,
47726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
47826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
47926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt;
48026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4890c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4920c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
4990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
5010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
5028640fb5e9b1094f35f8beab436f81661b8a99448glennrp  LosslessReduceDepthOK(Image *image)
5030c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
5040c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    MagickBooleanType
5050c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      ok_to_reduce=MagickFalse;
5060c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5070c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    /* Reduce bit depth if it can be reduced losslessly from 16 to 8.
5080c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * Note that the method GetImageDepth doesn't check background
5090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * and doesn't handle PseudoClass specially.  Also it uses
5100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * multiplication and division by 257 instead of shifting, so
5110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * might be slower.
5120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     */
5130c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5140c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    if (image->depth == 16)
5150c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
5160c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5170c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        const PixelPacket
5180c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
5190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5200c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
5210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          (((((size_t) image->background_color.red >> 8) & 0xff)
5228640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.red & 0xff)) &&
5230c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp           ((((size_t) image->background_color.green >> 8) & 0xff)
5248640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.green & 0xff)) &&
5250c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp           ((((size_t) image->background_color.blue >> 8) & 0xff)
5268640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.blue & 0xff))) ? MagickTrue :
5278640fb5e9b1094f35f8beab436f81661b8a99448glennrp          MagickFalse;
5280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
5300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
5320c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
5340c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5358640fb5e9b1094f35f8beab436f81661b8a99448glennrp                ok_to_reduce=(((((size_t) image->colormap[indx].red >>
5368640fb5e9b1094f35f8beab436f81661b8a99448glennrp                    8) & 0xff)
5378640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].red & 0xff)) &&
5380c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].green >> 8) & 0xff)
5398640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].green & 0xff)) &&
5400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].blue >> 8) & 0xff)
5418640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].blue & 0xff)) &&
5420c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].opacity >> 8) & 0xff)
5438640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].opacity & 0xff))) ?
54413d07043243e0c8c151aad7db5240b75e76ca281cristy                  MagickTrue : MagickFalse;
5450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
5510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
5520c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5530c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
5540c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
5550c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5560c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
5570c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
5580c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5590c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
5600c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
5610c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5620c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5630c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              if (p == (const PixelPacket *) NULL)
5640c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
5650c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
5660c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5670c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
5680c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5690c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
5700c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5718640fb5e9b1094f35f8beab436f81661b8a99448glennrp                ok_to_reduce=((
5728640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((size_t) p->red >> 8) & 0xff) ==
5738640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->red & 0xff)) &&
5740c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) p->green >> 8) & 0xff) ==
5758640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->green & 0xff)) &&
5760c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) p->blue >> 8) & 0xff) ==
5778640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->blue & 0xff)) &&
5788640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((!image->matte ||
5798640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((size_t) p->opacity >> 8) & 0xff) ==
5808640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->opacity & 0xff))))) ? MagickTrue : MagickFalse;
5810c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5830c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5850c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                p++;
5860c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5878640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
5880c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
5890c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
5900c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5910c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5920c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
5930c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5958640fb5e9b1094f35f8beab436f81661b8a99448glennrp                "  OK to reduce PNG bit depth to 8 without loss of info");
5960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
5980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
6000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
6010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
6020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
603e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
604e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_from_Magick_RenderingIntent(const RenderingIntent intent)
6050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
606e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
607e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
608e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
609e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
6100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
611e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
612e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
6130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
614e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
615e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
6160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
617e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
618e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
6190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
620e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
621e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
622e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
623e610a071534e448c46460a5aa39ede33bf56b329glennrp}
624e610a071534e448c46460a5aa39ede33bf56b329glennrp
625e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
626e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_to_Magick_RenderingIntent(const int png_intent)
6270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
628e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (png_intent)
629e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
630e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
631e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
6320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
633e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
634e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
6350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
636e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
637e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
6380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
639e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
640e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
6410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
642e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
643e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
644e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
645e610a071534e448c46460a5aa39ede33bf56b329glennrp}
646e610a071534e448c46460a5aa39ede33bf56b329glennrp
647bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6540c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
655bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6620c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
663dbb105fc25903e800273f7e980c0553060858a68glennrp
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
669dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s G r a y                                                     %
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
674dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
675dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
676dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
677dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
679dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsGray(Image *image)
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
684bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
686dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
687dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
692dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
693dbb105fc25903e800273f7e980c0553060858a68glennrp
694dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
696dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
697dbb105fc25903e800273f7e980c0553060858a68glennrp        if (IsGray(image->colormap+i) == MagickFalse)
698dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
699dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickTrue);
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
701bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
705dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
706dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
707dbb105fc25903e800273f7e980c0553060858a68glennrp    {
708dbb105fc25903e800273f7e980c0553060858a68glennrp       if (IsGray(p) == MagickFalse)
709dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
710dbb105fc25903e800273f7e980c0553060858a68glennrp       p++;
711dbb105fc25903e800273f7e980c0553060858a68glennrp    }
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
713dbb105fc25903e800273f7e980c0553060858a68glennrp  return(MagickTrue);
714dbb105fc25903e800273f7e980c0553060858a68glennrp}
715dbb105fc25903e800273f7e980c0553060858a68glennrp
716dbb105fc25903e800273f7e980c0553060858a68glennrp/*
717dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
718dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
719dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
720dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
721dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s M o n o c h r o m e                                         %
722dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
723dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
724dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
725dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
726dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
727dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
728dbb105fc25903e800273f7e980c0553060858a68glennrp%   and is more accurate.                                                     %
729dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
730dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
731dbb105fc25903e800273f7e980c0553060858a68glennrp*/
732dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsMonochrome(Image *image)
733dbb105fc25903e800273f7e980c0553060858a68glennrp{
734dbb105fc25903e800273f7e980c0553060858a68glennrp  register const PixelPacket
735dbb105fc25903e800273f7e980c0553060858a68glennrp    *p;
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
737dbb105fc25903e800273f7e980c0553060858a68glennrp  register ssize_t
738dbb105fc25903e800273f7e980c0553060858a68glennrp    i,
739dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
740dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
741a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
742dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image != (Image *) NULL);
743dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image->signature == MagickSignature);
744a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if (image->debug != MagickFalse)
745dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
746dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
747a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp    {
748dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
749dbb105fc25903e800273f7e980c0553060858a68glennrp      {
750dbb105fc25903e800273f7e980c0553060858a68glennrp        if ((IsGray(image->colormap+i) == MagickFalse) ||
751dbb105fc25903e800273f7e980c0553060858a68glennrp            ((image->colormap[i].red != 0) &&
752dbb105fc25903e800273f7e980c0553060858a68glennrp             (image->colormap[i].red != (Quantum) QuantumRange)))
753dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
754dbb105fc25903e800273f7e980c0553060858a68glennrp      }
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
757dbb105fc25903e800273f7e980c0553060858a68glennrp  for (y=0; y < (ssize_t) image->rows; y++)
758dbb105fc25903e800273f7e980c0553060858a68glennrp  {
759dbb105fc25903e800273f7e980c0553060858a68glennrp    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
760dbb105fc25903e800273f7e980c0553060858a68glennrp    if (p == (const PixelPacket *) NULL)
761dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
762dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsGray(p) == MagickFalse)
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->opacity != OpaqueOpacity) &&
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (p->opacity != (Quantum) TransparentOpacity))
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
779d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
897d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
898bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
920a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
928a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94103812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
94203812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
946e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
947e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
949d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
955d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
1069e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1070e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1098bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
11140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
11170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1174bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
11750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1189bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
12000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1201bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
12230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
12280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1241bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1243bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1251bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
12560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
12600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
12740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
12770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
12800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
12830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1295bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1296bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1297bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1298bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1316bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
13188182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
13198182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
13200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13308182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13328182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGErrorHandler(png_struct *ping,png_const_charp message)
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
13410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
13450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
13480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1349faa852bad40107edae19405e76a299057668d795glennrp#if PNG_LIBPNG_VER < 10500
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1351faa852bad40107edae19405e76a299057668d795glennrp#else
1352faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1353faa852bad40107edae19405e76a299057668d795glennrp#endif
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGWarningHandler(png_struct *ping,png_const_charp message)
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
13630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1367cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
13680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
13820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
13850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_read_raw_profile(Image *image, const ImageInfo *image_info,
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1412bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1445f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
14460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
14590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
14710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1472bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
14880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
14970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
15000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1534bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
15360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1537bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
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
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
160305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp  UShortPixelPacket
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent_color;
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1606faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1607faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1608faa852bad40107edae19405e76a299057668d795glennrp
1609faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1610faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1611faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1612faa852bad40107edae19405e76a299057668d795glennrp
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1623faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1624faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1625faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
1626faa852bad40107edae19405e76a299057668d795glennrp    ping_rowbytes;
1627faa852bad40107edae19405e76a299057668d795glennrp
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1634bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
16415c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1643bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
165139992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOnePNGImage()");
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1670f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
167325c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
167961b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
168061b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
168161b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
168261b4c957269727a0a2526edc2331881da8346100glennrp    {
168361b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
168461b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
168561b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
168661b4c957269727a0a2526edc2331881da8346100glennrp    }
168761b4c957269727a0a2526edc2331881da8346100glennrp#  endif
168861b4c957269727a0a2526edc2331881da8346100glennrp#endif
168961b4c957269727a0a2526edc2331881da8346100glennrp
169061b4c957269727a0a2526edc2331881da8346100glennrp
1691ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   PNGErrorHandler,PNGWarningHandler, NULL,
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
17090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
17170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
17250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1726faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1733f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
17380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
17407b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
17417b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
17427b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
17437b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
17440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1750faa852bad40107edae19405e76a299057668d795glennrp
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
17530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1786991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1787991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1788991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1802991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1806faa852bad40107edae19405e76a299057668d795glennrp
1807faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1808faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1809faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1810faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1811faa852bad40107edae19405e76a299057668d795glennrp
1812faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1813faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1814faa852bad40107edae19405e76a299057668d795glennrp
1815faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1816faa852bad40107edae19405e76a299057668d795glennrp
1817faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1819faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1820faa852bad40107edae19405e76a299057668d795glennrp        {
1821faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1822faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1823faa852bad40107edae19405e76a299057668d795glennrp        }
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1825faa852bad40107edae19405e76a299057668d795glennrp
1826faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1828faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1832e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1833e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
18340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1837faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
18380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1841faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
18420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1845faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1848faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1849faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        info,
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1885e610a071534e448c46460a5aa39ede33bf56b329glennrp      image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1886e610a071534e448c46460a5aa39ede33bf56b329glennrp        mng_info->global_srgb_intent);
18870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1890e610a071534e448c46460a5aa39ede33bf56b329glennrp        image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1891e610a071534e448c46460a5aa39ede33bf56b329glennrp          intent);
18920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1895e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1903faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1904faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1905faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
19060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1915faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1916faa852bad40107edae19405e76a299057668d795glennrp    {
1917faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1918faa852bad40107edae19405e76a299057668d795glennrp        {
1919faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1920faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1921faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1922faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1923faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1924faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1925faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1926faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1927faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1928faa852bad40107edae19405e76a299057668d795glennrp        }
1929faa852bad40107edae19405e76a299057668d795glennrp    }
19300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1931faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1948e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1950e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
1951e610a071534e448c46460a5aa39ede33bf56b329glennrp         PNG_RenderingIntent_from_Magick_RenderingIntent(
1952e610a071534e448c46460a5aa39ede33bf56b329glennrp         image->rendering_intent));
1953faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
1954faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
1955faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
1956faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
1959faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=png_get_x_offset_pixels(ping, ping_info);
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=png_get_y_offset_pixels(ping, ping_info);
19630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1967e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
1968e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
1972faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
1973faa852bad40107edae19405e76a299057668d795glennrp    {
1974faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
1975faa852bad40107edae19405e76a299057668d795glennrp        {
1976faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
1977faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
1978faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
1979faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
1980faa852bad40107edae19405e76a299057668d795glennrp        }
1981faa852bad40107edae19405e76a299057668d795glennrp    }
1982faa852bad40107edae19405e76a299057668d795glennrp
1983faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
19960881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
19970881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
19980881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
19990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2009e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2010e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2013faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
20220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2024faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
20300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2031faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2048faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2057faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2058faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
20590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
2081faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2082faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2085faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
20930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20942cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2096faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
2097faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
2098faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21012cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21032cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
21042cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
21052cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21062cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21072cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21082cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
21092cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
21102cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21112cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
21120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21132cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
21142cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
21150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21162cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
21172cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
21180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21192cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
21202cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
21210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21222cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
21232cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
21242cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21252cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
21262cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
21272cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
21282cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21292cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21302cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
21312cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21322cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
21330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21342cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21352cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
21362cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
21372cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
21382cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
2140faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
21410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
2143faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
21440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
2146faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
21470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2148f17da7472c6195cfc91626d98d166cae04345d34cristy          image->background_color.opacity=OpaqueOpacity;
21492cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21502cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21512cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2152e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
2153e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
2154e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
2155e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.red=0;
21603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.green=0;
21613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.blue=0;
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.opacity=0;
2163faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
21703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
217135ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
217235ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
217335ef824baa82511126ff0072ae30eee0da9c05a3cristy
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2178f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2180faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2181faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2182faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2183faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2184faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2185faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2191faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
219605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.red= (unsigned short)(ping_trans_color->red);
219705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.green= (unsigned short) (ping_trans_color->green);
219805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.blue= (unsigned short) (ping_trans_color->blue);
219905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.opacity= (unsigned short) (ping_trans_color->gray);
220005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2201faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
22030f111984738842d27d04aed2a3f823d82a943506glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22040f111984738842d27d04aed2a3f823d82a943506glennrp              if (ping_bit_depth < MAGICKCORE_QUANTUM_DEPTH)
22050f111984738842d27d04aed2a3f823d82a943506glennrp#endif
220605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp              transparent_color.opacity=(unsigned short) (
22070f111984738842d27d04aed2a3f823d82a943506glennrp                  ping_trans_color->gray *
220805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                  (65535L/((1UL << ping_bit_depth)-1)));
22090f111984738842d27d04aed2a3f823d82a943506glennrp
221005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
221105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp              else
221205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                transparent_color.opacity=(unsigned short) (
221305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                    (ping_trans_color->gray * 65535L)/
221405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                   ((1UL << ping_bit_depth)-1));
22150f111984738842d27d04aed2a3f823d82a943506glennrp#endif
22160f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
22170f111984738842d27d04aed2a3f823d82a943506glennrp              {
22180f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22190f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
22200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22210f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22220f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
22230f111984738842d27d04aed2a3f823d82a943506glennrp              }
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2233faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2238faa852bad40107edae19405e76a299057668d795glennrp
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2240faa852bad40107edae19405e76a299057668d795glennrp
2241faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2242faa852bad40107edae19405e76a299057668d795glennrp
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2247bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2249bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2252faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2253faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2264faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2265faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2266faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2267faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2268faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2270befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2271befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2272befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2274befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2275befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2283faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2292bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
22930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2308faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
23170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2318bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
23250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2328bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2331faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
23320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
23350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2336bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
23393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
23490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23500ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2351347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2352347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2356e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2360f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
23650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
23720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2375faa852bad40107edae19405e76a299057668d795glennrp      ping_rowbytes*sizeof(*png_pixels));
23760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2378faa852bad40107edae19405e76a299057668d795glennrp    png_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sizeof(*png_pixels));
23800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2390faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2397f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
23983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
24010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
24040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
24080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
24107b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
24117b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
24127b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
24137b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
24140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2418ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
24190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2420ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2421ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
24243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
24253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
24273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert image to DirectClass pixel packets.
24283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
24293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
24303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        depth;
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2433bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      depth=(ssize_t) ping_bit_depth;
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2435faa852bad40107edae19405e76a299057668d795glennrp      image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2436faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2437faa852bad40107edae19405e76a299057668d795glennrp          (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2438faa852bad40107edae19405e76a299057668d795glennrp          MagickTrue : MagickFalse;
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2440bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2443faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
24440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
24470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
2449abc8f408bb48da2d73cb760d61f16063695081d2cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
24500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (depth == 16)
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register Quantum
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *p,
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r;
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            r=png_pixels+row_offset;
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=r;
2462faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2464bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
2468faa852bad40107edae19405e76a299057668d795glennrp                  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS)) &&
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (((*(p-2) << 8)|*(p-1)) == transparent_color.opacity))
24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2478faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_RGB)
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2480faa852bad40107edae19405e76a299057668d795glennrp              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2481bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
24823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if ((((*(p-6) << 8)|*(p-5)) == transparent_color.red) &&
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-4) << 8)|*(p-3)) == transparent_color.green) &&
24913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-2) << 8)|*(p-1)) == transparent_color.blue))
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
24963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
24983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2500bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
25013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
25023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
25033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
25043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
25053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
25063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
25073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=OpaqueOpacity;
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
25103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2512faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2513bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (4*image->columns); x != 0; x--)
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
25173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2519faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2520bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (2*image->columns); x != 0; x--)
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2526faa852bad40107edae19405e76a299057668d795glennrp        if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_GRAY)
25273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset);
25290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2530faa852bad40107edae19405e76a299057668d795glennrp        if (ping_color_type == PNG_COLOR_TYPE_GRAY ||
2531faa852bad40107edae19405e76a299057668d795glennrp            ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GrayAlphaQuantum,png_pixels+row_offset);
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2538faa852bad40107edae19405e76a299057668d795glennrp        else if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_RGB)
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             RGBQuantum,png_pixels+row_offset);
25410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2542faa852bad40107edae19405e76a299057668d795glennrp        else if (ping_color_type == PNG_COLOR_TYPE_RGB ||
2543faa852bad40107edae19405e76a299057668d795glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
25463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RGBAQuantum,png_pixels+row_offset);
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2550faa852bad40107edae19405e76a299057668d795glennrp        else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              IndexQuantum,png_pixels+row_offset);
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
25540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2555faa852bad40107edae19405e76a299057668d795glennrp        if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset,exception);
25580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2559faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayAlphaQuantum,png_pixels+row_offset,exception);
25620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2563faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBAQuantum,png_pixels+row_offset,exception);
25660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2567faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexQuantum,png_pixels+row_offset,exception);
25700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBQuantum,png_pixels+row_offset,exception);
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
25757a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
25767a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2577cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2578cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
25790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25807a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
25817a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
25827a287bfadeadea12e47c2376ca78a5d101687142cristy          }
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25877a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2607faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
26090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
26120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
26150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2616bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2619faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
26240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26285c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
26293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=png_pixels+row_offset;
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2631faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2635bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2638bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2647bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
265347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2656bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2666bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
267247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2675bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
26830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
268647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2689faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2690bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
27010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2703bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
27050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
270847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2711bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2714bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
27190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
27220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
272747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2728faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2737bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
27420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
27450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
27500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2751faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity*=65537L;
275546f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
275947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
276347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2764faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
277347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
277647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
27840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2785bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
278680ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
27870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
27900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27917a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
27927a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2793cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2794cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
279547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27967a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
27977a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
27987a287bfadeadea12e47c2376ca78a5d101687142cristy          }
27993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
28007a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
280347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
28053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
28063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2809b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2810b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
28110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28125c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
28135c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2814aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
28155c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
28165c6f789db7a30bad01ace12b09ad9cd471339e94cristy
28175c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
28185c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
28195c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2820aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
28215c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
282247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
28243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2826bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
28273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
28293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2833f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
28343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
28383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
284047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2841faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
28453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2851c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28523c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
2853c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
28550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2857c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
28580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
28590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 image->colormap[x].opacity =
28610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                   ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
28620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
2863c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
286447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
28670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
28680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
28700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                     transparent_color.opacity)
28710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
28720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    image->colormap[x].opacity = (Quantum) TransparentOpacity;
28730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
28740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
28750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) SyncImage(image);
28770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
287847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
28800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
28820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
28830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
28840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2885c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (q == (PixelPacket *) NULL)
28870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
2888c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            indexes=GetAuthenticIndexQueue(image);
28900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
28920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
28930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              if (ScaleQuantumToShort(q->red) == transparent_color.red &&
28940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ScaleQuantumToShort(q->green) == transparent_color.green &&
28950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ScaleQuantumToShort(q->blue) == transparent_color.blue)
28960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  q->opacity=(Quantum) TransparentOpacity;
28970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
2899d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 q->opacity=(Quantum) OpaqueOpacity;
29000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              q++;
29020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
29030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
29050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
2906c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
29070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
2908c11cf6a442f3046940608a5743a68cc891deb13eglennrp
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29113c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
2912b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2913b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2914b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
291547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
2917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) num_text; i++)
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
29240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_read_raw_profile(image,image_info,text,(int) i);
29270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
29460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
29500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29543c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
296773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
29680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
297547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
29830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
29960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
29990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
30020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
30070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3008faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
30100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3011faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3012faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3013faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3014faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3015faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3016faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3017faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3018faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
30190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3020faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
30333c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
303947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3052f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
30580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
30603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
30753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
30773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
30823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
30853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
30903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
309147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
309547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
30983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
310247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
310547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
311047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
311347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
311873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
311947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
312247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
313347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
31400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
31480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
315147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
315347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
31590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
316247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
31660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
317247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
31810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
31840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3236bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3259bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3275bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOneJNGImage()");
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
32920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
33010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
33030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
33060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
33340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
33370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3345e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3346e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
33500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
335347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
33570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
33600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3361bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
33630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
336647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
337347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3381bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3383bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
338947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
339247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
339747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3401f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
340247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3404f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
340547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
340847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
341247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
341647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
342047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
342447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
342847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
343247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
343847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
344147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
345773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
345847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
346147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
34640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
34710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
34750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
348273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
34830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
34890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
35000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
35040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
35070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
35160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
35190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
352203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
353947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
354647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
354947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
355847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3566bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
356803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
358347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
36030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
36338182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
36340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36438182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
36448182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
36458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
36468182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
36478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
36488182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
36498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
36508182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
365247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3661e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3662e610a071534e448c46460a5aa39ede33bf56b329glennrp              PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
367347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36828182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.x=mng_get_long(p);
36838182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.y=mng_get_long(&p[4]);
36840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
369147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37028182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
37038182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
37110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* To do. */
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
37320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
376147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
37650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
37680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
37710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
37850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
37890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3790bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
379547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
38010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
381203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
38160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
38180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
38270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3829bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
383447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3836bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
38380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3840bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
38460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
385847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
385947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
38670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
38690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
38700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
38730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
38750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
38760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
38790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
38810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
38860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
38900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
39590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
39620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
396647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
396747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
396947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
397347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
397447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
397673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
39770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
398147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
398247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
39900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
39980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
40020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
400647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
40120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
40180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4042bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4067bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4073bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4090bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
409938ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
410038ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
410138ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4102bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
412447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
412547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
41350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
41380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
414247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
414347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
414447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
414573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
41460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
41490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
415047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
415147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
416147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
416547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
416647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4169bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4170bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
417447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4217e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4218e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
42220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
42250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
42280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
423247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
423547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4236bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
423847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
42480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
42520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
42590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
42630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
426847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
42730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
42800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4286bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
42880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4289bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
42910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4295e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4297e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
43018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
43020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
43050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
43090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
43120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
43168182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
43200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
43230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
43260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
433347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
43350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
43380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
43460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4347e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4348e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4349f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
43500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4354bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
43560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
43590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
43720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43758182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
43768182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
43770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
43800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
43890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4391e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
43920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4394e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
44060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
44080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
44130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
44370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
44400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
44470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
44480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
44500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
44510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4455e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4456f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
44570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4459e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4460f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
44700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
44770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
44820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
44850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
44880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
45000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
45030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
45080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
45110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
45140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
452647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
452947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
453047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
45360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4537bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
454435ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
45530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
45590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
456347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4569bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
457612560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
45940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
460147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
460247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46058182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
46068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
46078182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
46098182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
46118182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
46138182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
46158182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
46178182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
462247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
462647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4634e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4635e610a071534e448c46460a5aa39ede33bf56b329glennrp                  PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
464047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
464447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* To do. */
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
465447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
465747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
46640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
46670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
467147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
46750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
46790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
468247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
468347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
468547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4686bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
468847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
469047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4691bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
470247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47058182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
47068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
47070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47088182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
47098182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
47100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4711bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4712bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
47130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
47160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
47180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4721e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
472347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4726bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4727bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
47280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4729bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4730bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
47310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4732bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4733bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
47340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
47370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
47390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4742e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
474447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
47500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
4754e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4755e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
475647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
47640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4765bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
47670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4768bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4776e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4777e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
47780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
478247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
478647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
479347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
47980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
48080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
48190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4823e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4824e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
484147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
485347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
487747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
487847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4887bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4890bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
490247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4905bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
490947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
491047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4913bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
493047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4937bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
494047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
494147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
49428182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
49430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4946e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
4947e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
49480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
49510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
496247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
496647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
497847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
49850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
4989e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
4990f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
499147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
49960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
500147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
501947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
502347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
503047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
503347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
50500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
50530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
50560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
506747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
507347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
507947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
508247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
508847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
509147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
509747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
510047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
510647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
510947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
511547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
511847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
512447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
512747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
513347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
513747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
514547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
516447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
517147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
517447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
518147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
518447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
518947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
52058182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
52078182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
521147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
522047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
522647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
523147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5234bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5236bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
524447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
524747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
525047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
525347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
525647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
525947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
526247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
527047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
527347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
527647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
528147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
529147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
529847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
530147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
530747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
531547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53168182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
53178182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5330bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5332bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
534047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
534747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
535147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
535847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
536147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
536247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
536347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5375e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5376e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
539347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
540047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
54030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
54050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
541547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
54260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5430e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5431e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
543547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
544247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
544947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
54550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
54580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
54670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
54760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
548247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
548647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
549147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5492bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
549347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
550547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
551847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
555147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
555447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
555647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
555747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
555947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55624e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
556347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
556647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
556947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
557147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
557247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
557447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
557847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
558147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
558347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
558447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
558647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55894e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
559047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
559347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
559647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
559847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
559947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
560147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5611bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5615bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
563047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
563147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
563547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
563747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5661bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
566547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5666bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
567447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
568547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
569047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
569347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
569647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
569947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5708e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5709bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
571447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
572347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
572647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5727bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5730bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
573147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5732bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5733bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
573447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5735bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5736bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
573747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5738bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
574047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5742bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
574347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
574747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5748bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
575447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5760bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
576647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5767bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
57695c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      /* TO DO: get color as function of indexes[x] */
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
578047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
578547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5789bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5790bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5792bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5793bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5795bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5796bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
579847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5800bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5803bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
580547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
581547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
582147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
582447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5827bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5828bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
583647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
583947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
584247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5861e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5863bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
587147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5872bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5873bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5875bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5876bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
587747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5878bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5879bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
588047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5881bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5882bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
588347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5884bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
588647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5888bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
588947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
589747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
590247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5908bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5911bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5914bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
5917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
592047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
593047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
593647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
593947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
5944bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
595347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
5963bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
596647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5967bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
597547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
600947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6025bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6026bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
603247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
604447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60672b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
60682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
60692b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       * if lossy
60702b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
60712b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
60722b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
60732b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
60742b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
60750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
60768640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if (LosslessReduceDepthOK(image) != MagickFalse)
60778640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6079d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
608147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6085bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6088d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6092d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
609447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
609647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
610047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
61110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
612247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
612647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
61390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
61420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
61470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
61500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
615847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
616247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
61670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
617247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
617847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
618647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
619147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
619747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
620047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
620347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
62110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
62140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
62170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
622247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
62280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
62300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6233e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6234e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
62350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
624347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
624647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6248e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
624947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6254e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6266bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
627147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
627447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
627747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
628047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
628947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
629247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
630947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
631947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
632247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6324e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6325e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
632647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6328f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6329f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
633047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6331f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6332e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6333e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6334f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6335f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
633647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
634047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
634347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
634625c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
635147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
635447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
635747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
636225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6385bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6388bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
640147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
640747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
641547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
641947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
642747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
643047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
643547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
643847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
644147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
644747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
645247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
645747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
646047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
646547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
647047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
648047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
648447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
649147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
649447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
649947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
650747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
651247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
652047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
652747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
653447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
653518b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
653618b17443128598500357da7bff2f01683cf32890cristy  png_semaphore=AllocateSemaphoreInfo();
653718b17443128598500357da7bff2f01683cf32890cristy#endif
653847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
656947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6571514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy  if (png_semaphore != (SemaphoreInfo *) NULL)
6572514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy    DestroySemaphoreInfo(&png_semaphore);
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
657725c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    some GIF animations don't convert properly)
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6663bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
66840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
66850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
66870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6706f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
670847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6709bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
671647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
672347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
672647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType png_write_chunk_from_profile(Image *image,
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const char *string, int logging)
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
674747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
674847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
674947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
675147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png_profile;
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
675747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
675847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
675947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
676047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
676147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
676247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
676347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            png_profile=CloneStringInfo(profile);
676447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data=GetStringInfoDatum(png_profile),
676547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            length=(png_uint_32) GetStringInfoLength(png_profile);
676647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
676747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
676847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
676947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
677047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
677147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
677247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
677347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            png_profile=DestroyStringInfo(png_profile);
677447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
677647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
677947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6783b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6784b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
6786b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp   const ImageInfo *IMimage_info,Image *IMimage)
67873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6788b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  Image
6789b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image;
6790b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6791b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  ImageInfo
6792b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image_info;
6793b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_matte,
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6808cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6809cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6810e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6811e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
68125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
681339992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
681439992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
68175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
68185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
68195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
68275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
68285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
68295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6830bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
68323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
6834d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
683539992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
6836991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
6837991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
6838991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
683926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
684026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
684126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
684226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
684326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
684426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
684526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
684626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
684726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
684826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
684926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
685026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
685126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
685226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
685326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6859bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte;
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
68710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
68725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
68735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
68745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
68755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
68765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
68775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6878bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_colors,
68805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
68815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6883bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
688439992b4dd9b12ef752d55b8e402c069698851f72glennrp    number_colors,
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6889dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
68908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
68918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
68928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
6893dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
6894dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6895dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
6896dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
6897dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
6898dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOnePNGImage()");
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6902b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image = CloneImage(IMimage,0,0,MagickFalse,&IMimage->exception);
6903b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
6904b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6905b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  if (mng_info->need_blob != MagickFalse)
6906b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  {
6907b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) ==
6908b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       MagickFalse)
6909b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    {
6910b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
6911b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
6912b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      return(MagickFalse);
6913b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    }
6914b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  }
6915b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6917f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
69210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
69225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
69235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
69245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
69255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
69265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
69275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
69295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
69305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
69315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
69325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
69335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
69355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
69365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
69375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
69385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6939dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
6940dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
6941dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
6942dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6943d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
694439992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
6945991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
6946991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
6947991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
6948991d11dd9c33e65872778b81aff1347cd2878154glennrp
69498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
69508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
69518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
69528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
69550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69563241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
69573241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
69583241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
69593241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
69603241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
69613241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp     (void) SyncImage(image);
69623241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
69632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
69642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
69652b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
69662b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
69672b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  if (image->depth > 16)
69682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
69692b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
69702b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
69718640fb5e9b1094f35f8beab436f81661b8a99448glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
69727e2c405930c984e8ffb49b26efdfe1649bf394d6cristy  if (image->depth == 16 && mng_info->write_png_colortype != 16)
69738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
69748640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
69758640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
69768640fb5e9b1094f35f8beab436f81661b8a99448glennrp
697783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp#ifdef PNG_BUILD_PALETTE
6978d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype < 8 /* all */)
697983c2de583a59e41b57be8036d1cf7392c01d03d7glennrp    {
698083c2de583a59e41b57be8036d1cf7392c01d03d7glennrp      /*
69817ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       * Sometimes we get DirectClass images that have 256 colors or fewer.
6982d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * This code will build a colormap.
69837ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       *
69843241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp       * Also, sometimes we get PseudoClass images with an out-of-date
69853241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp       * colormap.  This code will replace the colormap with a new one.
6986d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * Sometimes we get PseudoClass images that have more than 256 colors.
6987d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * This code will delete the colormap and change the image to
6988d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * DirectClass.
69898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       *
69908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       * Also we gather some information (number of opaque, transparent,
6991d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * and semitransparent pixels, and whether the image has any non-gray
6992d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * pixels) that we might need later. If the user wants to force
6993d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * GrayAlpha or RGBA (colortype 4 or 6) we probably don't need any
6994d6bf1617e99df0272b231855a933a74e99b6578fglennrp       * of that.
69957ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       */
69963c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
69978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     ExceptionInfo
69988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       *exception;
69998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     int
70018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       n;
70028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     PixelPacket
7004d6bf1617e99df0272b231855a933a74e99b6578fglennrp       colormap[800],
7005d6bf1617e99df0272b231855a933a74e99b6578fglennrp       opaque[260],
7006d6bf1617e99df0272b231855a933a74e99b6578fglennrp       semitransparent[260],
7007d6bf1617e99df0272b231855a933a74e99b6578fglennrp       transparent[260];
70088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     register IndexPacket
70108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       *indexes;
70118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7012d6bf1617e99df0272b231855a933a74e99b6578fglennrp     register const PixelPacket
7013d6bf1617e99df0272b231855a933a74e99b6578fglennrp       *q;
7014d6bf1617e99df0272b231855a933a74e99b6578fglennrp
701503812ae402fb53d548f0e1d7d14720768f803c2dglennrp     if (logging != MagickFalse)
701603812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
701703812ae402fb53d548f0e1d7d14720768f803c2dglennrp           "    Enter BUILD_PALETTE:");
70183c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
70198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     image->colors=GetNumberColors(image,(FILE *) NULL,&image->exception);
70208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     image_colors=image->colors;
70218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp     if (logging != MagickFalse)
70237ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
70247ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image->columns=%.20g",(double) image->columns);
70268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image->rows=%.20g",(double) image->rows);
70288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image_matte=%.20g",(double) image->matte);
70308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      image->depth=%.20g",(double) image->depth);
70322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         if (image->colormap != NULL)
70347ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
70357ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "      Original colormap:");
70378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp               "        i    (red,green,blue,opacity)");
70398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
70408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           for (i=0; i < (ssize_t) image->colors; i++)
70418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           {
70428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                 "        %d    (%d,%d,%d,%d)",
70448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (int) i,
70458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (int) image->colormap[i].red,
70468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (int) image->colormap[i].green,
70478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (int) image->colormap[i].blue,
70488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (int) image->colormap[i].opacity);
70498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           }
70507ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
70512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             "      image->colors=%d",(int) image->colors);
70542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         if (image->colors == 0)
70568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             "        (zero means unknown)");
705883c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
705903812ae402fb53d548f0e1d7d14720768f803c2dglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
706003812ae402fb53d548f0e1d7d14720768f803c2dglennrp              "      Regenerate the colormap");
706103812ae402fb53d548f0e1d7d14720768f803c2dglennrp       }
70627ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       exception=(&image->exception);
70647ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7065d6bf1617e99df0272b231855a933a74e99b6578fglennrp       ping_have_color=MagickFalse;
7066d6bf1617e99df0272b231855a933a74e99b6578fglennrp       image_colors=0;
7067d6bf1617e99df0272b231855a933a74e99b6578fglennrp
70688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       for (y=0; y < (ssize_t) image->rows; y++)
70698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       {
707098bd891f2d35aeb2086bd36e81ededf2da65e714cristy         q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
70712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
70728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         if (q == (PixelPacket *) NULL)
70738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           break;
70747ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7075d6bf1617e99df0272b231855a933a74e99b6578fglennrp         for (x=0; x < (ssize_t) image->columns; x++)
7076d6bf1617e99df0272b231855a933a74e99b6578fglennrp            {
7077d6bf1617e99df0272b231855a933a74e99b6578fglennrp                if (q->red != q->green || q->red != q->blue)
7078d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  ping_have_color=MagickTrue;
70797ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7080d6bf1617e99df0272b231855a933a74e99b6578fglennrp                if (image_colors == 0)
7081d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  {
7082d6bf1617e99df0272b231855a933a74e99b6578fglennrp                   /* Initialize the colormap */
7083d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    colormap[0]=*q;
7084d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7085d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    if (image->matte == MagickFalse)
7086d6bf1617e99df0272b231855a933a74e99b6578fglennrp                          colormap[0].opacity = OpaqueOpacity;
70872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7088d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    image_colors=1;
7089d6bf1617e99df0272b231855a933a74e99b6578fglennrp                   }
70907ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                for (i=0; i<image_colors; i++)
70928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
70938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (((image->matte == MagickFalse ||
70948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        colormap[i].opacity == q->opacity)) &&
70958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        (IsColorEqual(colormap+i, (PixelPacket *) q)))
70968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      break;
70978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
70987ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7099d6bf1617e99df0272b231855a933a74e99b6578fglennrp                if (i == image_colors && image_colors < 299)
71008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
71013c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7102d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    image_colors++;
71033241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7104d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    colormap[i]=*q;
71053241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7106d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    if (image->matte == MagickFalse)
7107d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       colormap[i].opacity = OpaqueOpacity;
7108d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  }
71093241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                q++;
71118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
71128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
71133c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
71142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
711503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (logging != MagickFalse)
711603812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
711703812ae402fb53d548f0e1d7d14720768f803c2dglennrp              if (image_colors >= 800)
711803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
711903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                       "      image has more than 800 colors");
71203241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
712103812ae402fb53d548f0e1d7d14720768f803c2dglennrp              else
712203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
712303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                       "      image has %d colors",(int)image_colors);
712403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
71252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
712603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /*
712703812ae402fb53d548f0e1d7d14720768f803c2dglennrp            Initialize image colormap.
712803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          */
71292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
713003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (logging != MagickFalse)
71318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   "      Sort the new colormap");
71333241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
713403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* Sort palette, transparent first */;
713503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (i=0; i<image_colors; i++)
713603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          {
713703812ae402fb53d548f0e1d7d14720768f803c2dglennrp             if (colormap[i].opacity == OpaqueOpacity)
713803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                opaque[number_opaque++] = colormap[i];
71393241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
714003812ae402fb53d548f0e1d7d14720768f803c2dglennrp             else if (colormap[i].opacity == TransparentOpacity)
714103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                transparent[number_transparent++] = colormap[i];
71423241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
714303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             else
714403812ae402fb53d548f0e1d7d14720768f803c2dglennrp                semitransparent[number_semitransparent++] =
714503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    colormap[i];
714603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          }
71473241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71483241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
714903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          n = 0;
71503241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
715103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (i=0; i<number_transparent; i++)
715203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             colormap[n++] = transparent[i];
71533241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
715403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (i=0; i<number_semitransparent; i++)
715503812ae402fb53d548f0e1d7d14720768f803c2dglennrp             colormap[n++] = semitransparent[i];
71563241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
715703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (i=0; i<number_opaque; i++)
715803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             colormap[n++] = opaque[i];
71593241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
716003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* Add the background color to the palette, if it
716103812ae402fb53d548f0e1d7d14720768f803c2dglennrp           * isn't already there.
716203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           */
716303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (i=0; i<number_opaque; i++)
716403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          {
716503812ae402fb53d548f0e1d7d14720768f803c2dglennrp             if (IsColorEqual(opaque+i,
716603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                &image->background_color))
716703812ae402fb53d548f0e1d7d14720768f803c2dglennrp             break;
716803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          }
71693241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
717003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (number_opaque < 257 && i == number_opaque)
717103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          {
717203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             opaque[i]=image->background_color;
717303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             opaque[i].opacity = OpaqueOpacity;
717403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             number_opaque++;
717503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          }
7176d6bf1617e99df0272b231855a933a74e99b6578fglennrp
717703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (logging != MagickFalse)
717803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
717903812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
718003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      number_transparent     = %d",
718103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    number_transparent);
7182d6bf1617e99df0272b231855a933a74e99b6578fglennrp
718303812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
718403812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      number_opaque          = %d",
718503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    number_opaque);
7186d6bf1617e99df0272b231855a933a74e99b6578fglennrp
718703812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
718803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      number_semitransparent = %d",
718903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    number_semitransparent);
719003812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
71913241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71922cc891a179d622dde7bbb8854138851e828bc6eaglennrp          if (((mng_info->write_png_colortype-1) ==
719303812ae402fb53d548f0e1d7d14720768f803c2dglennrp              PNG_COLOR_TYPE_PALETTE) ||
719403812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (mng_info->write_png_colortype == 0))
719503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          {
719603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             if (logging != MagickFalse)
719703812ae402fb53d548f0e1d7d14720768f803c2dglennrp               {
719803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 if (n != image_colors)
719903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
720003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "   image_colors (%d) and n (%d)  don't match",
720103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    (int) image_colors, n);
72023241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
720303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
720403812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      AcquireImageColormap");
720503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
72063241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
720703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          image->colors = image_colors;
72083241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
720903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (AcquireImageColormap(image,image_colors) ==
721003812ae402fb53d548f0e1d7d14720768f803c2dglennrp              MagickFalse)
721103812ae402fb53d548f0e1d7d14720768f803c2dglennrp             ThrowWriterException(ResourceLimitError,
721203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                "MemoryAllocationFailed");
72133241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
721403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (i=0; i<image_colors; i++)
721503812ae402fb53d548f0e1d7d14720768f803c2dglennrp             image->colormap[i] = colormap[i];
72163c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
721703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          if (logging != MagickFalse)
721803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
721903812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
722003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      image->colors=%d (%d)",
722103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    (int) image->colors, (int) image_colors);
72227ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
722303812ae402fb53d548f0e1d7d14720768f803c2dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
722403812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    "      Update the pixel indexes");
722503812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
72263241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
722703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          for (y=0; y < (ssize_t) image->rows; y++)
722803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          {
722903812ae402fb53d548f0e1d7d14720768f803c2dglennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,
723003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                exception);
72312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
723203812ae402fb53d548f0e1d7d14720768f803c2dglennrp            if (q == (PixelPacket *) NULL)
723303812ae402fb53d548f0e1d7d14720768f803c2dglennrp              break;
72343c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
723503812ae402fb53d548f0e1d7d14720768f803c2dglennrp            indexes=GetAuthenticIndexQueue(image);
72363c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
723703812ae402fb53d548f0e1d7d14720768f803c2dglennrp            for (x=0; x < (ssize_t) image->columns; x++)
723803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
723903812ae402fb53d548f0e1d7d14720768f803c2dglennrp              for (i=0; i<image_colors; i++)
724003812ae402fb53d548f0e1d7d14720768f803c2dglennrp              {
724103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                if ((image->matte == MagickFalse ||
724203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    image->colormap[i].opacity == q->opacity) &&
724303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                    (IsColorEqual(&image->colormap[i],(PixelPacket *) q)))
724403812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
724503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                  indexes[x]=(IndexPacket) i;
72468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
724703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
724803812ae402fb53d548f0e1d7d14720768f803c2dglennrp              }
724903812ae402fb53d548f0e1d7d14720768f803c2dglennrp              q++;
72508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
725183c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
725203812ae402fb53d548f0e1d7d14720768f803c2dglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
725303812ae402fb53d548f0e1d7d14720768f803c2dglennrp               break;
725403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         }
725503812ae402fb53d548f0e1d7d14720768f803c2dglennrp       }
72563c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
725703812ae402fb53d548f0e1d7d14720768f803c2dglennrp       if (logging != MagickFalse)
725803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         {
725903812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
726003812ae402fb53d548f0e1d7d14720768f803c2dglennrp              "      image->colors=%d", (int) image->colors);
72613c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
726203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           if (image->colormap != NULL)
726303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             {
726403812ae402fb53d548f0e1d7d14720768f803c2dglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
726503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                   "       i     (red,green,blue,opacity)");
72663c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
726703812ae402fb53d548f0e1d7d14720768f803c2dglennrp               for (i=0; i < (ssize_t) image->colors; i++)
726803812ae402fb53d548f0e1d7d14720768f803c2dglennrp               {
726903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
727003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                     "       %d     (%d,%d,%d,%d)",
727103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                      (int) i,
727203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                      (int) image->colormap[i].red,
727303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                      (int) image->colormap[i].green,
727403812ae402fb53d548f0e1d7d14720768f803c2dglennrp                      (int) image->colormap[i].blue,
727503812ae402fb53d548f0e1d7d14720768f803c2dglennrp                      (int) image->colormap[i].opacity);
727603812ae402fb53d548f0e1d7d14720768f803c2dglennrp               }
727703812ae402fb53d548f0e1d7d14720768f803c2dglennrp             }
727803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
727903812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
728003812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
728103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         }
728283c2de583a59e41b57be8036d1cf7392c01d03d7glennrp    }
72833c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp#endif /* PNG_BUILD_PALETTE */
72843c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
72853c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
72863c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
72873c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
72883c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
72893c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_colors=image->colors;
72903c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
729183c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
72920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
72938eb57274a813fc3f2e2f96b166eb569f5e17aa26glennrp    image_colors <= 256;
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
73020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
73060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
73100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
73120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7333f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7335b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      if (mng_info->need_blob != MagickFalse)
7336b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
7337b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
7338b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
73443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
73472b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
73522b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73552b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
73572b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
73584e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
73594e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
73602b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
73630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
73660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
73700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
73730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
73760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7380e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7382e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7384e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73868640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73888640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73908640fb5e9b1094f35f8beab436f81661b8a99448glennrp
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
73925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
7393dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
739426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/* Check for chunks to be excluded:
739526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp *
739626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * The default is to not exclude any chunks except for any
739726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * listed in the "unused_chunks" array, above.
739826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp *
739926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * Chunks can be listed for exclusion via a "PNG:exclude-chunk"
740026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * define or via a mng_info member.  For convenience, in addition
740126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * to or instead of a comma-separated list of chunks, the
740226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * "exclude-chunk" string can be simply "all" or "none".
740326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp *
740426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * The exclude-chunk define takes priority over the mng_info.
740526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp *
740626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * A "PNG:include-chunk" define takes  priority over both the
740726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * mng_info and the "PNG:exclude-chunk" define.  Like the
740826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * "exclude-chunk" string, it can define "all" or "none" as
740926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * well as a comma-separated list.
741026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp *
741126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * Finally, all chunks listed in the "unused_chunks" array are
741226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * automatically excluded, regardless of the other instructions
741326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * or lack thereof.
741426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp *
741526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * if you exclude sRGB but not gAMA (recommended), then the gAMA
741626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp * chunk will only be written if it is not approximately (1.0/2.2).
741703812ae402fb53d548f0e1d7d14720768f803c2dglennrp *
741803812ae402fb53d548f0e1d7d14720768f803c2dglennrp * The -strip option causes StripImage() to set the png:include-chunk artifact
741903812ae402fb53d548f0e1d7d14720768f803c2dglennrp * to "none,gama".
742026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp */
742126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
742226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
742326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
742426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_EXIF=mng_info->ping_exclude_EXIF; /* hex-encoded EXIF in zTXt */
742526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
742626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
742726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
742826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
742926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
743026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
743126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
743226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
743326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
743426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
743526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
743626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
743826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
743926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
7444dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7445dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7449dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
7450dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
7451dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7453dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7456dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
7457dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution);
7458dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution);
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7460991d11dd9c33e65872778b81aff1347cd2878154glennrp
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
74623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7463dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
7464dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) image->x_resolution;
7465dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) image->y_resolution;
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7467991d11dd9c33e65872778b81aff1347cd2878154glennrp
7468991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
74693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
747026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
74713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7472a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
747326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
747426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
7475a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7477a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
7478a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
7479a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
7480a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
7481a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
7482a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
74830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7484a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
7485a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
74860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7487a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
7488a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
74890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7490a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
7491a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
74920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7493a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
7494a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
74950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7496a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
7497a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
74980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7499a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
7500a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
75010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
75020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
75043b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
75053b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75063b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
75073b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
75083b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75093b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
75103b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
75110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
751326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
75143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
75163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
75173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
75200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /* TO DO: make this a function cause it's used twice, except
75250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
75260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
75288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
75298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
75300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
75320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
75330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
75340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
75350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
75370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
75390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (int) number_colors, (int) image_colors);
75400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
75420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
75430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
75440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
75450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
75460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
75470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
75490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
75510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %5ld (%5d,%5d,%5d)",
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
75543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
75562b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
75578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
75588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
75598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
75605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
75618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (matte)
75628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
75630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
75640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
75650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
75660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
75678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
75708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
75710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          /* PNG8 can't have semitransparent colors so we threshold them
75738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           * to 0 or 255
75748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp           */
75758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (; i < (ssize_t) number_semitransparent; i++)
75768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=image->colormap[i].opacity >
75778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                OpaqueOpacity/2 ? 0 : 255;
75780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75792cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
75808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
75810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
75830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
75840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
75868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
75878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
75880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
75908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       * Identify which colormap entry is the background color.
75918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       */
75920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
75930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (IsPNGColorEqual(ping_background,image->colormap[i]))
75940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          break;
75950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_background.index=(png_byte) i;
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
75980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
76025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
76085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
76140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
76180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
76205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
76222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
76238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
76248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      else /* write_ping_colortype not specified */
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76313c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
76320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7633d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
76348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
76350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7636d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
76393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7642d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
76433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76485f1c1fff2a55c4d8756556e78c1f307d352ed1b8cristy          if (image_info->type == UndefinedType ||
76498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             image_info->type == OptimizeType)
76503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7651d6bf1617e99df0272b231855a933a74e99b6578fglennrp
76528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((image_info->type == GrayscaleType) &&
7653d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 image_matte == MagickFalse && ping_have_color != MagickFalse)
76548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
76558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
76568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_matte=MagickFalse;
76578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
76580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7659d6bf1617e99df0272b231855a933a74e99b6578fglennrp              else if ((image_info->type == GrayscaleMatteType) &&
7660d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  image_matte == MagickTrue && ping_have_color != MagickFalse)
76618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
76628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
76638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_matte=MagickTrue;
76648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
76658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7666d6bf1617e99df0272b231855a933a74e99b6578fglennrp              else if (image_info->type == PaletteType ||
76678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_info->type == PaletteMatteType)
76688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
76690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
767326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76748640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
767526c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
76765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
76770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
76780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
76790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
76800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
76810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
76820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7684d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
7685d6bf1617e99df0272b231855a933a74e99b6578fglennrp
76865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->matte == MagickFalse && image->colors < 256)
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ImageIsMonochrome(image))
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
76925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth=1;
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
76943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76968640fb5e9b1094f35f8beab436f81661b8a99448glennrp
76975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
769935ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
77005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
77010f111984738842d27d04aed2a3f823d82a943506glennrp
77020f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
77030f111984738842d27d04aed2a3f823d82a943506glennrp           {
77040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
77050f111984738842d27d04aed2a3f823d82a943506glennrp              (void) ThrowMagickException(&image->exception,
77060f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
77070f111984738842d27d04aed2a3f823d82a943506glennrp                "image has 0 colors", "`%s'","");
77080f111984738842d27d04aed2a3f823d82a943506glennrp           }
77090f111984738842d27d04aed2a3f823d82a943506glennrp
771035ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
77115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
7712d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
77133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7714d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
7715d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
7716d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7717d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
77180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7719d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7720d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
7721d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
77220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7723d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
7724d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
77275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
77282b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
77303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7732e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
77330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7735e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
77360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7738e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
77390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77413c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
77428640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
77438640fb5e9b1094f35f8beab436f81661b8a99448glennrp
77448640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7745e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
77463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
774839992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (matte && (mng_info->IsPalette))
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
77522b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
7753d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_have_color != MagickFalse)
7754d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_color_type=PNG_COLOR_TYPE_RGBA;
77552b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
77578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       * Determine if there is any transparent color.
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7759d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (number_transparent + number_semitransparent == 0)
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
77625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            No transparent pixels are present.  Change 4 or 6 to 0 or 2.
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_matte=MagickFalse;
77655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type&=0x03;
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
77693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned int
77713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mask;
77723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mask=0xffff;
77740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 8)
77763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x00ff;
77770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 4)
77793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x000f;
77800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 2)
77823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0003;
77830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 1)
77853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0001;
77860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.red=(png_uint_16)
7788d6bf1617e99df0272b231855a933a74e99b6578fglennrp            (ScaleQuantumToShort(image->colormap[0].red) & mask);
77890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.green=(png_uint_16)
7791d6bf1617e99df0272b231855a933a74e99b6578fglennrp            (ScaleQuantumToShort(image->colormap[0].green) & mask);
77920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.blue=(png_uint_16)
7794d6bf1617e99df0272b231855a933a74e99b6578fglennrp            (ScaleQuantumToShort(image->colormap[0].blue) & mask);
77950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.gray=(png_uint_16)
7797d6bf1617e99df0272b231855a933a74e99b6578fglennrp            (ScaleQuantumToShort(PixelIntensityToQuantum(
7798d6bf1617e99df0272b231855a933a74e99b6578fglennrp               image->colormap)) & mask);
77990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7800d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_trans_color.index=(png_byte) 0;
78010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7802991d11dd9c33e65872778b81aff1347cd2878154glennrp          ping_have_tRNS=MagickTrue;
78033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78052e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp      if (ping_have_tRNS != MagickFalse)
78063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
78073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
78083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine if there is one and only one transparent color
78093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            and if so if it is fully transparent.
78103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
78118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (logging != MagickFalse)
78128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7813d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "  Is there a single fully transparent color?");
78148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7815d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (number_transparent > 1 || number_semitransparent > 0)
78168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          {
78172e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp            ping_have_tRNS = MagickFalse;
78188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (logging != MagickFalse)
78198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7820d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "  ... No.");
78218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
78228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
78238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          {
78248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (logging != MagickFalse)
78258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7826d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "  ... Yes: (%d,%d,%d,%d)",
7827d6bf1617e99df0272b231855a933a74e99b6578fglennrp                (int) ping_trans_color.red,
7828d6bf1617e99df0272b231855a933a74e99b6578fglennrp                (int) ping_trans_color.green,
7829d6bf1617e99df0272b231855a933a74e99b6578fglennrp                (int) ping_trans_color.blue,
7830d6bf1617e99df0272b231855a933a74e99b6578fglennrp                (int) ping_trans_color.gray);
78318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
78323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78332b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
78342e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp      if (ping_have_tRNS != MagickFalse)
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
78365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
78370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
78393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
78405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
78415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
78425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
78435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
78443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
78453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
78478640fb5e9b1094f35f8beab436f81661b8a99448glennrp
78483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
78490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78502e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
78513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
78520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
785339992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
78543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
78553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageIsGray(image) && (!image_matte || image_depth >= 8))
78563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
785735ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
78580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
78609c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
78610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
78633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
78653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
78665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray*=0x0101;
78673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
78680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
78703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
78710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
787335ef824baa82511126ff0072ae30eee0da9c05a3cristy          image_colors=one << image_depth;
78740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
78765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
78770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
78793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
78815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
78823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
78833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
78843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
78855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
78860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
788735ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
7888bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
78895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
78903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
78913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
78922b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
78930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
78940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
78953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
78963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
78973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
78993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
79003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
79013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
79023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
79033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7904bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
79053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
79063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
79073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
79083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
79103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
79123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
79130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
79153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
79160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
79183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
79193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
79202b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
79229c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
79230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
79259c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
79260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
79289c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
79293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
79312b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
79333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
79340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
79360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
793917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
794017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
79413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
79423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
79443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
79453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
79465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
79470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->have_write_global_plte && !matte)
79493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
79509c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
79510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79523b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
79539c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79549c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
79553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
79583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7959bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
79603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
79623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
79633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
79643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
79650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79663b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
79673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
796898156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
796998156a3a465a004545e39434c63052b955a74d1cglennrp                    (int) number_colors);
79700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
797139992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
79723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
7975d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
79763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7977befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
7978befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
7979befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
79805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
7981befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
79820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7983befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
79845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
79853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
79880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
79900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
79910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
7992d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
7993d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
79940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
79953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7996d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
7997d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
79983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
80000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
80010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8002d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
80030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
8004d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
8005d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8006d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
8007d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
8008d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       ping_trans_alpha[i]= (png_byte) (255-
8009d6bf1617e99df0272b231855a933a74e99b6578fglennrp                          ScaleQuantumToChar(image->colormap[i].opacity));
8010d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
80110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
80120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
80133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
80150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
80173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
80183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
80193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
80200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
80223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
80235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
80245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
80255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
80265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
80273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
80283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
80293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8030d6bf1617e99df0272b231855a933a74e99b6578fglennrp    if (ping_bit_depth < mng_info->write_png_depth)
8031d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
80322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
80333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
80343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
80353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
80365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
80373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
80383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
80393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
80403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
80413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
804235ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
804335ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
804435ef824baa82511126ff0072ae30eee0da9c05a3cristy
804522ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
80463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
804726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         if (ping_exclude_bKGD == MagickTrue)
804826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
80493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8050a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
80513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
80523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
80543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80553c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Setting up bKGD chunk (2)");
80563b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
8057991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
805826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
80593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
80615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
80623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
806317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
806426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
806526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
806617a1485544c62993fc7a94e343c87fed5f3e6407glennrp    if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
806717a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
806817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
806917a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
807017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
807117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
807217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
807317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8074a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
8075a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
807617a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
807717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
807817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
807917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
80803b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
80810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
80820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
80840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
8085a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
808613d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
8087a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
80880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
80893b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
80903b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
80910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
80920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
80940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
80950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
80960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
80970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
8098a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
809917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8100d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
81013c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
81023b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
81033b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81043b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
81053c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
81063c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
810717a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
810826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
810917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
81103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
81133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
81180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
81200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
81230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
81240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
81260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
81300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
81320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
81350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
81373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
81403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8141bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
81420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
81443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
81460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
81533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
81550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
81643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
81653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
81700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
81723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
81753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
81763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
81783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81792b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
81813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
81833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
81858640fb5e9b1094f35f8beab436f81661b8a99448glennrp      base_filter=PNG_ALL_FILTERS;
81860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81878640fb5e9b1094f35f8beab436f81661b8a99448glennrp    else
81888640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if ((quality % 10) != 5)
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
81900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81918640fb5e9b1094f35f8beab436f81661b8a99448glennrp      else
81928640fb5e9b1094f35f8beab436f81661b8a99448glennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
81935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
81943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
81958640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_NO_FILTERS;
81960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81978640fb5e9b1094f35f8beab436f81661b8a99448glennrp        else
81988640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_ALL_FILTERS;
81990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
82013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
82023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
82033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
82053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
82063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
82083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
82092b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
82103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
82113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
82123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
82143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
82153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
82163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
82172b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
82183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (StringInfo *) NULL)
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
82205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
82213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((LocaleCompare(name,"ICC") == 0) ||
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (LocaleCompare(name,"ICM") == 0))
822326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
82240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
822526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (ping_exclude_iCCP == MagickFalse)
822626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
822726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   png_set_iCCP(ping,ping_info,(const png_charp) name,0,
822826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                     (png_charp) GetStringInfoDatum(profile),
82293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (png_uint_32) GetStringInfoLength(profile));
823026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
823126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
82320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
82343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
823526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_zCCP == MagickFalse)
823626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
823726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              png_write_raw_profile(image_info,ping,ping_info,(unsigned char *)
823826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                name,(unsigned char *) name,GetStringInfoDatum(profile),
823926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                (png_uint_32) GetStringInfoLength(profile));
824026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
82413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
82422b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
82433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
82443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Setting up text chunk with %s profile",name);
82460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    name=GetNextImageProfile(image);
82483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
82493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
82523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
82533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
825526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
825626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
825726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
825826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
825926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
826026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
826126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
826226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
82630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
826426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
826526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            PNG_RenderingIntent_from_Magick_RenderingIntent(
826626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            image->rendering_intent)));
82670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
826826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_gAMA == MagickFalse)
826926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            png_set_gAMA(ping,ping_info,0.45455);
827026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
82713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
827226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
82735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
82743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
82753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82762cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
82772cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
827826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
827926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
82803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
82813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
82823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
82833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
82843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
82853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
82893b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
82903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
82913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
829226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
82932b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
829426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
82953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
829626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
829726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
829826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
829926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
830026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
830126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
830226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
830326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
830426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
830526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
830626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
830726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
830826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
830926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
831026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
831126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
831226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
831326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
831426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
831526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
831626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
831726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
831826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
831926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
832026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
832126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
83223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8323dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
83245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
83253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
83273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
83283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8331d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
83323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
83343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
83353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
83365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
83372b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
83395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
83410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
83433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
83445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->write_png_depth &&
83485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
83493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
83505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
8351991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
83525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0))))
83533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
83553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
83573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
83603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
83615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
83623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
83633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
83643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
83673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
83685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
83693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
83703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83713bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
83723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
83733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83758640fb5e9b1094f35f8beab436f81661b8a99448glennrp  if (image_matte && !image->matte)
83763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
83783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
83800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8381b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
8382b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8383b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
83843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8386991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (image->matte == MagickTrue)
8387e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
8388991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
8389991d11dd9c33e65872778b81aff1347cd2878154glennrp        if (ping_color_type != 3 || ping_num_trans > 0)
8390991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
8391e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
8392e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
83933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
83943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
83963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
83985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
83995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
84005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
84015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
840239992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
840339992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
840439992b4dd9b12ef752d55b8e402c069698851f72glennrp      png_set_PLTE(ping,ping_info,palette,(int) number_colors);
84050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84063b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
840739992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
84088640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
84090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
8410d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
84110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8412d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
8413d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
84140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
84150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
84160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
8417d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
84180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
84190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
84200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8421d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
84220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
84230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
84240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
84250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
84260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
842739992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
842839992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
842939992b4dd9b12ef752d55b8e402c069698851f72glennrp
843026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
843126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
843226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
843326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
843426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
8435991d11dd9c33e65872778b81aff1347cd2878154glennrp
843626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
8437dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
843826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
843926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
844026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
844126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
844226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
844326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
844426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
8445dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
8446dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8447dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
844826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
8449dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
845026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
845126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
845226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
845326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
8454dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
845526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
845626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
845726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
845826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
845926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
8460dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
8461dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
8462dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
84633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
8464991d11dd9c33e65872778b81aff1347cd2878154glennrp
846539992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
8466991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
84673b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
84680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
84690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
84710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
8472991d11dd9c33e65872778b81aff1347cd2878154glennrp
84730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
84740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
84750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
84760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
84770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
8478991d11dd9c33e65872778b81aff1347cd2878154glennrp
84790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
84800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
84810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
84820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
84830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
84840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
84850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84863b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
84870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
84880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 "     background   =(%d,%d,%d)",
84900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
84910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
84920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
84930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
84940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
84950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
8496991d11dd9c33e65872778b81aff1347cd2878154glennrp
84973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
84983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",(int) logging);
84993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
8500991d11dd9c33e65872778b81aff1347cd2878154glennrp
85013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
85023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",(int) logging);
85033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
850426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
85053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
850626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.width || image->page.height)
850726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
850826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
850926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
851026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
851126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
851226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
851303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
851426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
851526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
851626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
851726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
851826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
851926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
85203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
85239c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
85243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
85259c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
85263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
85273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
85283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
85303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
85313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
85323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
85333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
8534b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
8535b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
85367202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
85373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8538b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
85393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
8540b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
85410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8542b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
8543b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
8544b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
85450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8546b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
85473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
8548b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
85490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8550b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
8551b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
85523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85533b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
85543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
85553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8556b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8557b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
85580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8559b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8560e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
85613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
85633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*png_pixels));
85640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
85663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
85670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
85693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
85703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
85715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
85723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
85753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
85763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
85773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
85783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
85793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
85803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
85813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
85823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
85833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
85843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
85853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8586f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
85873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8588b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      if (mng_info->need_blob != MagickFalse)
8589b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
8590b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
8591b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
85923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
85933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8594ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
8595ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
8596ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
85973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
85983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
86008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
86013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
86028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
86038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
86043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
86058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !image_matte && ImageIsMonochrome(image))
86063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
86083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
86100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
86123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
86133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
86143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
86153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
86163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
8617bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
86183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8619a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
86203241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp          if (logging != MagickFalse)
86213b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86223b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
8623a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
86243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
86250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
86273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
86280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
86303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
86313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
86323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
86343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
86353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
86363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
86373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
8638bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
86393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
86403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
86413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
86430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
86473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RedQuantum,png_pixels,&image->exception);
86483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
86490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
8651bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
86533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
86540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86553b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
8656b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8657b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
86580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
86603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
86653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
86663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
86683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
86743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image_matte ||
86755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
867639992b4dd9b12ef752d55b8e402c069698851f72glennrp         (mng_info->IsPalette) && ImageIsGray(image))
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
86788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
86798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
86800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
86823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8684bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
86872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
86893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
86902cc891a179d622dde7bbb8854138851e828bc6eaglennrp
86915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
86923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
86938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
86958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,GrayQuantum,png_pixels,&image->exception);
86962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
86983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
86998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,RedQuantum,png_pixels,&image->exception);
87002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
87028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
8707b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
87083b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
8709b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
87112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
8714b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
87152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87163b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
8717b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
87192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
87213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
87248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
87258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
87268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
87278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
87288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
87298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
87308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
87310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
87348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
87358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
87360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
87383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
87408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
87418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
87428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
87438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
8744b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
87458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
87468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   &image->exception);
87472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
87498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
87502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
87528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
87538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
87548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        quantum_info,RedQuantum,png_pixels,&image->exception);
87562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
87588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        quantum_info,GrayQuantum,png_pixels,&image->exception);
87608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
87612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
87638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
87648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      quantum_info,GrayAlphaQuantum,png_pixels,
87668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      &image->exception);
87672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
87698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
87718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
87722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
87748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,RGBAQuantum,png_pixels,&image->exception);
87762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
87788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,RGBQuantum,png_pixels,&image->exception);
87802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87813b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
8782b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
87842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                png_write_row(ping,png_pixels);
8786b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
87878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
87882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
87898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
87908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
87918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
87928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
87938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
87948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
87958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
87968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
87978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
87988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
88002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
88028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
88038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
88042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
88068640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
88078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
88088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
88102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
88122cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
88148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
88152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
88178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
8818d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       quantum_info,GrayQuantum,png_pixels,&image->exception);
88192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
88218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
88228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
88238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
88252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
8827d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         quantum_info,GrayAlphaQuantum,png_pixels,
8828d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         &image->exception);
88298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
88302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
88328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    quantum_info,IndexQuantum,png_pixels,&image->exception);
88342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse && y <= 2)
88368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
88378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        "  Writing row of pixels (4)");
88392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        "  png_pixels[0]=%d,png_pixels[1]=%d",
88428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                        (int)png_pixels[0],(int)png_pixels[1]);
88438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
88448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                png_write_row(ping,png_pixels);
88458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
88468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
88472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
88498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
88508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
88518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
88528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
88538640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
88568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
88578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
8858b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
8859b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
88603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8864b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
88650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8867e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
88680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8870e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
88710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
88733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
88743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
88763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
88770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
88800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
88823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
88833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
88853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
88860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
88890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
88923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
88953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
889626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_tEXt == MagickFalse && ping_exclude_zTXt == MagickFalse)
88973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
889826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
889926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
890026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
890126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
890226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
890326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
89042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
890526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      value=GetImageProperty(image,property);
890626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (value != (const char *) NULL)
890726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
890826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
890926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].key=(char *) property;
891026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].text=(char *) value;
891126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].text_length=strlen(value);
89122cc891a179d622dde7bbb8854138851e828bc6eaglennrp
891326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_tEXt != MagickFalse)
891426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             text[0].compression=0;
89152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
891626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          else if (ping_exclude_zTXt != MagickFalse)
891726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             text[0].compression=-1;
89182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
891926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          else
89203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
892126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                text[0].compression=image_info->compression == NoCompression ||
892226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                  (image_info->compression == UndefinedCompression &&
892326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                  text[0].text_length < 128) ? -1 : 0;
89243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
892626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
892726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
892826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
892926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up text chunk");
89302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
893126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
893226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "    keyword: %s",text[0].key);
893326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
89342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
893526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_text(ping,ping_info,text,1);
893626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_free(ping,text);
893726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
893826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
893926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",(int) logging);
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
89480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
89500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
89523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
89545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
89555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
89623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
896503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
89733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
89765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
89795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
89813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
89823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
89843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
89850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
89873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
89940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9004f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9007b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  if (mng_info->need_blob != MagickFalse)
9008b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp     (void) CloseBlob(image);
9009b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9010b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=DestroyImageInfo(image_info);
9011b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image=DestroyImage(image);
9012b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9013b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
9014b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
9015b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
9016b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9017b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  (void) SetImageProperty(IMimage,"png:bit-depth-written",s);
9018b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
90220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
90463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
90483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
90503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
90523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
90623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
90633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
90643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparent).  The pixels contain 8-bit indices even if
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               they could be represented with 1, 2, or 4 bits. Note: grayscale
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               PNG grayscale type might be slightly more efficient.
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               one of the colors as transparent.
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
90760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
90803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
9081bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
9082bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
9083bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
90953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
90973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  If the image cannot be written without loss in the requested PNG8, PNG24,
91023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or PNG32 format or with the requested bit-depth and color-type without loss,
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a PNG file will not be written, and the encoder will return MagickFalse.
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transparency prior to attempting to write the image in a format that
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is subject to depth, color, or transparency limitations.
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
9125bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
9126bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
9131bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
91323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9133bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91353241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
91360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
9137d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
91380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
91390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
91400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
91413241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%      transparent color first, if PNG_BUILD_PALETTE is defined.
91420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
9143d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
9144d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
9145d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      requested via the "-define PNG:bit-depth=N" option.
9146d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
9147d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
9148d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
9149d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
91500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
91553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
91563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
91643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
91663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
916826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  int
916926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    i;
917026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
91715c7cf4e469a4dad7e277783749155932252c52dfglennrp  int
91725c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
91735c7cf4e469a4dad7e277783749155932252c52dfglennrp
917403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  MagickBooleanType
917503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding,
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
91823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
91833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
91873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
919173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
91920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
91950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
9201a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
92053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92129c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
92139c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
92149c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
92153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
92183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92199c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
92209c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
92219c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
92220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92239c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
92249c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
92250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92269c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
92279c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
92280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92299c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
92303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92349c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
92359c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
92369c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
92370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92389c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
92399c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
92400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92419c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
92429c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
92430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92449c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
92453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
92488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
92493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
92503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
92529c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
92530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
92559c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
92560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
92589c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
92590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
92619c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
92620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
92649c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
92650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9266bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
9267bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
9268bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
9269bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
9270bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
9271bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
92723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
92739c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9274bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
92753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
92780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
92803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
92823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
92839c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
92840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
92869c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
92870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
92899c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
92900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
92929c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
92930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
92959c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
92960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9297bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
9298bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
9299bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
9300bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
9301bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
9302bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
93049c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9305d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
930826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* See if the user wants to exclude any chunks */
930926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
931026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
931126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
931226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
931326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
931426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
931526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
931626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
931726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
931826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
931926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
932026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
932126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
932226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
932326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
932403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
932503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
93265c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
93275c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
93285c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
93295c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
93305c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
93315c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
933226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
933303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
933403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
933526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
933603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
933703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
933826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
933903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
934026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
934103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
93422cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
93432cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
93442cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93452cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
93462cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
93472cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93482cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
93492cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
935003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
935103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
935203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
935303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
935403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
935503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
935603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
935703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
935803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
935903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
936003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
936103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
936203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
936303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
936403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
936503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
936603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
936703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
936803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
936903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
937003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
937103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
937203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
93732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
937403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
937503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
937603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
937703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
937803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
937903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
938003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
938103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
938203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
938303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
938403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
938503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
938603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
938703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
938803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
938903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
93902cc891a179d622dde7bbb8854138851e828bc6eaglennrp
939103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
939203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
93932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
939403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
939503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
93962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
939703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
939803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
93992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
940003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
940103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
94022cc891a179d622dde7bbb8854138851e828bc6eaglennrp
940303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
940403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
94052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
940603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
940703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
940803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
940903812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
94102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
941103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
941203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
94132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
941403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
941503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
94162cc891a179d622dde7bbb8854138851e828bc6eaglennrp
941703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
941803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
94192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
942003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"sRGB",4) == 0)
942103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
94222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
942303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
942403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
94252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
942603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
942703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
94282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
942903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
943003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
94312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
943203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
943303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
94342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
943503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
9436ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
943726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
943826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
94395c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
94405c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
94415c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
94425c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
94435c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
94445c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
944526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
944603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
944703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
944803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
944903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
945026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
945103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
945226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
945303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
94542cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
94552cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
94562cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94572cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
94582cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
94592cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94602cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
94612cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
946203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
946303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
946403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
946503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
946603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
946703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
946803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
946903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
947003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
947103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
947203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
947303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
947403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
947503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
947603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
947703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
947803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
947903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
948003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
948103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
948203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
948303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
94842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
948503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
948603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
948703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
948803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
948903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
949003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
949103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
949203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
949303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
949403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
949503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
949603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
949703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
949803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
949903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
950003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
95012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
950203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
950303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
95042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
950503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
950603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
95072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
950803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
950903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
95102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
951103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
951203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
95132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
951403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
951503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
95162cc891a179d622dde7bbb8854138851e828bc6eaglennrp
951703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
951803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
951903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
952003812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
95212cc891a179d622dde7bbb8854138851e828bc6eaglennrp
952203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
952303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
95242cc891a179d622dde7bbb8854138851e828bc6eaglennrp
952503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
952603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
95272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
952803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
952903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
95302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
953103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"sRGB",4) == 0)
953203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
95332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
953403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
953503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
95362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
953703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
953803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
95392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
954003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
954103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
95422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
954303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
954403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
95452cc891a179d622dde7bbb8854138851e828bc6eaglennrp
954603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
9547ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
954826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
954926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
955003812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
955126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
955226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
955326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      "  Chunks to be excluded from the output PNG:");
955426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
955526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
955626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
955726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
955826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
955926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
956026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
956126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
956226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
956326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
956426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
956526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
956626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
956726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
956826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
956926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
957026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
957126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
957226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
957326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
957426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
957526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
957626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
957726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
957826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
957926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
958026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
958126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
958226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
958326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
958426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
958526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
958626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
958726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
958826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
958926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
959026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
959126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
959226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
959326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
959426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
959526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
959626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9597b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
95983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9599b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  status=WriteOnePNGImage(mng_info,image_info,image);
96003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
96020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
96043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
96050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
96073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
96083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
96103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
96123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
96133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
96143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
96153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
96163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
96173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
96193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
96203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
962203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
96233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
96243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
96263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
96273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
96303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
96313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
96343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
96363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
96373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
96383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9639bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
96403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
96413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
96433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOneJNGImage()");
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
96463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
96473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
96483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
96503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
96513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
96523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
96533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
96543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
96553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
96563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
96603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
96613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
96623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
96633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
96663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
96680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
96703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
96713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
96730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
96750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
96773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
96780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
96803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
96820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
96840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
96863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
96870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
96893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
96903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
96913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
96920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
96943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
96950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
96973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
96980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
97003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
97013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
97023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
97033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
97043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
97073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
97093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
97103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
97113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
97123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
97143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
97163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
97183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
97193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
97213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
97223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
97233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
97243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
97263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
97273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
97293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
97303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
97313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
97333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
97343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
97363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
97373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
97383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
97393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
97413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
97433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
97453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
97463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
97483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
97493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
97503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
97513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
97533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
9754f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
97553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
97560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
97583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9759e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
9760e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
97613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
97643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
97653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
97663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
97673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
97703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
97713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
977203812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
97734e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
97744e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
97753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
97763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
97773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
97783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
97793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
97803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
97813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
97823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
97833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
97843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
97853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9788f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
97890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9791f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
97920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
97950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
97980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
98010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
98040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
98070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
98100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
98130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
98163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
98193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",(int) logging);
98203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
98223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
98233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
98243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
98263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
98273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
98283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
98293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
98303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
98323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
98333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
98343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
98353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9836bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
98373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
98383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
98403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
98413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
98423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
9843bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
98443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
984503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
98463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
98473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
98483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
98493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
98503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
98513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
98523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
98533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
98543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
98553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
98563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
98573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
98583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
98603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
98623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
98643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
98653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
986603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
98670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
9869e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
9870e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
9871e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
98720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
9874e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
9875e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
9876e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
98770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
98793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
98803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
98823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
98863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
98873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
98893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
989003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
989135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
98923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
98933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
98943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
98983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
98993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
99003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
99013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
99033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
99053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
99063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
990703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
99083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
990935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
991035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
99113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
991235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
991335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
99143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
991535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
991635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
99173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
991835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
991935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
99203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
99213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
99223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
99233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
99263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
99283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
99293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
99303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
99313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
993203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
99333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
99343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
993535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
99363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
99370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
993835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
99393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
99400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
99430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
99453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
99463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
994835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
99500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
995135ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
99530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
99553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
99560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
99583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
995935ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
996035ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
99613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
99623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
99633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
99733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
997503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
9976bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
9977bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
99793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
99803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
99813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
99833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
99853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
998603812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
99883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
99903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
99913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
99923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
99963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
99983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9999bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
100003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
100013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10002bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
100033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
100043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
100063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
100073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10008e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
10009f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
100103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
100123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
100133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
10014bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
100153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
100163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
100173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
100180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
100203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
10022bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1002303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
100243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
100253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
100263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
100273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
100303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
100313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
100323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10033e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
10034e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
100353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
100363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
100373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
100383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
100393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
100403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
100413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
100423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
100433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10044e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
10045bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
100463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1004703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
100483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
100493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
100503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
100513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
100523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
100533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
100543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
100553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
100583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
100593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
100613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
100623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
100633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
100663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
100683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
100703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
100713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
100723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
100733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
100753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
100763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
100773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
100793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
100823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10083e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
10084e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
100853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
100873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
100880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
100903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
100913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
100920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
100943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
100960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
100980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10102e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
10103e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
101043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10106e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
101073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
10110bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
101113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1011203812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
101133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
101143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
101153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
101163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
101183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
101193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
101203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
101213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
101233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",(int) logging);
101243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
101263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
101273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1012803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
101303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
101313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
101350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
101373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
101383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
101413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
101433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
101443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
101453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
101463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
101473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
101483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
101493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
101513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
101523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
101533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
101543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
101553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
101573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
101583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
101593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
101603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
101613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
101623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
101633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
101643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
101653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
101673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
101683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
101693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1017003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
101713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
101723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
101743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
101753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
101773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
101783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
101803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
101813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
101823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
101833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
101843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
101853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
101863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
101873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
101883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
101893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
101913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
101933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
101943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
101953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1019673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
101973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
101983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
101993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
102003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
102013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
102023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
102033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
102043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
102053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
102073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
102093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
102103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
102123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
102133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
102143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
102153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
102163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
102173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
102183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
102223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
102233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
102243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
102253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
102273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
102283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
102303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
102313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1023203812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1023303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1023403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
102353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
102363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
102373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
102393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
102403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
102413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
102423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
102433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
102453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
102463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
102473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
102483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
102493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
102503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
102513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
102523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10253bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
102543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
102553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
102573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
102583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
102603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
102613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
102623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10263bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
102643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
102653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10266bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
102673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
102683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
102693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10270d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
102713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
102723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
102733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
102743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
102753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
102773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
102783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
102793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
102803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
102813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
102823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
102833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
102843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
102853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
102863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
102873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
102883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
102903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
102913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
102923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1029373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
102943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
102953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
102963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
102973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
102983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
102993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
103003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
103013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
103023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
103033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
103053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
103063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
103073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
103083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
103093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
103103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
103113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
103123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
103133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
103143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
103163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
103173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
103183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
103203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
103213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
103223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
103243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
103253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
103273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
103293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
103303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
103313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
103340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10336e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
103370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
103403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
103423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
103433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
103443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10345e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
103460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10348e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
103490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
103513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
103530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
103553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
103570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
103593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
103610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
103633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
103650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
103673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10368e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
103690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
103713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
103730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
103753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
103763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
103773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
103783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
103803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
103813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
103823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
103833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
103843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
103853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
103863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
103873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
103883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
103903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
103913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
103923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
103933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
103943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
103953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
103963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
103973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
103983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
103993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
104003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
104013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
104023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
104033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
104053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
104063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
104073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
104083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
104103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
104113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
104123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
104133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
104143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
104153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
104163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
104173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
104183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
104193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
104203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
104213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
104223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
104233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
104243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
104253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
104263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
104273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
104283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
104293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
104303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
104313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
104323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
104333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
104343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
104353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
104360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
104383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
104393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
104400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
104423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
104430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
104453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
104460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
104483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
104493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
104503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
104513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
104520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
104543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
104550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
104570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
104593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
104603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
104610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
104633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
104643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
104653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
104663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
104673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
104683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
104690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
104713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
104723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
104733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
104743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
104753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
104763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
104773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
104783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
104793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
104803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
104813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
104823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
104833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
104843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
104853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
104863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
104873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
104883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
104890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
104913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
104920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
104943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
104953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
104960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
104983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
104993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
105003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
105010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
105033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
105043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
105053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
105063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
105073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
105083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
105093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
105103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
105113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
105123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
105133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
105143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
105153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
105163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
105173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
105183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
105193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
105203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
105213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
105223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
105233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
105243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
105253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
105263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
105273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
105293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
105303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
105313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
105323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
105333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
105343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
105353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
105363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
105373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
105383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
105390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
105413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
105423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
105433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
105443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
105453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
105463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
105473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
105483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
105493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
105503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
105513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
105523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
105530261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
10554d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
10555d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
10556d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
10557d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
10558d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
10559d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
10560d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
105613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
105623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
105633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
105643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
105653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
105664e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->ticks_per_second=(png_uint_32) (image->ticks_per_second/final_delay);
105673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
105690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
105720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
105743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
105750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
105773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
105783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
105793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
105803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
105820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
105843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
105853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
105873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
105883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
105893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
105903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
105913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
105923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
105943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
105953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1059603812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
105974e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
105984e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
105993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
106003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
106013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
106023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
106033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
106043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
106053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
106063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
106083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
106090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
106113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
106123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
106130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
106153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
106180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
106203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
106223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
106230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
106253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
106283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
106300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
106323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
106333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
106340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
106363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
106383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
106390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
106413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
106423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
106433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
106443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
106453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
106463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
106473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
106483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
106493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
106503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
106513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
106533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
106543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
106553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
106563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
10657bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1065803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
106593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
106603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
106613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
106623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
106633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
106643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
106653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
106663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
106673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
106683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
106693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
106703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
106713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1067203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
106733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
106743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
106753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
106763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
106770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
106793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
106800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
106823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
106830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
106853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
106863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10687e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
10688e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
106890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
106913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10692e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
106930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
106953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10696e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
106973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
106983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
106993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
107013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
107043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
107053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
107063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
107083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
107103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
107113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1071203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
107130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
10715e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
10716e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
10717e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
107180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
10720e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
10721e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
10722e610a071534e448c46460a5aa39ede33bf56b329glennrp             (PerceptualIntent));
107230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
107280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
107303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
107323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
107333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
107353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
107363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1073803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1073935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
107463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
107523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1075403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1075635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1075735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
107583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1075935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1076035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
107613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1076235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1076335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1076535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1076635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
107713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
107773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1077903812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
107800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1078335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
107843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
107850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1078635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
107873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
107880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
107910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
107933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1079635ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
107980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1079935ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
108010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
108033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
108040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1080735ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1080835ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
108103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
108113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
108163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
108223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
108233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
108243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
108253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
108263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1082703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
108283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
108293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
108323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
108343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
108353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
108363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
108373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
108393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1084003812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
108413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
108423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
108483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
108493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
10851bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
108553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
108563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
108573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1086003812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
108610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10862bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
108633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
108680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
108773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
108783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
108793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
108823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
108833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
108883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
108923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
108933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
108943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
108953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
108963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
108973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
108983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
108993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
109013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
109023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
109043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
109053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
10906bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
109073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
109083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
109103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
109113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1091203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
109130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10914bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
109163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
109173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
109183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
109193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
109200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
109223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
109233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
109243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
109253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
109273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
109303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
109313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
109323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10933bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
109343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
109353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
109403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
109413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
109423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
109433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
109453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
109463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
109473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
109503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1095303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
109573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
109583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
109593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
109603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
109613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
109623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
109643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
109673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
109693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
109703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
109723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
109733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
109743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
109753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
109763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
109773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
109783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
109793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
109803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
109813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1098203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
109833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
109843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
109853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
109863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
109873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
109883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
109893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
109903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
109913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
109923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
109933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1099403812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
109953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
109963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
109973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
109983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
109993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
110003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
110013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
110023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
110033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
110043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
110053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
110064e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
110073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
110083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
110093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
110103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
110123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
110133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
110143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
110153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
110183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
110203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
110233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
110253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
110263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
110273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
110283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
110293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
110303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
110322f2e514554975d510c88df54de98c6cdc1080f1cglennrp
11033b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
110342f2e514554975d510c88df54de98c6cdc1080f1cglennrp
110352f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
110362f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
110372f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
110382f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
110392f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
110402f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
110412f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
110422f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
110432f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
110442f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
110452f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
110462f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
110472f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
110482f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
110492f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
110502f2e514554975d510c88df54de98c6cdc1080f1cglennrp
110513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
110523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
110533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
110553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
110563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
110573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
110583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
110593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
110603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
110613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
110623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
110633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
110643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
110653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
110660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
110683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
110690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
110710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
110733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
110753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
110763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
110773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
110783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
110793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
110803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1108103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
110833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
110843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
110873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
110883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
110893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
110900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
110930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
110953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11096d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1109739992b4dd9b12ef752d55b8e402c069698851f72glennrp
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
111023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
111030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
111053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1110739992b4dd9b12ef752d55b8e402c069698851f72glennrp
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
111113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11112d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11114