png.c revision 5a39f3714559b4d9c08beb391ce4326354bb0f0c
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 */
948371ecc013ff231ce380d8717e517312e62e1f01glennrp/* #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 */
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (((color).red == (target).red) && \
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).green == (target).green) && \
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).blue == (target).blue))
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
136cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  *ping_semaphore = (SemaphoreInfo *) NULL;
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
173bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
263bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
341bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38735ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
397b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  MagickBooleanType
398b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    need_blob;
399b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
422bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* Added at version 6.6.6-7 */
45526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  MagickBooleanType
45626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
45726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
45826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
45926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
46026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
46126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
46226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
46326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
46426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
46526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
466a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
46726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
46826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
46926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt;
47026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4790c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4880c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
4890c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
490fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
4910c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
4920c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
493fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrpLosslessReduceDepthOK(Image *image)
4940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
4950c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    MagickBooleanType
4960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      ok_to_reduce=MagickFalse;
4970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    /* Reduce bit depth if it can be reduced losslessly from 16 to 8.
4990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * Note that the method GetImageDepth doesn't check background
5000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * and doesn't handle PseudoClass specially.  Also it uses
5010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * multiplication and division by 257 instead of shifting, so
5020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * might be slower.
5030c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     */
5040c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5050c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    if (image->depth == 16)
5060c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
5070c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5080c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        const PixelPacket
5090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
5100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
5120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          (((((size_t) image->background_color.red >> 8) & 0xff)
5138640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.red & 0xff)) &&
5140c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp           ((((size_t) image->background_color.green >> 8) & 0xff)
5158640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.green & 0xff)) &&
5160c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp           ((((size_t) image->background_color.blue >> 8) & 0xff)
5178640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.blue & 0xff))) ? MagickTrue :
5188640fb5e9b1094f35f8beab436f81661b8a99448glennrp          MagickFalse;
5190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5200c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
5210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5220c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
5230c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5240c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
5250c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5268640fb5e9b1094f35f8beab436f81661b8a99448glennrp                ok_to_reduce=(((((size_t) image->colormap[indx].red >>
5278640fb5e9b1094f35f8beab436f81661b8a99448glennrp                    8) & 0xff)
5288640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].red & 0xff)) &&
5290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].green >> 8) & 0xff)
5308640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].green & 0xff)) &&
5310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].blue >> 8) & 0xff)
5328640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].blue & 0xff)) &&
53384758fbdf1574b04e67fc4f49d217b738768c614glennrp                  (image->matte == MagickFalse ||
53484758fbdf1574b04e67fc4f49d217b738768c614glennrp                  (((size_t) image->colormap[indx].opacity >> 8) & 0xff)
5358640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].opacity & 0xff))) ?
53613d07043243e0c8c151aad7db5240b75e76ca281cristy                  MagickTrue : MagickFalse;
5370c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5380c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5410c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5420c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
5430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
5440c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
5460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
5470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
5490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
5500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
5520c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
5530c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5540c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5550c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              if (p == (const PixelPacket *) NULL)
5560c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
5570c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
5580c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5590c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
5600c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5610c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
5620c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5638640fb5e9b1094f35f8beab436f81661b8a99448glennrp                ok_to_reduce=((
5648640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((size_t) p->red >> 8) & 0xff) ==
5658640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->red & 0xff)) &&
5660c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) p->green >> 8) & 0xff) ==
5678640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->green & 0xff)) &&
5680c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) p->blue >> 8) & 0xff) ==
5698640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->blue & 0xff)) &&
57084758fbdf1574b04e67fc4f49d217b738768c614glennrp                  (((image->matte == MagickFalse ||
5718640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((size_t) p->opacity >> 8) & 0xff) ==
5728640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->opacity & 0xff))))) ? MagickTrue : MagickFalse;
5730c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5740c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5760c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5770c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                p++;
5780c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5798640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
5800c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
5810c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
5820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5830c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
5850c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5860c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
587fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    OK to reduce PNG bit depth to 8 without loss of info");
5880c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
589a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        else
590a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          {
591a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
592fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    Not OK to reduce PNG bit depth to 8 without loss of info");
593a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          }
5940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
5950c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
5970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
5980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
5990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
600e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
601cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_to_PNG_RenderingIntent(const RenderingIntent intent)
6020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
603e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
604e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
605e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
606e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
6070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
608e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
609e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
6100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
611e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
612e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
6130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
614e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
615e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
6160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
617e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
618e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
619e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
620e610a071534e448c46460a5aa39ede33bf56b329glennrp}
621e610a071534e448c46460a5aa39ede33bf56b329glennrp
622e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
623cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_from_PNG_RenderingIntent(const int ping_intent)
6240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
625cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  switch (ping_intent)
626e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
627e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
628e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
6290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
630e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
631e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
6320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
633e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
634e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
6350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
636e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
637e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
6380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
639e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
640e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
641e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
642e610a071534e448c46460a5aa39ede33bf56b329glennrp}
643e610a071534e448c46460a5aa39ede33bf56b329glennrp
644bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
652bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6590c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
660dbb105fc25903e800273f7e980c0553060858a68glennrp
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
666dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s G r a y                                                     %
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
672dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
673dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
674dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
676dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsGray(Image *image)
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
681bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
683dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
684dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
689dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
690dbb105fc25903e800273f7e980c0553060858a68glennrp
691dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
693dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
694dbb105fc25903e800273f7e980c0553060858a68glennrp        if (IsGray(image->colormap+i) == MagickFalse)
695dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
696dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickTrue);
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
698bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
702dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
703dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
704dbb105fc25903e800273f7e980c0553060858a68glennrp    {
705dbb105fc25903e800273f7e980c0553060858a68glennrp       if (IsGray(p) == MagickFalse)
706dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
707dbb105fc25903e800273f7e980c0553060858a68glennrp       p++;
708dbb105fc25903e800273f7e980c0553060858a68glennrp    }
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
710dbb105fc25903e800273f7e980c0553060858a68glennrp  return(MagickTrue);
711dbb105fc25903e800273f7e980c0553060858a68glennrp}
712d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
7450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
7480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
7820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
7850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
830d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
831bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
853a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
861a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87403812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
87503812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
879e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
880e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
882d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
888d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
1002e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1003e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1031bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
10470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
10500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
10680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1107bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
11080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1122bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1134bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
11560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
11610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1174bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1176bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrpstatic void MngInfoFreeStruct(MngInfo *mng_info,
118121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    MagickBooleanType *have_mng_structure)
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
118321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp  if (*have_mng_structure != MagickFalse && (mng_info != (MngInfo *) NULL))
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1185bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
11900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
11940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
12080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
12110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
12140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
12170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1229bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1230bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1231bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1232bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1250bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
12528182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
12538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
12540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12648182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12668182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1269cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGErrorHandler(png_struct *ping,png_const_charp message)
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
12750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
12790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
12820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1283e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
12848371ecc013ff231ce380d8717e517312e62e1f01glennrp  /* A warning about deprecated use of jmpbuf here is unavoidable if you
12858371ecc013ff231ce380d8717e517312e62e1f01glennrp   * are building with libpng-1.4.x and can be ignored.
12868371ecc013ff231ce380d8717e517312e62e1f01glennrp   */
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1288faa852bad40107edae19405e76a299057668d795glennrp#else
1289faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1290faa852bad40107edae19405e76a299057668d795glennrp#endif
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1293cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGWarningHandler(png_struct *ping,png_const_charp message)
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
13000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1304cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
13050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
1311cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_voidp Magick_png_malloc(png_structp png_ptr,png_uint_32 size)
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
13190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
13220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1333cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_free_ptr Magick_png_free(png_structp png_ptr,png_voidp ptr)
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
1346cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_read_raw_profile(Image *image, const ImageInfo *image_info,
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1349bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13650c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
13770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
13810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1382f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
13830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
138497f90e23c85b9c58387880125c29d8c99126f83aglennrp  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
138597f90e23c85b9c58387880125c29d8c99126f83aglennrp       "      length: %lu",(unsigned long) length);
138697f90e23c85b9c58387880125c29d8c99126f83aglennrp
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
13890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
13990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
14110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1412bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
14280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
14370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
14400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1474bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
14760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1531faa852bad40107edae19405e76a299057668d795glennrp    pass,
1532faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1533faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1534faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1535faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1536faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
1537faa852bad40107edae19405e76a299057668d795glennrp    ping_num_trans;
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1539a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  LongPixelPacket
1540a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    transparent_color;
1541a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
15434383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1546faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1547faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1548faa852bad40107edae19405e76a299057668d795glennrp
1549faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1550faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1551faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1552faa852bad40107edae19405e76a299057668d795glennrp
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1563faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1564faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1565faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
1566faa852bad40107edae19405e76a299057668d795glennrp    ping_rowbytes;
1567faa852bad40107edae19405e76a299057668d795glennrp
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
1572cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1574bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
15815c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1583bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
159139992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
1607fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOnePNGImage()");
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1610cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
161325c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
161961b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
162061b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
162161b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
162261b4c957269727a0a2526edc2331881da8346100glennrp    {
162361b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
162461b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
162561b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
162661b4c957269727a0a2526edc2331881da8346100glennrp    }
162761b4c957269727a0a2526edc2331881da8346100glennrp#  endif
162861b4c957269727a0a2526edc2331881da8346100glennrp#endif
162961b4c957269727a0a2526edc2331881da8346100glennrp
163061b4c957269727a0a2526edc2331881da8346100glennrp
1631ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1634a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
1635a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
1636a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      "  image->matte=%d",(int) image->matte);
1637a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
16380e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
16390e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
16400e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
16410e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
16420e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.opacity=65537;
16430e319739731741c52a6303723e0c8678a0df5579glennrp
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
1649cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
1650cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
1653cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
16590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
16670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1674cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
16750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1676faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1683cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
16880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
16907b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
16917b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
16927b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
16937b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
16940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1700faa852bad40107edae19405e76a299057668d795glennrp
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
17030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1736991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1737991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1738991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1752991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1756faa852bad40107edae19405e76a299057668d795glennrp
1757faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1758faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1759faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1760faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1761faa852bad40107edae19405e76a299057668d795glennrp
1762faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1763faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1764faa852bad40107edae19405e76a299057668d795glennrp
1765faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1766faa852bad40107edae19405e76a299057668d795glennrp
1767faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1769faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1770faa852bad40107edae19405e76a299057668d795glennrp        {
1771faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1772faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1773faa852bad40107edae19405e76a299057668d795glennrp        }
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1775faa852bad40107edae19405e76a299057668d795glennrp
1776faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1778faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1782e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1783e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
17840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1787faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
17880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1791faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
17920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1795faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1798faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1799faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1804e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
1805e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
1806e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1807e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
1808e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
1809e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1810e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
1811e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1842cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
1843cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        (mng_info->global_srgb_intent);
18440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1847cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
1848cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (intent);
18490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1852e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1860faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1861faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1862faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
18630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1872faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1873faa852bad40107edae19405e76a299057668d795glennrp    {
1874faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1875faa852bad40107edae19405e76a299057668d795glennrp        {
1876faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1877faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1878faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1879faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1880faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1881faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1882faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1883faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1884faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1885faa852bad40107edae19405e76a299057668d795glennrp        }
1886faa852bad40107edae19405e76a299057668d795glennrp    }
18870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1888faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
18990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1905e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1907e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
1908cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         Magick_RenderingIntent_to_PNG_RenderingIntent
1909cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         (image->rendering_intent));
1910faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
1911faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
1912faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
1913faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
1916faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1918905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
1919905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
19200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1924e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
1925e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
1929faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
1930faa852bad40107edae19405e76a299057668d795glennrp    {
1931faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
1932faa852bad40107edae19405e76a299057668d795glennrp        {
1933faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
1934faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
1935faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
1936faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
1937faa852bad40107edae19405e76a299057668d795glennrp        }
1938faa852bad40107edae19405e76a299057668d795glennrp    }
1939faa852bad40107edae19405e76a299057668d795glennrp
1940faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
19530881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
19540881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
19550881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
19560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1966e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
1967e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1970faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
19790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
1981faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
19870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1988faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2005faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2014faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2015faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
20160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
2038faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2039faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2042faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
20500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20512cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2053faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
2054faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
2055faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20582cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20602cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
20612cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
20622cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20632cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
20642cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20652cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
20662cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
20672cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20682cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
20690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20702cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
20712cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
20720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20732cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
20742cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
20750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20762cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
20772cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
20780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20792cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
20802cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
20812cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20822cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
20832cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
20842cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
20852cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20862cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
20872cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
20882cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20892cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
20900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20912cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20922cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
20932cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
20942cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
20952cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
2097faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
20980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
2100faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
21010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
2103faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
21040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2105f17da7472c6195cfc91626d98d166cae04345d34cristy          image->background_color.opacity=OpaqueOpacity;
21062cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21072cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21082cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2109e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
2110e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
2111e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
2112e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2116a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2117faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2120a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
21213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
212535ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
212635ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
212735ef824baa82511126ff0072ae30eee0da9c05a3cristy
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2132f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2134faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2135faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2136faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2137faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2138faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2139faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2145faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2150a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2151a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2152a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2153a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          scale_to_short = 65535L/((1UL << ping_bit_depth)-1);
2154a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2155a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2156a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2157a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2158a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
2159a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.opacity= scale_to_short*ping_trans_color->gray;
216005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2161faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
21630f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
21640f111984738842d27d04aed2a3f823d82a943506glennrp              {
21650f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21660f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
21670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21680f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21690f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
21700f111984738842d27d04aed2a3f823d82a943506glennrp              }
21713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2180faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2185faa852bad40107edae19405e76a299057668d795glennrp
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2187faa852bad40107edae19405e76a299057668d795glennrp
2188faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2189faa852bad40107edae19405e76a299057668d795glennrp
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2194bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2196bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2199faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2200faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2211faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2212faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2213faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2214faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2215faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2217befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2218befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2219befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2221befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2222befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2230faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2239bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
22400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2255faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
22640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2265bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2275bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2278faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
22790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
22820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2283bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
22960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22970ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2298347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2299347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2303e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2307cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
23120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
23190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
2321cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2322cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_rowbytes*sizeof(*ping_pixels));
23230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2325cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
2326cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
23270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2328cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2337faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2344cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
23480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2349cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
2350cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
23510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
23550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
23577b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
23587b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
23597b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
23607b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
23610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2365ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
23660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2367ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2368ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2370c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
2371c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2372c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
2373c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
2374c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2375c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
2376c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2379c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
2380c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2381c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
2382c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
2383c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
2384c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#if  (MAGICKCORE_QUANTUM_DEPTH == 8)
2385c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        int
2386c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          depth;
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2388c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        depth=(ssize_t) ping_bit_depth;
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2390c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2391c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2392c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2393c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            MagickTrue : MagickFalse;
23940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2395c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
2396c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
2397c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
2398c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
23990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2400c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
2401c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
24020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2403cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
2404c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2406c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (q == (PixelPacket *) NULL)
2407c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
24080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2409c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#if  (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
2410c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp/* code deleted from version 6.6.6-8 */
2411c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#else  /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
24120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2413c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2415cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              GrayQuantum,ping_pixels+row_offset,exception);
24160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2417c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2419cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              GrayAlphaQuantum,ping_pixels+row_offset,exception);
24200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2421c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2423cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              RGBAQuantum,ping_pixels+row_offset,exception);
24240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2425c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2426c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2427cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              IndexQuantum,ping_pixels+row_offset,exception);
24280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2429c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
2430c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2431cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              RGBQuantum,ping_pixels+row_offset,exception);
2432c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#endif
2433c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
2434c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2435c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
2436a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
2437a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2438a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
2439a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2440c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
2441c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
24425aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
24435aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
24445aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                   (q->opacity != OpaqueOpacity))
2445c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
2446a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2447a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2448a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
2449a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2450c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
2451c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
2452c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
24534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
24544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
2455a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    (ScaleQuantumToShort(q->red) == transparent_color.red &&
2456a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    ScaleQuantumToShort(q->green) == transparent_color.green &&
2457a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    ScaleQuantumToShort(q->blue) == transparent_color.blue))
24584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
2459a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2460a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2461a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
24624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
24634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
24644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
2465c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                q++;
2466c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
2467c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
24680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2469c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
2470c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2471c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2472c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
24730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2474c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
2475c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
2476c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
2477c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
2478c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
2479c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
24800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2481c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
24827a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2483c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
24847a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
24857a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
24867a287bfadeadea12e47c2376ca78a5d101687142cristy          }
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
2491c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
24963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
24983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
24993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
25023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2503faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
25043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
25050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
25073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
25080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
25103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
25110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2512bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
25133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2515faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
2516c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
2519c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2520cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
25220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25265c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
2527cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2529c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2530faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
25313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2534bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2537bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
25423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2546bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
25473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
255247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2555bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
25583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2565bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
257147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2574bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
25773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
25820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
258547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
25863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2588faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2589bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
2598c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                if (q->opacity != OpaqueOpacity)
25990b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2604bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
260947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2612bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2615bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
262847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2629faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
2634c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
26350b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2640bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
26530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2654faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
2657afee4d36aae894a74306a3c492437ca55dce2badcristy                  q->opacity*=65537L;
265846f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
2659afee4d36aae894a74306a3c492437ca55dce2badcristy                  if (q->opacity != OpaqueOpacity)
26600b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
266447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
266847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2669faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
2672c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
26730b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
268047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
268347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
26910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2692bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
269380ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
26940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26987a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
26997a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2700cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2701cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
270247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27037a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
27047a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
27057a287bfadeadea12e47c2376ca78a5d101687142cristy          }
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2707c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27087a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
271147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
2715c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2718c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2719c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    image->matte=found_transparent_pixel;
2720c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2721c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
2722c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2723c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
2724c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2725c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
2726c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
27275aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
27285aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27295aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
2730a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
27315aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
27325aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
2733c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
2734c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
2735c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2736b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2737b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
27380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27395c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
27405c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2741aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
27425c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
27435c6f789db7a30bad01ace12b09ad9cd471339e94cristy
27445c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
27455c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
27465c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2747aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
27485c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
274947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
27513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2753bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2756cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2760cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
276747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2768faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
27743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
27763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2778c11cf6a442f3046940608a5743a68cc891deb13eglennrp
27793c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
2780c11cf6a442f3046940608a5743a68cc891deb13eglennrp
27810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
27820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
27830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2784c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
27850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
27860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
27870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 image->colormap[x].opacity =
27880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                   ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
27890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
2790c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
279147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
27930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
27940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
27950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
27960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
27970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                     transparent_color.opacity)
27980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
27990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    image->colormap[x].opacity = (Quantum) TransparentOpacity;
28000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
28010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
28020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) SyncImage(image);
28040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
280547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2806a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
2807a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
2808a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
28090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
28100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
28120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
28130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
28140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2815c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (q == (PixelPacket *) NULL)
28170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
2818c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            indexes=GetAuthenticIndexQueue(image);
28200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2821a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
2822a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
2823a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
28240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
28250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
2826a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (ScaleQuantumToShort(q->red) == transparent_color.red &&
2827a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  ScaleQuantumToShort(q->green) == transparent_color.green &&
2828a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  ScaleQuantumToShort(q->blue) == transparent_color.blue)
28294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  q->opacity=(Quantum) TransparentOpacity;
28314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
28320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2833a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 0 /* I have not found a case where this is needed. */
28340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
28354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  q->opacity=(Quantum) OpaqueOpacity;
28374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
2838a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
28390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              q++;
28410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
28440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
2845c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
28460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
2847a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
2848c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28513c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
2852b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2853b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2854b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
285547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
2857bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) num_text; i++)
28583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
28603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
28640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
2866cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (void) Magick_png_read_raw_profile(image,image_info,text,(int) i);
28670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
28693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
28713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
28723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
28743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
28753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
28783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
28793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
28803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
28823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
28833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
28843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
28853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
28860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
288897f90e23c85b9c58387880125c29d8c99126f83aglennrp          {
288997f90e23c85b9c58387880125c29d8c99126f83aglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
289097f90e23c85b9c58387880125c29d8c99126f83aglennrp              "      length: %lu",(unsigned long) length);
28913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
289397f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
28940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28983c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
29003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
29043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
291173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
29120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
291947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
29270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
29293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
29400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
29430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
29460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2952faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
29540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2955faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
2956faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
2957faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
2958faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
2959faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
2960faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
2961faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
2962faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
29630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2964faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
29773c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
298347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2994cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2996cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
30020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
301521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
301621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
303347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
303747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3040fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
304447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
304747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
305247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3053dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
305547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
306073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
306147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
306447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
307547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
30773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
30820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
30853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
30900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
309347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
309547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
31010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
310447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
31080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
311447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
31230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
312597f90e23c85b9c58387880125c29d8c99126f83aglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
312697f90e23c85b9c58387880125c29d8c99126f83aglennrp        "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
312797f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.width,(double) image->page.height,
312897f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.x,(double) image->page.y);
312997f90e23c85b9c58387880125c29d8c99126f83aglennrp
313097f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
31320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31844383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
31854383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
31864383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3187bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3210bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3225bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
3239fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
32420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
32510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
32530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
32560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
32840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
32870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3295e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3296e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
33000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
330347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
33070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
33100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3311bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
33130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
331647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
332347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3331bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3333bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
333947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
334247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
334747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3351f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
335247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3354f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
335547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
335847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
336247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
336647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
337047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
337447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
337847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
338247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
338847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
339147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
340773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
340847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
341147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
34140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
34210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
34250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
343273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
34330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
34390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
34500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
34540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
34570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
34660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
34690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
347203812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
348947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
349647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
349947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
350847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3516bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
351803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
353347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
35530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
35838182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
35840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
35948182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
35958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
35968182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
35978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
35988182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
35998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
36008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
360247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3611e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3612cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
362347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36325eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
36335eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
36340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
364147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36528182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
36538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3669fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
36820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
371147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
37150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
37180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
37210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
37350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
37390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3740bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
374547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
37510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
376203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
37660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
37680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
37770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3779bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
378447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3786bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
37880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3790bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
37960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
380847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
380947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
38170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
38190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
38200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
38230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
38250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
38260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
38290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
38310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
38360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
38400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
388221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
388321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3903fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
39070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
39100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
391447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
391547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
391747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39183b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
392147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
392247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
392473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
39250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
392947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
393047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
39380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
39460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
39500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
395447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
39600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
39660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39804383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
398121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
398221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
39834383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3990bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4015bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4021bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4038bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
404738ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
404838ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
404938ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4050bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
407247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
407347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4079fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
40830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
40860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
409047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
409147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
409247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
409373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
40940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
409847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
409947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
410947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
411347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
411447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4117bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4118bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
412247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4165e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4166e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
41700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
41730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
41760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
418047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
418347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4184bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
418647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
41960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
42000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
42070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
42110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
421647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
42210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
42280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4234bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
42360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4237bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
42390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4243e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4245e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
42498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
42500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
42530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
42570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
42600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
42648182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
42680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
42710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
42740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
428147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
42830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
42860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
42940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4295e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4296e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4297f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
42980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4300bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4302bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
43040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
43070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
43200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43238182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
43248182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
43250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
43280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
43370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4339e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
43400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4342e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
43540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
43560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
43610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
43830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
43850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
43880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
43950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
43960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
43980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
43990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4403e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4404f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
44050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4407e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4408f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
44180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
44250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
44300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
44330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
44360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
44480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
44510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
44560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
44590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
44620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
447447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
447747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
447847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
44840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4485bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
449235ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
45010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
45070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
451147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4517bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
452412560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4532bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45358182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
45420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
454947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
455047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
45548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
45558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
45578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
45598182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
45618182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
45638182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
45658182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
457047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
457447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4582e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4583cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
458847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
459247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4595fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
460247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
460547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
46120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
46150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
461947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
46230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
46270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
463047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
463147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
463347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4634bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
463647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
463847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4639bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
465047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
46538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
46548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
46550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
46578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
46580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4659bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4660bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
46610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
46640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
46660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4669e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
467147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4674bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4675bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
46760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4677bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4678bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
46790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4680bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4681bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
46820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
46850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
46870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4690e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
469247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
46980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
4702e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4703e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
470447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
47120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4713bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
47150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4716bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4724e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4725e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
47260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
473047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
473447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
474147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
47460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
47560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
47670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4771e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4772e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
478947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
480147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
482547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
482647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4835bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4838bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
485047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4853bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
485747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
485847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4861bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
487847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4885bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
488847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
488947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
48908182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
48910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4894e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
4895e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
48960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
48990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
491047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
491447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
492647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
49330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
4937e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
4938f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
493947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
49440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
494947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
496747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
497147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
497847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
498147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
49980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
50010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
50040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
501547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
502147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
502747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
503047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
503647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
503947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
504547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
504847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
505447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
505747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
506347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
506647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
507247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
507547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
508147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
508547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
509347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
511247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
511947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
512247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
512947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
513247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
513747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
51538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
51558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
515947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
516847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
517447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
517947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5182bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5184bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
519247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
519547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
519847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
520147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
520447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
520747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
521047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
521847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
522147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
522447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
522947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
523947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
524647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
524947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
525547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
526347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52648182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
52658182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5278bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5280bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
528847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
529547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
529947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
530647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
530947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
531047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
531147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5323e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5324e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
534147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
534847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
53510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
53530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
536347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
53740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5378e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5379e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
538347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
539047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
539747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
54030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
54060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
54150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
54240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
543047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
543447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
543947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5440bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
544147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
545347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
546647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
54700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
54780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
549947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
550247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
550447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
550547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
550747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55104e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
551147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
551447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
551747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
551947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
552047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
552247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
552647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
552947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
553147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
553247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
553447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55374e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
553847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
554147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
554447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
554647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
554747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
554947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5559bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5563bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
557847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
557947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
558347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
558547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5609bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
561347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5614bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
562247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
563347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
563847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
564147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
564447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
564747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5656e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5657bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
566247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
567147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
567447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5675bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5678bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
567947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5680bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5681bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
568247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5683bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5684bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
568547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5686bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
568847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5690bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
569147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
569547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5696bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
570247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5708bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
571447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5715bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
5717fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
572847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
573347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5737bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5738bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5740bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5741bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5743bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5744bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
574647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5748bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5751bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
575347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
576347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
576947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
577247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5775bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
578447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
578747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
579047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5809e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5811bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
581947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5820bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5821bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5823bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5824bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
582547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5826bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5827bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
582847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5829bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5830bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
583147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5832bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
583447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5836bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
583747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
584547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
585047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5856bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5859bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5862bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
5865bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
586847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
587847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
588447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
588747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
5892bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
590147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
5911bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
591447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5915bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
592347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
595747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
5973bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
5974bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
598047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
599247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60152b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
60162b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
60172b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       * if lossy
60182b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
60192b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
60202b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
60212b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
60222b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
60230c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
60248640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if (LosslessReduceDepthOK(image) != MagickFalse)
60258640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6027d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
602947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6033bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6036d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6040d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
604247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
604447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
604847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
60590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
607047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
607447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
60870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
60900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
60950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
60980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
610647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
611047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
61150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
612047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
612647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
613447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
613947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
614547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
614847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
615147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
61590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
61620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
61650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
617047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
61760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
61780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6181e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6182e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
61830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
619147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
619447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6196e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
619747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6202e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6214bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
621947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
622247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
622547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
622847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
623747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
624047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
625747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
626747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
627047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6272e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6273e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
627447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6276f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6277f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
627847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6279f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6280e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6281e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6282f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6283f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
628447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
628847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
629147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
629425c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
629947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
630247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
630547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
631025c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6333bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6336bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
634947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
635547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
636347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
636747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
637547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
637847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
638347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
638647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
638947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
639547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
640047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
640547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
640847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
641347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
641847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
642847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
643247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
643947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
644247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
644747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
645547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
646047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
646847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
647547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
648247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
648318b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6484cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_semaphore=AllocateSemaphoreInfo();
648518b17443128598500357da7bff2f01683cf32890cristy#endif
648647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
651747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6519cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
6520cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    DestroySemaphoreInfo(&ping_semaphore);
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
652525c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
6601cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6608bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
66290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
66300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
66320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6651f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
665347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6654bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
666147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
666847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
667147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6677cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
66784383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
669247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
669347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
669447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
669647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
6700cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
670247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
670347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
670447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
670547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
670647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
670747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6708cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
6709cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
6710cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
671147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
671247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
671347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
671447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
671547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
671647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
671747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
6718cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
671947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
672147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
672447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6728b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6729b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
6731b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp   const ImageInfo *IMimage_info,Image *IMimage)
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6733b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  Image
6734b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image;
6735b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6736b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  ImageInfo
6737b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image_info;
6738b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6752cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6753cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6754e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6755e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
67565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
675739992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
675839992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
67615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
67625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
67635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
67715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
67725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
67735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6774bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
677858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
677921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
678058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
678158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
6782fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
6783d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
67848d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
678539992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
6786991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
6787991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
6788991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
678926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
679026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
679126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
6792e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
679326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
679426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
679526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
679626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
679726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
679826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
679926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
6800e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
680126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
680226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
680326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
680426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
68050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
68060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6812bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
6817cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
6820f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
68210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
68225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
68235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
68245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
68255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
68265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
68275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6828bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
68295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
68305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6832bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
68333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6837dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
6838fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
6839f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
68408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
68418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
68428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
6843dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
6844dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6845dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
6846dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
6847dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
6848dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
6850fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6852b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image = CloneImage(IMimage,0,0,MagickFalse,&IMimage->exception);
6853b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
6854b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6855b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  if (mng_info->need_blob != MagickFalse)
6856b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  {
6857b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) ==
6858b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       MagickFalse)
6859b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    {
6860b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
6861b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
6862b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      return(MagickFalse);
6863b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    }
6864b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  }
6865b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6867cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
68710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
68725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
68735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
68745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
68755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
68765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
68775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
68795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
68805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
68815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
68825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
68835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
68855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
68865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
68875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
68885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6889dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
6890dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
6891dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
6892dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6893d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
68948d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
689539992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
6896991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
6897991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
6898991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
6899991d11dd9c33e65872778b81aff1347cd2878154glennrp
69000e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
69010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
6902dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
69030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
69040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
69050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
69060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
69070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
69080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
69090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
69100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
6911dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
69120e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
69130e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
69140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
69150e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
69160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
69170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
69188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
69198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
69208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
69218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
6922fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
6923fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
6924fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
6925fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6926fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
6927fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
6928fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6929fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
6930fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
6931fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6932fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
6933fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
6934fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
69370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
69383241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
69393241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
69403241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
69413241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
69423241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
69433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp     (void) SyncImage(image);
69443241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
6945a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
6946a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
6947a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
6948a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
6949a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6950a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
6951a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
6952a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
6953a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
6954a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
6955a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
6956a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
69572b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
69582b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
69592b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
69602b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
69612b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  if (image->depth > 16)
69622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
69632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
69642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
69658640fb5e9b1094f35f8beab436f81661b8a99448glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
6966c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
69678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
69688640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
69698640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
69708640fb5e9b1094f35f8beab436f81661b8a99448glennrp
6971fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  for (j=0; j<3; j++)
6972d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
6973d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp    /* BUILD_PALETTE
6974d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
6975d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
6976d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
6977d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
6978d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
6979d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
6980d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
6981d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
6982d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
6983d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
6984d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * If image->matte is MagickFalse, we ignore the opacity channel
6985d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
6986d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
6987d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
6988d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
6989d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
6990d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
6991d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
6992d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
6993d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
69943c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
6995d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   ExceptionInfo
6996d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *exception;
69978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
6998d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
6999d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
70008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7001d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   PixelPacket
7002d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
7003d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
7004d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
70058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7006d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   register IndexPacket
7007d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *indexes;
70088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7009d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   register const PixelPacket
7010d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *s,
7011d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *q;
7012d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7013fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   register PixelPacket
7014fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
7015fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7016d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7017d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7018d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
7019d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7020d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7021d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7022d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7023d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
7024d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7025d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
7026d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7027d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->matte=%.20g",(double) image->matte);
702803812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7029d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
70303c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7031fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
70327ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
70337ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7034d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
70358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7036d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "        i    (red,green,blue,opacity)");
70372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7038d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
70397ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
7040d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7041d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7042d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7043d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7044d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7045d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
7046d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].opacity);
70477ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
70482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7049d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
7050d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7051d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
7052d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7053d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7054d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7055d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7056d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7057d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7058d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
7059d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].opacity);
7060d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7061d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
7062d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
70632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7064d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7065d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
706683c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7067d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
7068d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7069d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "        (zero means unknown)");
70707ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7071d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7072d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      Regenerate the colormap");
7073d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
70747ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7075d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     exception=(&image->exception);
7076d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7077d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
7078fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
7079fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
7080fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
70812cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7082d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
7083d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7084d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
70857ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7086d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (q == (PixelPacket *) NULL)
7087d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
708897fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
7089d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
7090d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7091d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (image->matte == MagickFalse || q->opacity == OpaqueOpacity)
70928d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7093d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
70948d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7095d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
7096d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7097d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[0]=*q;
7098d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[0].opacity=OpaqueOpacity;
7099d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
7100d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7101d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7102d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
7103d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7104d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(opaque+i, (PixelPacket *) q))
7105d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7106d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7107d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7108d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_opaque &&
7109d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque < 259)
7110d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7111d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
7112d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[i] = *q;
7113d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[i].opacity = OpaqueOpacity;
7114d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
71158d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
71168d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
7117d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (q->opacity == TransparentOpacity)
71188d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7119d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
71208d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7121d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
7122d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7123d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       transparent[0]=*q;
7124d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.red=(unsigned short)(q->red);
7125d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.green=(unsigned short) (q->green);
7126d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.blue=(unsigned short) (q->blue);
7127d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.gray=(unsigned short) (q->blue);
7128d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
7129d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7130d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7131d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
7132d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7133d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(transparent+i, (PixelPacket *) q))
7134d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7135d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7136d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7137d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
7138d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
7139d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7140d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
7141d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       transparent[i] = *q;
7142d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
71438d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
71448d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
7145d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7146d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7147d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
7148d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7149d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
7150d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7151d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       semitransparent[0]=*q;
7152d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
7153d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
71548d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
7155d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
7156d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7157d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(semitransparent+i,
7158d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          (PixelPacket *) q) &&
7159d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          q->opacity == semitransparent[i].opacity)
7160d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7161d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7162d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7163d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
7164d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
7165d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7166d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
7167d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       semitransparent[i] = *q;
7168d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7169d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
71708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
7171d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           q++;
7172d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
7173d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
71743c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7175d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (ping_exclude_bKGD == MagickFalse)
7176d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7177d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
7178d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
7179d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7180d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
7181d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
7182d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             if (IsColorEqual(opaque+i,
7183d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                &image->background_color))
7184d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             break;
7185d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
7186a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7187d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
718803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
7189d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               opaque[i]=image->background_color;
7190d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               opaque[i].opacity = OpaqueOpacity;
7191d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               number_opaque++;
719203812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
7193d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
71942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7195d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
71963241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7197d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
7198d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7199d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
7200d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7201d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
72023241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7203d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
7204d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7205d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
7206d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
72073241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7208fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
7209d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7210d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
7211d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_non_bw=MagickFalse;
72123241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7213d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
7214d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
7215d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
7216d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7217d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
72186185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7219d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (q == (PixelPacket *) NULL)
7220d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
72216185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7222d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
7223d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
7224d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
72256185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7226d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_color == MagickFalse)
7227d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7228d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
7229d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
7230d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   {
7231d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     if (s->red != s->green || s->red != s->blue)
7232d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
7233d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          ping_have_color=MagickTrue;
7234d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          ping_have_non_bw=MagickTrue;
7235d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          break;
7236d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
7237d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     s++;
7238d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
7239d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
72403241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7241d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
7242d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7243d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
7244d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
72456185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
7246d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     if (s->red != 0 && s->red != QuantumRange)
7247d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
7248d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
7249d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
7250d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     s++;
7251d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
7252d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
7253d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7254d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           }
7255d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
72564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
7257d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
7258d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7259d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         PixelPacket
7260d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
7261d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7262d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
7263d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
7264d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7265d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7266d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
7267d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7268d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
7269d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7270d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
7271d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7272d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
72733241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7274d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
7275d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
72763241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7277d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
7278d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
7279d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7280d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
7281d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
7282d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7283d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7284d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
7285d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
7286d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7287d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
7288d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7289d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
7290d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7291d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
7292d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
7293d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
7294d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
7295d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
7296d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
7297d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
7298d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7299d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7300d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
7301d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7302d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
7303d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
7304d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7305d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
73063241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7307d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
7308d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
7309d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
7310d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
7311d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
7312d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
7313d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
73146185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
7315d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
7316d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7317d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
7318d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
73192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7320d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7321d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
7322d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7323d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7324d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
7325d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7326d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (AcquireImageColormap(image,image_colors) ==
7327d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
7328d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               ThrowWriterException(ResourceLimitError,
7329d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "MemoryAllocationFailed");
7330d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7331d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
7332d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
7333d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7334d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
7335d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
7336d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7337d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
7338d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
7339d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7340d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7341d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
7342d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7343d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7344fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
7345fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7346d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
7347d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
7348d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              q=GetAuthenticPixels(image,0,y,image->columns,1,
7349d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  exception);
73503c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7351d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (q == (PixelPacket *) NULL)
7352d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
73533c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7354d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              indexes=GetAuthenticIndexQueue(image);
7355d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7356d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
7357d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
7358d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
735903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
7360d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  if ((image->matte == MagickFalse ||
7361d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      image->colormap[i].opacity == q->opacity) &&
7362d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (IsColorEqual(&image->colormap[i],
7363d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         (PixelPacket *) q)))
73646185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
7365d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    indexes[x]=(IndexPacket) i;
7366d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
73676185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
736803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
7369d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                q++;
7370d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7371d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7372d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
7373d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
7374d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
7375d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
7376d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
7377d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7378d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
7379d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7380d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7381d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
7382d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7383d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
7384d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
7385d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7386d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 "       i     (red,green,blue,opacity)");
738783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7388d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
7389d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7390d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (i < 300 || i >= image->colors - 10)
7391d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7392d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7393d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
7394d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
7395d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
7396d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
7397d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
7398d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].opacity);
7399d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
74006185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
74016185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
74023c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7403d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
7404d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7405d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
7406d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
7407d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
74083c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7409d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7410d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
74113c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7412d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
7413d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7414d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
7415d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
741603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
7417d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7418d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7419d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
74206185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7421d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
7422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7423d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
7424d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
74256185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7426d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7427d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
7429a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7430d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
7431d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
7433a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7434d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
7435d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7436d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
7437d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7438d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7439d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
74416185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
744203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
744303812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
7444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
74453c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7446fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   if (mng_info->write_png8)
7447fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     {
7448fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image_colors <= 256 &&
7449fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image_colors != 0 &&
7450fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           number_semitransparent == 0 &&
7451fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           number_transparent <= 1)
7452fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         break;
7453fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7454fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       /* PNG8 can't have semitransparent colors so we threshold them
7455fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        * to 0 or OpaqueOpacity
7456fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        */
7457fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
7458fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
7459fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7460fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               "    Thresholding the alpha channel to binary");
7461fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7462fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
7463fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
7464fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             r=GetAuthenticPixels(image,0,y,image->columns,1,
7465fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 exception);
7466fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7467fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (r == (PixelPacket *) NULL)
7468fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
7469fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7470fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
7471fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
7472fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 r->opacity = r->opacity > OpaqueOpacity/2 ? 0 :
7473fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      OpaqueOpacity;
7474fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 r++;
7475fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
7476fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7477fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
7478fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
7479fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7480d7d0418dd0afcd0b9948254cd6e88a8f6c9f051eglennrp             if (image_colors != 0 && image_colors <= 256 &&
7481d7d0418dd0afcd0b9948254cd6e88a8f6c9f051eglennrp                image->colormap != NULL)
7482fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               for (i=0; i<image_colors; i++)
7483fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   image->colormap[i].opacity =
7484fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                       image->colormap[i].opacity > OpaqueOpacity/2 ? 0 :
7485fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                       OpaqueOpacity;
7486fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
7487fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         continue;
7488fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       }
7489fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7490fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       /* PNG8 can't have more than 256 colors so we do a quick and dirty
7491fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        * quantization of the pixels and background color to the 3-3-2
7492fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        * palette.
7493fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        */
7494d7d0418dd0afcd0b9948254cd6e88a8f6c9f051eglennrp       if (image_colors != 0 && image_colors <= 256 &&
7495d7d0418dd0afcd0b9948254cd6e88a8f6c9f051eglennrp           image->colormap != NULL)
7496fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
7497fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (logging != MagickFalse)
7498fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7499fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  "    Quantizing the background color to 3-3-2");
7500fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7501fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->background_color.red =
7502fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 (image->background_color.red & 0xe0) |
7503fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 ((image->background_color.red & 0xe0) >> 3) |
7504fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 ((image->background_color.red & 0xc0) >> 6);
7505fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->background_color.green =
7506fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 (image->background_color.green & 0xe0) |
7507fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 ((image->background_color.green & 0xe0) >> 3) |
7508fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 ((image->background_color.green & 0xc0) >> 6);
7509fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->background_color.blue =
7510fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 (image->background_color.blue & 0xe0) |
7511fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 ((image->background_color.blue & 0xe0) >> 3) |
7512fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 ((image->background_color.blue & 0xc0) >> 6);
7513fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7514fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
7515fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->background_color.red <<= (MAGICKCORE_QUANTUM_DEPTH-8);
7516fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->background_color.green <<= (MAGICKCORE_QUANTUM_DEPTH-8);
7517fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->background_color.blue <<= (MAGICKCORE_QUANTUM_DEPTH-8);
7518fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp#endif
7519fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7520fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (logging != MagickFalse)
7521fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7522fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "    Quantizing the pixel colors to 3-3-2");
7523fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
7524fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
7525fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             r=GetAuthenticPixels(image,0,y,image->columns,1,
7526fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 exception);
7527fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7528fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (r == (PixelPacket *) NULL)
7529fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
75308d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
7531fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
7532fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
7533fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 r->red = (r->red & 0xe0) | ((r->red & 0xe0) >> 3) |
7534fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ((r->red & 0xc0) >> 6);
7535fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 r->green = (r->green & 0xe0) | ((r->green & 0xe0) >> 3) |
7536fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ((r->green & 0xc0) >> 6);
7537fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 r->blue = (r->blue & 0xe0) | ((r->blue & 0xe0) >> 3) |
7538fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ((r->blue & 0xc0) >> 6);
7539fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
7540fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 r->red <<= (MAGICKCORE_QUANTUM_DEPTH-8);
7541fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 r->green <<= (MAGICKCORE_QUANTUM_DEPTH-8);
7542fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 r->blue <<= (MAGICKCORE_QUANTUM_DEPTH-8);
7543fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp#endif
7544fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 r++;
7545fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
7546fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7547fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
7548fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
7549fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
7550c722dd852e8abe407c2846d39662f7ade9c234deglennrp
7551d7d0418dd0afcd0b9948254cd6e88a8f6c9f051eglennrp         if (image_colors != 0 && image_colors <= 256 &&
7552d7d0418dd0afcd0b9948254cd6e88a8f6c9f051eglennrp           image->colormap != NULL)
7553fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
7554fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (logging != MagickFalse)
7555fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7556fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "    Quantizing the colormap to 3-3-2");
7557fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (i=0; i<image_colors; i++)
7558fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
7559fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 image->colormap[i].red = (image->colormap[i].red & 0xe0) |
7560fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ((image->colormap[i].red & 0xe0) >> 3) |
7561fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ((image->colormap[i].red & 0xc0) >> 6);
7562fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 image->colormap[i].green = (image->colormap[i].green & 0xe0) |
7563fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ((image->colormap[i].green & 0xe0) >> 3) |
7564fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ((image->colormap[i].green & 0xc0) >> 6);
7565fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 image->colormap[i].blue = (image->colormap[i].blue & 0xe0) |
7566fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ((image->colormap[i].blue & 0xe0) >> 3) |
7567fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ((image->colormap[i].blue & 0xc0) >> 6);
7568fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
7569fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 image->colormap[i].red <<= (MAGICKCORE_QUANTUM_DEPTH-8);
7570fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 image->colormap[i].green <<= (MAGICKCORE_QUANTUM_DEPTH-8);
7571fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 image->colormap[i].blue <<= (MAGICKCORE_QUANTUM_DEPTH-8);
7572fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp#endif
7573fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              }
7574fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
7575fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         continue;
7576fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       }
7577fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       break;
7578fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
7579fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   else
7580fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     break;
7581fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
7582fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
7583fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7584fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
7585fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
7586fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
7587fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
75880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
75890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
75900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
75910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      int colortype=mng_info->write_png_colortype;
75920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
75930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
75940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
75950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
75960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
75970e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
75980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
75998d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
76008d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         mng_info->write_png_colortype != (ssize_t) colortype)
76010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
76020b206f5daa453dc1035db5890cabc899736dc2d0glennrp
76030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
76040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
7605fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
7606fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
7607fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
76085a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
76095a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
76105a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
7611fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
76125a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
76135a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
7614fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7615fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
7616fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7617fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
7618fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
7619fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7620fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
7621fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
7622fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
7623fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           ExceptionInfo
7624fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *exception;
7625fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7626fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           register const PixelPacket
7627fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
7628fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7629fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           exception=(&image->exception);
7630fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7631fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
7632fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
7633fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
7634fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7635fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (q == (PixelPacket *) NULL)
7636fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
7637fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7638fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
7639fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
7640fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 if (q->opacity != TransparentOpacity &&
7641fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->red == ping_trans_color.red &&
7642fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->green == ping_trans_color.green &&
7643fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->blue == ping_trans_color.blue)
7644fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
7645fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
7646fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
7647fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
7648fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7649fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 q++;
7650fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
7651fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7652fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
7653fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
7654fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
7655fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
7656fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
7657fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
7658fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Assuming that image->colormap[0] is the one transparent color
7659fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             * and that all others are opaque.
7660fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             */
7661fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
7662fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              for (i=1; i<image_colors; i++)
7663fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                if (image->colormap[i].red == image->colormap[0].red &&
7664fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                    image->colormap[i].green == image->colormap[0].green &&
7665fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                    image->colormap[i].blue == image->colormap[0].blue)
7666fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
7667fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
7668fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
7669fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
7670fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
7671fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7672fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
7673fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
7674fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
7675fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7676fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
7677fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7678fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
7679fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7680fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
7681fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
7682fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
7683fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
7684fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
7685fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
76863c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
76873c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
76883c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
76893c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
7690f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
76913c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
769283c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
76930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
76941273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    image_colors <= 256 && image->colormap != NULL;
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
7701cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
7702cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
77030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
7706cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
77070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
77110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
77130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
77153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
77173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
77183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
7721cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
77243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
77263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
77273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
77283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
77293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
77303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
77313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
77323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7734cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7736b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      if (mng_info->need_blob != MagickFalse)
7737b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
7738b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
7739b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7742c722dd852e8abe407c2846d39662f7ade9c234deglennrp
7743c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
7744c722dd852e8abe407c2846d39662f7ade9c234deglennrp     (image->colors == 0 || image->colormap == NULL))
7745c722dd852e8abe407c2846d39662f7ade9c234deglennrp    {
7746c722dd852e8abe407c2846d39662f7ade9c234deglennrp      png_error(ping, "Cannot write PNG8 or color-type 3; colormap is NULL");
7747c722dd852e8abe407c2846d39662f7ade9c234deglennrp    }
7748c722dd852e8abe407c2846d39662f7ade9c234deglennrp
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
77503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
77513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
77533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
77543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
77552b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
77573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
77593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
77602b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
77623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
77632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
77652b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77664e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
77674e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
77682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
77703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
77710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
77733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
77740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
77763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
77773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
77780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
77803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
77810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
77833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
77840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
77863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7788e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
77893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7790e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
77913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7792e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
77933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77948640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
77953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77968640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
77973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77988640fb5e9b1094f35f8beab436f81661b8a99448glennrp
77993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
78005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
7801dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
780226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
78033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
780426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
780526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
78063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
78073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
78083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
78090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
7810dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7811dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
78123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
78143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7815dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
7816dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
7817dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
78183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7819dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
78203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
78213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7822dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
7823dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution);
7824dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution);
78253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7826991d11dd9c33e65872778b81aff1347cd2878154glennrp
78273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
78283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7829dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
7830dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) image->x_resolution;
7831dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) image->y_resolution;
78323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7833991d11dd9c33e65872778b81aff1347cd2878154glennrp
7834991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
783626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
78373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7838a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
783926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
784026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
7841a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
78423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7843a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
7844a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
7845a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
7846a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
7847a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
7848a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
78490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7850a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
7851a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
78520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7853a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
7854a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
78550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7856a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
7857a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
78580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7859a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
7860a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
78610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7862a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
7863a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
78640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7865a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
7866a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
78670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
78680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
78703b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
78713b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78723b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
78733b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
78743b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78753b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
78763b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
78770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
787926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
78803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
78823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
78833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
78843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
78853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
78860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78871273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
78883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
78890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7890fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
78910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
78920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
78948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
78958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
78960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
78980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
78990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
79000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
79010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
79030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
7905f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
79060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
79080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
79090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
79100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
79110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
79120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
79130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
79150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
79163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
79170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %5ld (%5d,%5d,%5d)",
79183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
79190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
79203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
79222b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
79248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
79258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
79265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
792758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
79288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
79290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
79300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
79310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
79320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
79338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
79343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
79368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
79370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79392cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
79408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
79410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
79430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
79440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
79468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
79478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
79480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79491273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
79504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
79511273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
79521273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
79531273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
79541273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
79554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
79564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
79574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
79580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
79604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
79620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
79643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
79665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
79673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
79703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
79725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
79733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
79763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
79780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
79803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
79815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
79820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
79845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
79853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
79862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
79878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
79888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
79893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
79900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      else /* write_ping_colortype not specified */
79923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
79933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
79943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79953c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
79960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7997d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
79988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
79990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8000d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
80013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
80025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
80033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
80043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
80050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8006d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
80073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
80085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
80093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
80103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
80110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80125aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
80135aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
80145aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
80155aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
80165f1c1fff2a55c4d8756556e78c1f307d352ed1b8cristy          if (image_info->type == UndefinedType ||
80178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             image_info->type == OptimizeType)
80183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
80195aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
80208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
80215aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
80225aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
80235aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
80245aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
80255aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
80260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80270b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
80285aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
80295aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
80305aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
80315aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
80328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
80335aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
80345aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
80355aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
80365aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
80375aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
80385aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
80395aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
80408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
80410b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
80425aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
80435aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
80445aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
80455aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
80465aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
80470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
80485aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
80493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
80500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
805226c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80538640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
805426c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
80555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
80560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
80570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
80580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
80590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
80600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
80610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
80623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8063d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
8064d6bf1617e99df0272b231855a933a74e99b6578fglennrp
80655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
80663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
80678d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp          if (image->matte == MagickFalse && ping_have_non_bw == MagickFalse)
80688d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
80693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
80708640fb5e9b1094f35f8beab436f81661b8a99448glennrp
80715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
80723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
807335ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
80745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
80750f111984738842d27d04aed2a3f823d82a943506glennrp
80760f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
80770f111984738842d27d04aed2a3f823d82a943506glennrp           {
80780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
80790f111984738842d27d04aed2a3f823d82a943506glennrp              (void) ThrowMagickException(&image->exception,
80800f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
80810f111984738842d27d04aed2a3f823d82a943506glennrp                "image has 0 colors", "`%s'","");
80820f111984738842d27d04aed2a3f823d82a943506glennrp           }
80830f111984738842d27d04aed2a3f823d82a943506glennrp
808435ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
80855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
8086d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
80873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8088d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
8089d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
8090d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8091d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
80920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8093d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8094d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
8095d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
80960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8097d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
8098d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
80993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
81015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
81022b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8106e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
81070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8109e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
81100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8112e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
81130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81153c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
81168640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
81178640fb5e9b1094f35f8beab436f81661b8a99448glennrp
81188640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8119e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
812258e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
81254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
81264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
81272b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_color != MagickFalse)
81294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             ping_color_type=PNG_COLOR_TYPE_RGBA;
81302b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
81324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
81344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
81354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
81364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
81374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
81384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
8139a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
81404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
81414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_color_type&=0x03;
81424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
81430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
81454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
81464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
81471273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp                mask;
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
81500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
81524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
81530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
81554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
81560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
81584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
81590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
81614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
81620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
81644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
81650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
81674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
81680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
81704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
81710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
81734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(PixelIntensityToQuantum(
81744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
81750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
81770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
81794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
81800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
81824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
81834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
8184fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
8185fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
8186fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
8187fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
8188fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
81894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
81902b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
81924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
81934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
81940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
81964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
81974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
81984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
81994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
82004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
82014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
82024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
82034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
82044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
82054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
82063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
82073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
82085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
82095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
82105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
82115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
82123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
82133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
82143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82158640fb5e9b1094f35f8beab436f81661b8a99448glennrp
82163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
82170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82182e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
82200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
822139992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
82238d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
82248d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
82253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
822635ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
82270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
82299c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
82300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
82323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
82335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
82344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
82353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
82364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
82374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
82384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
82394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
82414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
82424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
82434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
82443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
82450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
82473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
82480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
8250f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
82510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
82535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
82540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
82563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
82575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
82585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
82593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
82603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
82613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
82625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
82630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
826435ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
8265bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
82665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
82673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
82683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
82692b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
8270fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp#if 1 /* To do: Enable this when low bit-depth grayscale is working */
82710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
82720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
82733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
82743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
82753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
82773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
82783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
82793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
82803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
82813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8282bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
82833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
82843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
82853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
82903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
82910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
82933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
82940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
82963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
82973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
82982b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
82993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
83009c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
83010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8302fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp#if 0 /* To do: Enable this when bit depths 2 and 4 are working. */
83033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
83049c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
83050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
83079c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
8308fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp#endif
83093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
8310d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp#endif /* 1 */
83113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
83122b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
83143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
83150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
83170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
83193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
832017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
832117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
83223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
83233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
83243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
83253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
83263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
83275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
83280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
832958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (mng_info->have_write_global_plte && matte == MagickFalse)
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
83319c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
83320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83333b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
83349c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83359c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
83363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
83370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
83393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8340bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
83413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
83423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
83433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
83443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
83460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83473b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
83483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
834998156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
8350f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
83510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
835239992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
83533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
83540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
8356d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
83573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8358befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
8359befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
8360befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
83615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
8362befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
83630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8364befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
83655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
83663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
83670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
83690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
837058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
83710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
83720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
8373d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
8374d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
83750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
83763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8377d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
8378d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
83810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
83820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8383d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
83840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
8385c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
8386c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
8387c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8388c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
8389c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
8390d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
8391d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8392d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
8393d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
8394d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       ping_trans_alpha[i]= (png_byte) (255-
8395d6bf1617e99df0272b231855a933a74e99b6578fglennrp                          ScaleQuantumToChar(image->colormap[i].opacity));
8396d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
83970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
83980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
83993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
84003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
84010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
84033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8404c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
84053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
84063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
84070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
84093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
84104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
84114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
84124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
84144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
84154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
84164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
84174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
84184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
84195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
84205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
84215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
84225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
84234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
84244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
84254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
84264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
84284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
84294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
84304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
84314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
84323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
84333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
84343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84354383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
84364383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
84372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
84383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
84393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
84403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
84415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
84423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
84433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
84443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
84453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
84463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
844735ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
844835ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
844935ef824baa82511126ff0072ae30eee0da9c05a3cristy
845022ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
84513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
845326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
84543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8455a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
84563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
84573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
84593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84603c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Setting up bKGD chunk (2)");
84613b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
8462991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
846326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
84643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
84665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
84673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
846817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
846926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
847026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
84711273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
847217a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
847317a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
847417a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
847517a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
847617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
847717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
847817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8479a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
8480a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
848117a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
848217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
848317a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
848417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
84853b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
84860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
84870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
84890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
8490a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
849113d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
8492a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
84930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
84943b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
84953b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
84960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
84970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
84990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
85000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
85010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
85020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
8503a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
850417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8505d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
85063c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
85073b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
85083b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85093b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
85103c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
85113c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
851217a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
851326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
851417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
85153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
85183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
85193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
85203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
85213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
85230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
85250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
85280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
85290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
85310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
85350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
85370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
85393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
85400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
85423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
85443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
85453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8546bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
85470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
85493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
85510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
85533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
85563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
85583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
85600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
85623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
85673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
85693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
85703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
85713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
85733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
85750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
85773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
85803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
85813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
85833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
85842b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
85863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
85873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
85883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
85908640fb5e9b1094f35f8beab436f81661b8a99448glennrp      base_filter=PNG_ALL_FILTERS;
85910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85928640fb5e9b1094f35f8beab436f81661b8a99448glennrp    else
85938640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if ((quality % 10) != 5)
85943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
85950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85968640fb5e9b1094f35f8beab436f81661b8a99448glennrp      else
85978640fb5e9b1094f35f8beab436f81661b8a99448glennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
85985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
86008640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_NO_FILTERS;
86010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86028640fb5e9b1094f35f8beab436f81661b8a99448glennrp        else
86038640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_ALL_FILTERS;
86040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
86063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
86073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
86083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
86103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
86113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
86133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
86142b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
86153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
86163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
86173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8618c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  if (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse)
8619c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
8620c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
8621c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
86223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8623c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
86240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8625c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
8626c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
8627c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
8628c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
8629c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
863026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
8631c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
8632c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
8633c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
8634c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                       png_set_iCCP(ping,ping_info,(const png_charp) name,0,
8635e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
8636c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
8637e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
8638e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
8639e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
8640c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
8641c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
864226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
86430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8644c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8646c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
8647c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
8648cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
8649c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
8650c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
8651c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
8652c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
8653c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
86540b206f5daa453dc1035db5890cabc899736dc2d0glennrp
8655c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
8656c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8657c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
86580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8659c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
8660c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
86613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
86653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
86663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
866826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
866926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
867026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
867126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
867226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
867326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
867426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
867526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
86760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
867726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
8678cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
8679cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
86800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
868126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_gAMA == MagickFalse)
868226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            png_set_gAMA(ping,ping_info,0.45455);
868326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
86843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
868526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
86865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
86873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86892cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
86902cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
869126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
869226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
86983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
86993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
87023b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
870526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
87062b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
870726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
870926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
871026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
871126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
871226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
871326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
871426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
871526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
871626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
871726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
871826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
871926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
872026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
872126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
872226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
872326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
872426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
872526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
872626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
872726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
872826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
872926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
873026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
873126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
873226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
873326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
873426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
87353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8736dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
87375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
87383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
87403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
87413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
87433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8744d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
87478d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
87483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
87495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
87502b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
87515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
87525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
87533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
87540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
87568d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
87575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
87583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
87610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
87625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
87633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
87645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
8765991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
87660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
87673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
87693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
87700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
87710e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
87720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
87740e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
87750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
87773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
87783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
87803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
87815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
87823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
87843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
87853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
87863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
87883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
87895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
87903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
87920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
87933bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
87943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
87953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
879758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (image_matte != MagickFalse && image->matte == MagickFalse)
87983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
88003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
88013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
88020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8803b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
8804b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8805b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
88063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88080e319739731741c52a6303723e0c8678a0df5579glennrp  if (number_transparent != 0 || number_semitransparent != 0)
8809e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
8810991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
8811c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
8812991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
8813c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
8814c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8815c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
8816c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
8817e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
8818e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
88193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
88223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
88245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
88255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
88265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
88275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
882839992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
882939992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
8830f09bdedccf9ca10bc002a946227df3367cb58d14glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
88310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88323b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
883339992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
88348640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
88350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
8836d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
88370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8838d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
8839d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
88400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
88410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
88420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
8843d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
88440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
88450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
88460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8847d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
88480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
88490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
88500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
88510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
88520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
885339992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
885439992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
885539992b4dd9b12ef752d55b8e402c069698851f72glennrp
885626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
885726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
885826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
885926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
886026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
8861991d11dd9c33e65872778b81aff1347cd2878154glennrp
886226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
8863dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
886426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
886526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
886626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
886726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
886826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
886926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
887026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
8871dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
8872dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8873dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
88744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
8875dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
887626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
887726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
887826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
887926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
8880dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
888126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
888226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
888326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
888426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
888526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
8886dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
8887dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
8888dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
88893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
8890991d11dd9c33e65872778b81aff1347cd2878154glennrp
889139992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
8892991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
88933b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
88940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
88950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
88970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
8898991d11dd9c33e65872778b81aff1347cd2878154glennrp
88990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
89000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
89010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
89020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
89030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
8904991d11dd9c33e65872778b81aff1347cd2878154glennrp
89050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
89060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
89070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
89080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
89090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
89100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
89110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89123b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
89130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
89140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8915c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
89160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
89170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
89180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
89190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
89200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
89210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
8922991d11dd9c33e65872778b81aff1347cd2878154glennrp
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
8924cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
89253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
8926991d11dd9c33e65872778b81aff1347cd2878154glennrp
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
8928cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
893026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
89334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
893426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
893526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
893626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
893726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
893826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
893926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
894003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
894126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
894226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
894326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
894426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
894526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
894626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
89509c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
89529c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
8961b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
8962b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
89637202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8965b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
8967b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
89680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8969b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
8970b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
8971b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
89720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8973b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
8975b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
89760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8977b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
8978b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
89793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89803b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
89813b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
89823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8983b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8984b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
89850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8986b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8987e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8989cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
8990cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    sizeof(*ping_pixels));
89910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8992cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
89940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
9010cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
9011cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9013cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
90143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9015b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      if (mng_info->need_blob != MagickFalse)
9016b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
9017b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
9018b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9021ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
9022ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
9023ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
90278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
90298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
90308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
90328d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
90338d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
90380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
9045bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
90463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9047d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
90483b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90493b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
9050a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
90520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
90550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9059cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,GrayQuantum,ping_pixels,&image->exception);
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
90623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
90633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
90643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
9065bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
9066cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
90700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9074cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,RedQuantum,ping_pixels,&image->exception);
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
90760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
9078bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
9079cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
90803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
90810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90823b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
9083b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9084b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
90850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9086cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
90953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
910158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp         (image_matte != MagickFalse ||
91025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
91038d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         (mng_info->IsPalette) && ping_have_color == MagickFalse)
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
91068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
91070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
91108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9111bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
91142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
91172cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
91208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9122cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,GrayQuantum,ping_pixels,&image->exception);
91232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9126cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RedQuantum,ping_pixels,&image->exception);
91272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
91298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
91322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
9134b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
91353b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
9136b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
91382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9140cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  quantum_info,GrayAlphaQuantum,ping_pixels,&image->exception);
9141b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
91422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91433b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
9144b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
91462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9147cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
91492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
91518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
91528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
91538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
91548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
91558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
91568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
91578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
91580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
91628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
91630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
91668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
91678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
91688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
91698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
91708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
9171b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
91728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
91738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   &image->exception);
91742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
91768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
91772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
91798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
91808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
91818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9182cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,RedQuantum,ping_pixels,&image->exception);
91832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
91858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9186cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,GrayQuantum,ping_pixels,&image->exception);
91878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
91882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
91908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
91918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9192cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
91938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      &image->exception);
91942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
91958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
91968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
91988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
91992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
92018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9202cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBAQuantum,ping_pixels,&image->exception);
92032cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
92058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9206cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBQuantum,ping_pixels,&image->exception);
92072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92083b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
9209b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
92112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9212cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
9213b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
92148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
92152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
92178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
92188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
92198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
92208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
92218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
92228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
92238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
92248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
92258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
92272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
92298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
92308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
92312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
92338640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
92348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
92358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
92372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
92392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
92418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
92422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
92448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9245cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                       quantum_info,GrayQuantum,ping_pixels,&image->exception);
92462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
92488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
92498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
92508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
92522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9254cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
9255d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         &image->exception);
92568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
92572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
92598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
9260fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                    /* To do:
92615eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                     *
92625eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                     * This is failing to account for 1, 2, 4-bit depths
92635eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                     * The call to png_set_packing() above is supposed to
92645eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                     * take care of those.
92655eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                     */
92665eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
92675eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    /* GrayQuantum does not work here */
92685eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
92695eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      quantum_info,IndexQuantum,ping_pixels,&image->exception);
92702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92715eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
92725eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
92735eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92745eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  Writing row of pixels (4)");
92755eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
92765eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92775eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
92785eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
92795eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
92808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
9281cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
92828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
92838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
92842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
92868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
92878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
92888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
92898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
92908640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
92913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
92923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
92938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
92948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9295b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
9296b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
92973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
92993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9301b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
93020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9304e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
93050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9307e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
93080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
93133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
93140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
93170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
93230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
93260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
93323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
933326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_tEXt == MagickFalse && ping_exclude_zTXt == MagickFalse)
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
933526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
933626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
933726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
933826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
933926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
934026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
93412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
934226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      value=GetImageProperty(image,property);
934326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (value != (const char *) NULL)
934426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
934526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
934626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].key=(char *) property;
934726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].text=(char *) value;
934826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          text[0].text_length=strlen(value);
93492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
935026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_tEXt != MagickFalse)
93514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
93522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
935326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          else if (ping_exclude_zTXt != MagickFalse)
93544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             text[0].compression=PNG_TEXT_COMPRESSION_NONE;
93552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
935626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          else
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp             text[0].compression=image_info->compression == NoCompression ||
93594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               (image_info->compression == UndefinedCompression &&
93604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
93614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp               PNG_TEXT_COMPRESSION_zTXt ;
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93632cc891a179d622dde7bbb8854138851e828bc6eaglennrp
936426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
936526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
936626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
936726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up text chunk");
93682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
936926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
937026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "    keyword: %s",text[0].key);
937126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
93722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
937326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_text(ping,ping_info,text,1);
937426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_free(ping,text);
937526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
937626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
937726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
93783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
9381cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
93843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
93860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
93880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
93925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
93935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
93993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
94023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
940303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
94073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
94145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
94175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
94230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
94320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
94365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
94373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9439cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9442cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9445b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  if (mng_info->need_blob != MagickFalse)
9446b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp     (void) CloseBlob(image);
9447b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9448b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=DestroyImageInfo(image_info);
9449b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image=DestroyImage(image);
9450b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9451b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
9452b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
9453b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
9454b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9455b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  (void) SetImageProperty(IMimage,"png:bit-depth-written",s);
9456b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
94600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
94703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
94713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
94743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
94803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
94823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
94963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
94973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
94983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
94995a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
95005a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
95013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
95023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
95035a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
95045a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
95055a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               colors are present, they will be quantized to the 3-3-2
95065a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               palette.  If you want better quantization or dithering of
95075a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               the colors or alpha, you need to do it before calling the
95085a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
95095a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
95103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
95115a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
95125a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
95135a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
95143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
95163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
95175a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
95185a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
95195a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
95205a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
95215a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
95223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
95253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
95260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
95275a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
95285a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
95293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
95323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
9533bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
9534bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
9535bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
95363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
95383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
95403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
95413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
95433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
95443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
95463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
95473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
95483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
95493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
95523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95535a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  If the image cannot be written without loss with the requested bit-depth
95545a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  and color-type, a PNG file will not be written, and the encoder will
95555a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  return MagickFalse.
95565a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
95573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
95583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
95593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
95605a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
95615a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%   or transparency limitations.
95623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
95643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
95663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
95673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
95683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
95703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
95713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
95723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
95733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
95753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
95773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
9578bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
9579bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
95803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
95823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
95833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
9584bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
95853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9586bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
95873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
95883241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
95890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
9590d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
95910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
95920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
95930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
9594cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
95950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
9596d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
9597d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
9598d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      requested via the "-define PNG:bit-depth=N" option.
9599d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
9600d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
9601d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
9602d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
96030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
96043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
96063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
96073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
96083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
96093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
961021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
961121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
961221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
96133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
96143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
96163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
96173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
96193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
96203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
962221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
96235c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
96245c7cf4e469a4dad7e277783749155932252c52dfglennrp
96253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
96263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
96273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
96283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
96303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
96313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
9633fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
96343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
96363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
96373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
963873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
96390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
96413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
96420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
96463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
96473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
9648a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
96493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
96503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
96523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
96543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
96553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
96563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96599c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
96609c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
96619c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
96623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
96653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96669c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
96679c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
96689c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
96690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96709c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
96719c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
96720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96739c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
96749c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
96750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96769c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
96773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
96803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96819c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
96829c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
96839c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
96840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96859c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
96869c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
96870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96889c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
96899c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
96900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96919c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
96923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
96958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
96963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
96973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
96999c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
97000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
97029c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
97030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
97059c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
97060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
97089c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
97090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
97119c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
97120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9713bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
9714bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
9715bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
9716bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
9717bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
9718bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
97193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
97209c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9721bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
97223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
97250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
97273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
97293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
97309c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
97310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
97339c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
97340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
97369c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
97370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
97399c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
97400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
97429c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
97430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9744bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
9745bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
9746bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
9747bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
9748bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
9749bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
97503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
97519c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9752d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
97533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
97560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
97570dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
97580e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
97590e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
97600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Chunks can be listed for exclusion via a "PNG:exclude-chunk"
97610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
97620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
97630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
97640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
97650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
97660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
97670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
97680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * A "PNG:include-chunk" define takes  priority over both the
97690e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * mng_info and the "PNG:exclude-chunk" define.  Like the
97700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
97710dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
97720dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
97730dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
97740dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * appear in the "include-chunk" list.
97750e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
97760e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
97770e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
97780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
97790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
97800e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
97810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
97820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
97830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
97840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
97850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
97860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
97870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
97880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * artifact to "none,gama".
97890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
97900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
979126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
979226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
979326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
979426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
979526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
979626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
979726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
979826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
979926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
980026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
980126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
9802a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
980326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
980426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
980526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
980626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
980703812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
980803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
98095c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
98105c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
98115c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
9812acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
98135c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
9814acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
9815acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9816acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
9817acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
98185c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
9819acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
98205c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
982126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9822acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9823acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
9824acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
9825acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
982603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
982703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
982826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
982903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
983003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
983126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
983203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
983326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
983403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
98352cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
98362cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
98372cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98382cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
98392cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
98402cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98412cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
98422cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
984303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
984403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
984503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
984603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
984703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
984803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
984903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
985003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
985103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
985203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
985303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
985403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
985503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
985603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
985703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
985803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
985903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
986003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
9861a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
986203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
986303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
986403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
986503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
986603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
98672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
986803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
986903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
987003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
987103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
987203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
987303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
987403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
987503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
987603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
987703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
987803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
987903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
9880a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
988103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
988203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
988303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
988403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
98852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
988603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
988703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
98882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
988903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
989003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
98912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
989203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
989303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
98942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
989503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
989603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
98972cc891a179d622dde7bbb8854138851e828bc6eaglennrp
989803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
989903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
99002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
990103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
990203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
990303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
990403812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
99052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
990603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
990703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
99082cc891a179d622dde7bbb8854138851e828bc6eaglennrp
990903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
991003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
99112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
991203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
991303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
99142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9915a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
9916a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
99172cc891a179d622dde7bbb8854138851e828bc6eaglennrp
991803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
991903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
99202cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9921a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
9922a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
9923a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
992403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
992503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
99262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
992703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
992803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
99292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
993003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
993103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
99322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
993303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
9934ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
993526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
993626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
99375c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
99385c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
99395c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
9940acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
99415c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
9942acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
9943acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9944acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
9945acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
99465c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
9947acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
99485c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
994926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9950acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
9951acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
9952acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
9953acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
995403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
995503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
995603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
995703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
995826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
995903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
996026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
996103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
99622cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
99632cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
99642cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99652cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
99662cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
99672cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99682cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
99692cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
997003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
997103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
997203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
997303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
997403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
997503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
997603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
997703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
997803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
997903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
998003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
998103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
998203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
998303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
998403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
998503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
998603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
9987a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
998803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
998903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
999003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
999103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
999203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
99932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
999403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
999503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
999603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
999703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
999803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
999903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
1000003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
1000103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
1000203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
1000303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
1000403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
1000503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
10006a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
1000703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
1000803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
1000903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
1001003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
100112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1001203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1001303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
100142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1001503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1001603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
100172cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1001803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1001903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
100202cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1002103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1002203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
100232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1002403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1002503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
100262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1002703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1002803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1002903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
1003003812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
100312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1003203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1003303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
100342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1003503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1003603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
100372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1003803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1003903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
100402cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10041a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
10042a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
100432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1004403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1004503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
100462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10047a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
10048a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
10049a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1005003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1005103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
100522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1005303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1005403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
100552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1005603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1005703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
100582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1005903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
10060ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1006126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1006226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1006303812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
1006426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1006526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1006626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      "  Chunks to be excluded from the output PNG:");
1006726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1006826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1006926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1007026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1007126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1007226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
1007326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1007426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1007526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1007626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1007726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1007826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1007926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1008026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1008126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
1008226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
1008326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1008426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1008526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
1008626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
1008726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1008826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1008926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1009026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1009126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1009226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1009326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1009426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1009526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1009626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1009726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1009826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
10099a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
10100a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10101a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1010226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1010326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1010426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1010526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1010626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1010726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1010826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1010926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1011026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1011126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1011226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10113b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
101143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10115b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  status=WriteOnePNGImage(mng_info,image_info,image);
101163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
101180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
101203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
101210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
101233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
101243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
101263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
101283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
101303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
101313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
101323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
101333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
101353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
101363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1013803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
101393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
101403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
101423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
101433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
101453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
101463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
101473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
101483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
101503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
101513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
101523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
101533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
101543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10155bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
101573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
10159fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
101603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
101623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
101633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
101643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
101663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
101673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
101683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
101693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
101703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
101713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
101723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
101743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
101763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
101773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
101783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
101793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
101823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
101840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
101863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
101873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
101890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
101910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
101933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
101940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
101963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
101980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
102000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
102023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
102030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
102053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
102063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
102073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
102080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
102103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
102110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
102133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
102140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
102163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
102173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
102183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
102193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
102203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
102233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
102253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
102263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
102273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
102283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
102303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
102323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
102333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
102343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
102353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
102373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
102383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
102393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
102403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
102423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
102433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
102453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
102463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
102473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
102493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
102503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
102523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
102533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
102543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
102553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
102563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
102573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
102583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
102593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
102613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
102623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
102643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
102653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
102663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
102673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
102693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
10270f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
102713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
102720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
102743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10275e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
10276e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
102773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
102793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
102803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
102813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
102823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
102833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
102863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
102873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1028803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
102894e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
102904e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
102913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
102923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
102933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
102943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
102953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
102963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
102973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
102983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
102993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
103003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
103013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
103023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10304f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
103050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10307f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
103080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
103110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
103140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
103170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
103200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
103230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
103260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
103290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
103323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
103333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
10335cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
103363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
103383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
103393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
103403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
103423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
103433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
103443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
103453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
103463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
103483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
103493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
103503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
103513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
103533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
103543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
103563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
103573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
103583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
10359bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
103603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1036103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
103623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
103633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
103643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
103653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
103663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
103673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
103683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
103693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
103703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
103713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
103723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
103733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
103743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
103763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
103783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
103793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
103803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
103813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1038203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
103830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
10385e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10386cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
10387e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
103880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
10390e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10391cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
10392e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
103930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
103953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
103963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
103973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
103983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
104003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
104013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
104023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
104033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
104043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
104053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1040603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1040735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
104083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
104093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
104103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
104110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
104133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
104143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
104153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
104163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
104173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
104193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
104203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
104213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
104223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1042303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
104243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1042535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1042635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
104273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1042835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1042935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
104303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1043135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1043235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
104333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1043435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1043535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
104363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
104373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
104383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
104393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
104400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
104423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
104433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
104443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
104453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
104463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
104473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1044803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
104493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
104503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1045135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
104523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
104530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1045435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
104553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
104560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
104583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
104590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
104613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
104623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
104633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1046435ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
104653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
104660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1046735ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
104683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
104690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
104713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
104720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
104743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1047535ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1047635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
104773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
104783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
104793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
104803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
104813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
104823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
104833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
104853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
104863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
104873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
104883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
104893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
104903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1049103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
10492bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
10493bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
104943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
104953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
104963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
104973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
104983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
104993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
105013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1050203812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
105033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
105043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
105053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
105063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
105073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
105083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
105093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
105123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
105143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
105163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
105173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10518bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
105193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
105203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
105223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
105233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10524e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
10525f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
105263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
105283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
105293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
10530bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
105313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
105323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
105333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
105340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
105363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
105373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
10538bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1053903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
105403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
105413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
105423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
105433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
105440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
105463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
105473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
105483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10549e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
10550e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
105513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
105523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
105533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
105543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
105553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
105563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
105583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
105593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10560e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
10561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
105623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1056303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
105643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
105653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
105663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
105673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
105693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
105703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
105723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
105743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
105753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
105773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
105783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
105793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
105803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
105823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
105843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
105873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
105883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
105893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
105913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
105923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
105953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
105963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
105983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10599e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
10600e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
106013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
106033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
106040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
106063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
106080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
106103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
106120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
106140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10618e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
10619e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
106203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10622e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
106233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
10626bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1062803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
106303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
106323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
106353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
106363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
10639cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
106403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
106423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
106433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1064403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
106453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
106463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
106473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
106493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
106510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
106533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
106543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
106573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
106623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
106673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
106683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
106693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
106703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
106713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
106723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
106733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
106743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
106753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
106763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
106773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
106783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
106793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
106803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
106813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
106833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
106843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
106853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1068621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1068703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
106883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
106893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
106913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
106923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
106943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
106953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
106963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
106973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
106983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
106993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10701fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
107043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
107053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
107083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1071073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
107113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
107123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
107133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
107153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
107173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
107183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
107213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
107233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
107243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
107283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
107293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
107303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
107323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
107363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
107383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1074421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
107463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1074703812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1074803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1074903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
107523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
107563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
107573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
107603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
107613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
107623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
107633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10767bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
107713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10777bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10780bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
107833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10784d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
107853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
107873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
107883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
107893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
107963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10798fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
108013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1080773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
108083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
108103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
108163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
108223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
108233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
108243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
108253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
108263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
108283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
108323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
108343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
108353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
108363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
108393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
108413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
108480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10850e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
108510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
108563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
108573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10859e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
108600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10862e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
108630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
108670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
108693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
108710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
108750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
108773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
108790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10882e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
108830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
108870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
108943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
108953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
108963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
108973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
108983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
108993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
109013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
109023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
109043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
109053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
109063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
109073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
109083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
109093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
109103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
109113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
109123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
109143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
109163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
109173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
109193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
109203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
109213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
109223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
109243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
109253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
109263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
109273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
109303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
109313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
109323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
109333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
109343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
109353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
109393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
109403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
109413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
109423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
109433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
109443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
109453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
109463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
109473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
109500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
109533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
109540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
109570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
109593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
109600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
109623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
109643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
109653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
109660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
109690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
109710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
109733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
109743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
109750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
109773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
109783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
109793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
109803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
109813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
109823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
109830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
109853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
109873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
109883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
109893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
109903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
109913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
109923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
109933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
109943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
109953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
109973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
109983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
109993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
110003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
110013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
110023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
110030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
110053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
110060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
110083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
110093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
110100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
110123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
110133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
110143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
110150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
110183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
110193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
110203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
110233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
110253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
110263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
110273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
110283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
110293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
110303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
110313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
110323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
110333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
110343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
110353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
110363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
110383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
110393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
110403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
110413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
110423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
110433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
110443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
110453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
110463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
110473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
110483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
110493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
110503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
110513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
110523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
110553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
110563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
110573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
110583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
110593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
110603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
110613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
110623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
110633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
110643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
110653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
110663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
110670261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
11068d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
11069d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
11070d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
11071d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
11072d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
11073d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
11074d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
110753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
110763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
110773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
110783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
110793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
11080cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
11081cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
110833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
110840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
110870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
110893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
110900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
110923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
110933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
110943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
110953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
110963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
110970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
111023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
111053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1111103812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
111124e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
111134e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
111143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
111153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
111173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
111183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
111193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
111213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
111233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
111240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
111263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
111273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
111280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
111303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
111313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
111323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
111330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
111353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
111363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
111373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
111380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
111403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
111413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
111423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
111433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
111443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
111450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
111473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
111483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
111490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
111513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
111523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
111533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
111540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
111563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
111573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
111583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
111593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
111603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
111613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
111623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
111633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
111643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
111653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
111663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
111683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
111693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
111703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
111713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
11172bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1117303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
111743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
111753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
111763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
111773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
111783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
111793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
111803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
111813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
111823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
111833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
111843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
111853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
111863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1118703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
111883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
111893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
111903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
111913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
111920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
111943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
111950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
111973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
111980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
112003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
112013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11202e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
11203e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
112040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11207e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
112080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11211e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
112143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
112163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
112183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
112213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1122703812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
112280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
11230e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
11231cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
11232e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
112330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
11235e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
11236cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
11237cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
112380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
112403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
112413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
112430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
112453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
112463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
112473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
112483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
112493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
112503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
112513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
112523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1125303812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1125435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
112553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
112563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
112573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
112583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
112593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
112603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
112613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
112623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
112633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
112653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
112663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
112673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
112683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1126903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
112703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1127135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1127235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
112733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1127435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1127535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
112763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1127735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1127835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
112793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1128035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1128135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
112823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
112833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
112843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
112853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
112863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
112873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
112883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
112893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
112903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
112913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
112923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
112933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1129403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
112950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
112973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1129835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
112993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
113000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1130135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
113023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
113030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
113060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
113083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
113093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
113103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1131135ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
113123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
113130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1131435ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
113153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
113160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
113183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
113190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
113213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1132235ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1132335ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
113243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
113253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
113263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
113273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
113283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
113293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
113303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
113313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
113323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
113333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
113343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
113353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
113363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
113373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
113383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
113393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
113403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
113413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1134203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
113433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
113443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
113453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
113463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
113473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
113483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
113493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
113503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
113513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
113523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
113533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
113543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1135503812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
113563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
113573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
113583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
113593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
113603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
113623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
113633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
113643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
113653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
11366bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
113673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
113683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
113703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
113713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
113723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
113733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
113743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1137503812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
113760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11377bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
113783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
113793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
113803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
113813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
113823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
113830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
113853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
113863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
113873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
113883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
113893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
113903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
113913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
113923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
113933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
113943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
113953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
113963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
113983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
113993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
114003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
114013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
114023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
114033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
114043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
114053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
114063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
114073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
114083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
114093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
114103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
114113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
114123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
114133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
114153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
114163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
114173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
114183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
114193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
114203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
11421bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
114223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
114233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
114253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
114263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1142703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
114280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11429bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
114303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
114313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
114323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
114333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
114343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
114350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
114373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
114383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
114393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
114403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
114413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
114433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
114443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
114453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
114463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
114473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11448bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
114493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
114503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
114513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
114533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
114543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
114553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
114563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
114583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
114593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
114603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
114613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
114633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
114643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
114653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
114663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
114673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1146803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
114693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
114703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
114713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
114723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
114733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
114743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
114753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
114763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
114773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
114793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
114803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
114823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
114853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
114873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
114883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
114903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
114913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
114923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
114933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
114943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
114953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
114963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1149703812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
114983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
114993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
115003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
115013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
115023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
115033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
115043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
115053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
115063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
115073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
115083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1150903812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
115103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
115113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
115123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
115133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
115143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
115153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
115163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
115173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
115183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
115193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
115203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
115214e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
115223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
115233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
115243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
115253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
115273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
115283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
115293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
115303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
115313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
115333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
115343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
115353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
115363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
115373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
115383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
115393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
115403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
115413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
115423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
115433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
115443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
115453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
115463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
115472f2e514554975d510c88df54de98c6cdc1080f1cglennrp
11548b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
115492f2e514554975d510c88df54de98c6cdc1080f1cglennrp
115502f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
115512f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
115522f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
115532f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
115542f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
115552f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
115562f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
115572f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
115582f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
115592f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
115602f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
115612f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
11562a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
115632f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
115642f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
115652f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
115662f2e514554975d510c88df54de98c6cdc1080f1cglennrp
115673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
115683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
115693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
115713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
115723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
115733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
115743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
115753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
115763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
115773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
115783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
115793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
115803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
115813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
115820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
115843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
115850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
115870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
115893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
115913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
115923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
115933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
115943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
115953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
115963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1159703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
115983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
115993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
116003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
116023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
116033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
116043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
116053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
116060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
116083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
116090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
116113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11612d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1161339992b4dd9b12ef752d55b8e402c069698851f72glennrp
116143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
116153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
116163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
116173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
116183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
116190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
116213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
116223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1162339992b4dd9b12ef752d55b8e402c069698851f72glennrp
116243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
116253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
116263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
116273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11628d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
116293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11630